Sunteți pe pagina 1din 290

ING. LUIS G. URIBE C.

Computer
Architecture:
The MC9S08
Primera Edicin
Septiembre de 2014, V1.3d

ING. LUIS GUILLERMO URIBE CATAO

Computer Architecture: The MC9S08

2014 Ing. Luis G. Uribe C.


Caracas, Venezuela

Contenido
PRLOGO ........................................................................................................................................................................... 5

ABSTRACT............................................................................................................................................................. 5
INTRODUCCIN ................................................................................................................................................... 6
ARQUITECTURA DEL COMPUTADOR: QU DEBEMOS ESTUDIAR .................................................................. 6
Enfoque ......................................................................................................................................................................... 7
Observaciones sobre algunos trminos empleados ...................................................................................................... 7

VON NEUMANN COMPUTERS....................................................................................................................................... 8

INTRODUCCIN ................................................................................................................................................... 8
QU ES UNA INSTRUCCIN ..................................................................................................................................... 8

MQUINAS DE 3, 2, 1 Y 0 DIRECCIONES ................................................................................................................... 10

HCS08 ARCHITECTURE: PROGRAMMING MODEL...................................................................................... 11


MODOS DE DIRECCIONAMIENTO EN EL MC9S08 (CPU08RM Reference Manual)........................................... 11
VARIACIONES Y OPTIMIZACIONES ....................................................................................................................... 12

CODIDAC, VON URIBES COMPUTER.................................................................................................................... 14


LA ARQUITECTURA ................................................................................................................................................. 14
LAS INSTRUCCIONES............................................................................................................................................... 14
LOS MODIFICADORES ............................................................................................................................................ 14
EL SUBSISTEMA DE ENTRADA Y SALIDA.............................................................................................................. 14
CDIGOS DE OPERACIN ..................................................................................................................................... 14
EL EDITOR ................................................................................................................................................................ 15
EL FORMATO DE LOS NMEROS .......................................................................................................................... 15
LA CALCULADORA................................................................................................................................................... 15
LA ESTRUCTURA ...................................................................................................................................................... 15
DATOS ESTADSTICOS............................................................................................................................................. 15
CIRCUITOS IMPRESOS ............................................................................................................................................ 15
FOTOS........................................................................................................................................................................ 16
ASSEMBLER HCS08 ........................................................................................................................................................ 37

EJERCICIOS BSICOS EN ASSEMBLY LANGUAGE .......................................................................................... 37


1) Primer Programa para el HCS08: MINIMUM Program for HCS08..................................................................... 37
COMENTARIOS a ["Laboratorios\Lab1\00a_L1.asm"]:........................................................................................... 38
2) Segundo Programa para el HCS08: Init COP & STACK ...................................................................................... 40
COMENTARIOS a ["Laboratorios\Lab1\00c_L1.asm"]:........................................................................................... 41
3) Programacin en Lenguaje de Mquina (HEX) para el HCS08:........................................................................... 42
COMENTARIOS a ["Laboratorios\Lab1\01a_L1.asm"]:........................................................................................... 43
4) Invente su propio Instruction Set para el HCS08:.................................................................................................. 46
COMENTARIOS a ["Laboratorios\Lab1\01b_L1.asm"]:........................................................................................... 47
5) Usando los OpCodes del Fabricante para el HCS08:............................................................................................ 47
COMENTARIOS a ["Laboratorios\Lab1\01c_L1.asm"]:........................................................................................... 48

6) Forma DEFINITIVA para programar el HCS08: .................................................................................................. 49


COMENTARIOS a ["Laboratorios\Lab1\01d_L1.asm"]:........................................................................................... 50
7) CODE SECTION, DATA SECTION, en el HCS08:................................................................................................ 50
COMENTARIOS a ["Laboratorios\Lab1\01e_L1.asm"]:........................................................................................... 51
PROGRAMAS AVANZADOS EN ASSEMBLY LANGUAGE, PARTE I ......................................................... 54
8) Serie de Fibonacci.................................................................................................................................................. 54
COMENTARIOS a ["Laboratorios\Lab1\02Fibonacci.asm"]:................................................................................... 56
9) Empleo de Subrutinas; Identificacin de Modos de Direccionamiento.................................................................. 56
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03a_L1_M.asm"]:....................................................................... 58
10) Introduccin a las INTERRUPCIONES ............................................................................................................... 58
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03b_L1_M.asm"]:....................................................................... 61
11) Ejercicio con ms Aspectos Nuevos: .................................................................................................................... 63
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03c_L1_M.asm"]:....................................................................... 65
12) Ejercicio con ms Aspectos Nuevos an: ............................................................................................................. 67
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03d_L1_M.asm"]:....................................................................... 70
13) Aspectos Cosmticos en el trato de los Vectores de Interrupcin:....................................................................... 71
14) Ejemplo: Rutina de MULTIPLICAR, por Sumas Sucesivas: ................................................................................ 72
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05a_L1_M.asm"]:....................................................................... 73
15) "SUBRUTINA" de MULTIPLICAR, por sumas sucesivas:................................................................................... 74
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05b_L1_M.asm"]:....................................................................... 75
16) Ejemplo PRIMORDIAL del uso de Variables Dinmicas: ................................................................................... 76
COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05d_L1_M.asm"]:....................................................................... 80
PROGRAMAS AVANZADOS EN ASSEMBLY LANGUAGE, PARTE II........................................................ 84
17) Torres de Hanoi, MNIMO, en C: ........................................................................................................................ 84
COMENTARIOS a ["Temarios\Ex#1-HanoiMin\HanoiMin--.c"]: .......................................................................... 85
18) Torres de Hanoi, MNIMO, en ASSEMBLY LANGUAGE: .................................................................................. 86
A) Programa HanoiMin--.asm: ................................................................................................................................. 87
B) Include File HanoiMin_.inc:................................................................................................................................. 88
COMENTARIOS a ["Temarios\Ex#1-HanoiMin\HanoiMin--.asm"]: ........................................................................ 90
COMENTARIOS a ["Temarios\Ex#1-HanoiMin\hanoiMin_.inc"]: ........................................................................... 91
TIMERS.................................................................................................................................................................. 93
NMERO DE TIMERS: ............................................................................................................................................. 93
OPERACIN Y USO DE LA BIBLIOTECA DE TIMERS:......................................................................................... 94
19) Timers for Windows (timers.cpp): ........................................................................................................................ 95
COMENTARIOS a ["Laboratorios\Lab2\_New\timers_.h"]: ..................................................................................... 99
COMENTARIOS a ["Laboratorios\Lab2\_New\timers.cpp"]: ................................................................................. 100
COMENTARIOS a ["Laboratorios\Lab2\_New\timtst2.cpp"]: ................................................................................ 101
20) Librera de TIMERS para el HC9S08 (timers8HS.inc): ..................................................................................... 101
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\timers8HS.inc"]:................................................................... 104
21) Ejemplo del uso de la Librera de TIMERS (timer8HS.asm): ............................................................................ 108
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\timer8HS.asm"]: .................................................................. 111
22) "WaitISR_on" Interactuando con la "IRQISR" .................................................................................................. 111
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\tim8_IRQ-HS.asm"]:............................................................ 114
23) Enciende los 8 LEDs con Diferentes Intervalos ................................................................................................. 116
COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\TimedFlash8.asm"]:............................................................. 119
24) Enciende ORDENADAMENTE los 8 LEDs con Diferentes Intervalos .............................................................. 120
Finalizacin Tema TIMERS...................................................................................................................................... 123
PROGRAMAS AVANZADOS EN ASSEMBLY LANGUAGE, PARTE III .................................................... 123
COLAS DE DATOS .............................................................................................................................................. 126
25) BIBLIOTECA de COLAS: Que.inc ..................................................................................................................... 129
COMENTARIOS a ["Laboratorios\Lab3\SciComm\Que.inc"]: ............................................................................... 133
"STRUCT" in ASSEMBLY LANGUAGE................................................................................................................... 134
26) Programa Elemental para Probar la Librera de COLAS ................................................................................. 139
COMENTARIOS a ["Laboratorios\Lab3\SciComm\4quetst.asm"] .......................................................................... 141
COMUNICACIONES SERIALES......................................................................................................................... 143

27) LIBRERA de COMUNICACIONES SERIALES: SciComm.inc ......................................................................... 143


COMENTARIOS a ["Laboratorios\Lab3\SciComm\SciComm.inc"]:....................................................................... 147
28) Transmisin. ....................................................................................................................................................... 158
COMENTARIOS a ["Laboratorios\Lab3\SciComm\1tstXmt.asm"].......................................................................... 160
29) ECHO. ................................................................................................................................................................ 160
COMENTARIOS a ["Laboratorios\Lab3\SciComm\2echo1.asm"]:......................................................................... 162
30) Transmisin por INTERRUPCIONES. ............................................................................................................... 163
COMENTARIOS a ["Laboratorios\Lab3\SciComm\3echoInt-1.asm"]: ................................................................... 165
31) Cuarto Programa de COMUNICACIONES: Flash LEDs.................................................................................. 168
COMENTARIOS a ["Laboratorios\Lab3\SciComm\3echoInt-1Leds.asm"]:............................................................ 170
32) Programas de COMUNICACIONES que USTED Debe Hacer: ........................................................................ 173

PROGRAMAS VARIOS EN ASSEMBLY LANGUAGE .................................................................................. 174


33) BITCOPY, MACRO y Ejemplo. .......................................................................................................................... 174
COMENTARIOS a ["Laboratorios\Proy\Buzzer\BitCopy.asm"]: ............................................................................ 178
34) USO Bsico del ADC, y Display en LEDs.......................................................................................................... 180
COMENTARIOS a ["Laboratorios\Proy\Buzzer\ADC.asm"]................................................................................... 182
35) Uso Bsico del ADC, Reversar Datos Antes de ir a los LEDs. .......................................................................... 184
COMENTARIOS a ["Laboratorios\Proy\Buzzer\ADC_Reverse.asm"]:................................................................... 187
36) Contador de UNOS............................................................................................................................................. 189
COMENTARIOS a ["Books\Interfacing-HCS08\Examples\bitcount3.asm"]: .......................................................... 190
37) Programacin de un TONO en el BUZZER. ...................................................................................................... 191
COMENTARIOS a ["Laboratorios\Proy\Buzzer\Buzzer.asm"]: .............................................................................. 193
38) Un "WALKMAN" Elemental............................................................................................................................... 195
COMENTARIOS a ["Laboratorios\Proy\Buzzer\Walkman.asm"]: .......................................................................... 199
39) "SWITCH", va "COMPUTED GOTO".............................................................................................................. 202
COMENTARIOS a ["Laboratorios\FSM-FiniteStateMachines\ComputedGoTo.asm"]:.......................................... 204
40) La FBRICA de CHOCOLATES........................................................................................................................ 207
41) TABLAS de DATOS; Implementacin del "FOR". ............................................................................................. 209
COMENTARIOS a ["Laboratorios\Tables\Tables0.asm"] ....................................................................................... 211
42) Last, but not Least: 8 Bits Rotate Left. ............................................................................................................... 212
COMENTARIOS a ["Evaluaciones\2013-01Ene\Evaluaciones\Ex#1\Rotate8.asm"]:............................................. 213
PROGRAMACIN EN "C"........................................................................................................................................... 215

NOTAS INICIALES ............................................................................................................................................ 215


DNDE ESTAMOS ............................................................................................................................................ 215
GENERALIDADES ............................................................................................................................................ 216
43) Programa INTRODUCTORIO en C, para HCS08, Comparativo con ASM. ..................................................... 216
COMENTARIOS a ["Labs-C\Fibonacci\060Fibonacci.c"]:..................................................................................... 217
["Labs-C\Fibonacci\Fibonacci_.h"]: ....................................................................................................................... 219
COMENTARIOS a ["Labs-C\Fibonacci\Fibonacci_.h"]: ........................................................................................ 220
44) FIBONACCI PROGRAMADO EN C, NORMALMENTE, PARA COMPARAR ................................................. 221
COMENTARIOS a ["Labs-C\Fibonacci\090FibonacciOK.c"]: ............................................................................... 221
45) EXPONENCIACIN POR MULTIPLICACIONES Y SUMAS SUCESIVAS: WHILE ....................................... 222
COMENTARIOS a ["Labs-C\Lab1\010Lab0e-1.c"]: ............................................................................................... 222
46) EXPONENCIACIN, MULTIPLICACIONES Y SUMAS SUCESIVAS: FUNCIONES ..................................... 222
COMENTARIOS a ["Labs-C\Lab1\020Lab0e-2Sub.c"]: ......................................................................................... 223
47) EXPONENCIACIN, FUNCIONES: PARA VISUAL STUDIO ......................................................................... 223
COMENTARIOS a ["Labs-C\Lab1\030Lab0e-2SubVisualStudio.c"]: ..................................................................... 224
48) PRIMER PROGRAMA PARA HCS08: MINIMUM C PROGRAM..................................................................... 224
COMENTARIOS a ["Labs-C\lab1\00a_l1.c"]:......................................................................................................... 224
49) PROGRAMA EN C PARA HCS08, UN POCO MS TIL ................................................................................ 225
COMENTARIOS a ["Labs-C\Lab1\01c_L1.c"]:....................................................................................................... 226
50) "INTERRUPTS" EN EL LENGUAJE C.............................................................................................................. 227
COMENTARIOS a ["Labs-C\Lab1\03b_L1_M.c"]: ................................................................................................. 229
EL INCLUDE FILE "SEVERAL_U.H":.................................................................................................................... 232

COMENTARIOS a ["Labs-C\Lab1\several_U.h"]: .................................................................................................. 232


OBSERVACIN: ...................................................................................................................................................... 233
51) "Interrupts" en el lenguaje C, variacin............................................................................................................. 234

MANEJO DE TIMERS ......................................................................................................................................... 234


52) LIBRERA DE TIMERS: timersJ.c ..................................................................................................................... 234
COMENTARIOS a ["Labs-C\Lab2\TimersJ\timersJ.c"]: ......................................................................................... 238
COMENTARIOS a ["Labs-C\Lab2\TimersJ\timersJ_.h"]:....................................................................................... 242
53) EJEMPLO #1 USANDO LIBRERA DE TIMERS .............................................................................................. 243
COMENTARIOS a ["Labs-C\Lab2\TimersJ\100TimedFlash8.c"] ........................................................................... 245
54) EJEMPLO #2 USANDO LIBRERA DE TIMERS .............................................................................................. 247
COMENTARIOS a ["Labs-C\Lab2\TimersJ\110TimedFlash8X4.c"]: ..................................................................... 249

SERIAL COMMUNICATIONS & DATA QUES IN C............................................................................................ 250


55) LIBRERA DE COMUNICACIONES SERIALES............................................................................................... 250
COMENTARIOS a ["Labs-C\Lab3\SciComm\SciComm.h"]:................................................................................... 253
56) Send 'A' to 'z' letters for ever, to PC ................................................................................................................... 257
COMENTARIOS a ["Labs-C\Lab3\SciComm\1tstXmt.c"]: ...................................................................................... 258
57) SEND STEP BY STEP (IRQ) 'A' TO 'Z' LETTERS TO PC & SHOW IN LEDS ................................................. 258
COMENTARIOS a ["Labs-C\Lab3\SciComm\1tstXmt-Leds.c"]: ............................................................................. 260
58) ECHO ................................................................................................................................................................. 262
COMENTARIOS a ["Labs-C\Lab3\SciComm\2echo1.c"]:....................................................................................... 263
59) ECHO USANDO INTERRUPCIONES............................................................................................................... 263
COMENTARIOS a ["Labs-C\Lab3\SciComm\3echoInt-1.c"]: ................................................................................. 265
60) ECHO CON INTERRUPCIONES, ASCIZ STRINGS ......................................................................................... 266
COMENTARIOS a ["Labs-C\Lab3\SciComm\3EchoInt-2Z.c"]: .............................................................................. 268
61) COLAS DE DATOS ............................................................................................................................................ 268
COMENTARIOS a ["Labs-C\Lab3\SciComm\Que.h"]: ........................................................................................... 270
62) COLAS DE DATOS: DEMOSTRACIN............................................................................................................ 274
COMENTARIOS a ["Labs-C\Lab3\SciComm\4quetst.c"]:....................................................................................... 276
63) CHAT POR INTERRUPCIONES, USANDO COLAS......................................................................................... 277
COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt.c"]: .................................................................................... 280
COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt_.h"]:.................................................................................. 282
COMENTARIOS a ["Labs-C\Lab3\SciComm\4InputPushButtons_.h"]:.................................................................. 283
64) BIG CHAT, INTERRUPCIONES, COLAS ......................................................................................................... 284
COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt-4.c"]:................................................................................. 286
FIN DE LA OBRA..................................................................................................................................................... 288

PRLOGO
CoDiDac, Computador Digital Didctico: In Memoriam.

ABSTRACT

ABIENDO dictado clases de Arquitectura del Computador a Ingenieros, sin solucin de


continuidad desde 1971 (43 aos y contando) y especialmente desde 2003 en la USB donde se
emplea para las prcticas la familia de 8 bits de Motorola/Freescale, he acumulado notas y
ejercicios que resultan de utilidad en mis clases, pues mi propsito es el de ir ms all de los
conocimientos tericos impartidos en los planes de estudio, que suelen tratar estos temas a nivel de
sistemas, y omiten referirse en estricto detalle y en profundidad, al hardware, al software, a los algoritmos
y a los problemas prcticos.
No hay forma tan eficaz como Aprender Haciendo (ah!), pero ese mtodo no est exento de
problemas; por ejemplo, para aplicarlo al estudio de los microcontroladores se requiere manejar con
precisin una enorme cantidad de detalles. Esa es la diferencia fundamental entre el enfoque del aula
y la aproximacin del laboratorio; y entre comprender los conceptos u ostentar destrezas de Maestro.
Estas notas pretenden mostrar una pequea pero importante fraccin de esos detalles, que se necesitan
para la lograr Maestra en la praxis, y que no se consiguen con facilidad ni en claustros ni en
bibliotecas. De hecho, en relacin a los ltimos exponentes de la familia de microcontroladores que nos
ocupa la MCS08 solo se ha identificado en el mercado un de libro de texto, de calidad precaria.
Desde luego, siendo ilimitado el mbito de lo que desconocemos, este aporte siempre resultar
insuficiente, con independencia de su extensin y otro autor habr, que aparezca calificando tambin
nuestro esfuerzo de insuficiente. De eso estoy conciente; este es un trabajo en evolucin. Habr que
aadir la utilizacin de ms perifricos (aunque los tiempos en mis asignaturas no dan para ms
dispositivos) y tcnicas avanzadas que incluyan la aproximacin a los Sistemas Operativos

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

INTRODUCCIN
ARQUITECTURA DEL COMPUTADOR: QU DEBEMOS ESTUDIAR

Es bastante conocida mi polmica opinin en relacin al objetivo de nuestro plan de estudios. Para
comenzar, permtaseme incluir una parfrasis:
Qu diramos de un mdico eminente que aplica los ltimos desarrollos de la instrumentacin electrnica para diagnosticar
acertadamente la pltora de pacientes que lo agobia, y que prescribiendo los ms modernos antibiticos de ltima generacin logra
mantener a raya difciles y dolorosas enfermedades; que interviene mediante tcnicas no invasivas a quienes no responden a los
medicamentos apropiadamente, para rescatarlos de la enfermedad y devolverles la salud pero que no tiene sino una superficial
aunque a todas vistas suficiente idea de los increbles principios fsicos que hacen funcionar el scanner y sus conocimientos de la
maravillosa qumica que se sintetiza en las cpsulas no le permitiran dirigir un laboratorio qumico, y que es completamente lego en relacin
al genial concurso que hacen la micromecnica, la ptica y la electrnica, aplicadas a las miniaturas que usa como utensilios quirrgicos?
Casi todos podramos convenir en que es un excelente mdico; sus pacientes lo veneran, los enfermos hacen lo imposible por ser
atendidos por l pero, probablemente de sus manos no salga el prximo CAT ni el tan esperado antibitico final, y tampoco lo
contratarn para disear el Escalpelo del Futuro. No ser un investigador, ni electrnico, ni qumico, ni micro-mecnico. Eso s, est al
tanto de conseguir y emplear las ltimas y ms certeras herramientas que se ofrecen para el ejercicio de su profesin Mdica.

Bueno, subyace aqu un dilema que en realidad parece sencillo: Qu queremos como egresado, un
cientfico, o un Ingeniero? Es claro que el ttulo que concedemos es el de Ingeniero...
Un ingeniero resuelve problemas en la industria (ojal que los de la USB lo hagan en Venezuela),
empleando dispositivos especializados y complejos, como el Core i7 de Intel, por ejemplo, que
cuando lo aplicamos no tenemos sino una muy aproximada idea de cmo est hecho un quadra-core.
Un ingeniero hace eso: aprende a usar la tecnologa como herramienta en su trabajo diario, y s que no
hay muchos de nosotros que pudiramos disear un Core i7 de Intel, ni ello resultara tampoco en gran
beneficio, pues Intel no adolece de profesionales en esa rea y Venezuela no tiene como prioridad
preparar ingenieros para trabajar en Intel
Quiero hacer las siguiente citas:
"A good Scientist is a person with original ideas. A good ENGINEER is a person who
makes a design that works with as few original ideas as possible. There are no prima
donnas in engineering. - Freeman Dyson (Nanotechnology father)" cfr en.wikipedia.org/wiki/Freeman_Dyson
Uno puede estar de acuerdo con esta afirmacin o rechazarla, pero todos debemos convenir en que, s,
es cierto que el mbito de accin de un cientfico no es el mismo que el de un Ingeniero, y que
nuestra carrera es la de Ingeniero Electrnico, no la de cientfico; ni siquiera la de profesor o docente.
Parafraseando a Martin Grimheden, del Royal Institute of Technology, que habla de la legitimidad de la
profesin:
The question of legitimacy is defined as the relation between the actual outcome of the educational efforts
undertaken by the university, and the actual demands that are put on the students abilities by the society and/or
industry at the end of the students education. To simplify: Why teach [electronics]? and What does the industry
want? (Y yo preguntara: qu quiere NUESTRA industria, para empezar...)
El artculo profundiza sobre knowledge and skills (teora y prctica): industries hiring
[electronics] engineers, search for functional skills rather than formal knowledge

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

En nuestro pas, y en Latinoamrica, probablemente tambin sea as. Y, a lo mejor, con los
INGENIEROS, en general, ocurra de la misma manera en todas partes! Solo cuando
pretendemos que los egresados funjan ms bien como Docentes o Investigadores, todo queda
medio al revs. O cuando ignoramos el patrn que para Ingenieros usan tan prestigiosas
instituciones como Stanford y el MIT.
En nuestra profesin NO se puede conocer un poco de todo; hay que saber USAR ese todo.
En 40 aos de ejercicio profesional, y en mi transicin desde profesor hasta el rea de proyectos:
ingeniero, gerente, vicepresidente de R&D, y en el perfil de empleado y de empresario (! y, de nuevo,
a profesor !), en las compaas en las que me desenvolv, contrat o trabaj con ellos a ms de 100
ingenieros, casi todos electrnicos, la mayora de la USB (NB: Cuando la profesora Trina Adrin de Prez hizo
la ltima encuesta externa para cambio de currculum, en mi empresa yo empleaba, simultneamente, 44 ingenieros electrnicos, 40
de la USB) Algo conozco del tema, y mi reales que me ha costado. OBSERVACIN: Yo podra

ser el profesor activo de la USB, que ms egresados de electrnica ha contratado)

Para m, el que diseaba amplificadores operacionales, microprocesadores, modems, e incluso


dispositivos de ms alto nivel no estaba capacitado para lo que yo necesitaba.
Yo requera siempre al que saba ENCONTRAR y EMPLEAR las herramientas ms apropiadas
de la tecnologa.
p

Como integrador de sistemas, nunca reinvent la rueda, y me fue bastante bien... en Venezuela!
Con lo anterior como premisa, yo abogo por un estudio de la Arquitectura (y los Sistemas
Operativos, y TODO lo que enseamos) orientado hacia la APLICACIN de la tecnologa a
la solucin de problemas. Si alguien quiere disear (micro)procesadores en Intel, se encontrar
con que las plazas ya estn copadas, que ese desarrollo lo hacen cientficos rara vez Ingenieros y
que son como 1,000 especialistas en todo el mundo.
Enfoque

Este libro no estudia cmo disear una computadora, y hace nfasis en cmo estn diseadas, no
en por qu estn diseadas as.
Observaciones sobre algunos trminos empleados

Siendo el Ingls la lingua mater de la investigacin electrnica, resulta en ocasiones difcil elaborar en
esa materia un texto en Castellano que no incurra en anglicismos, y aquellos que lo hacen pueden
terminar en un galimatas. Recuerdo algn impreso que traduca Master Clear como Limpieza
Maestra o, peor, buffer como Memorias Tampn, y flip-flops por bsculas.
Adems, he empleado la primera forma verbal en vez de la tercera, clsica y neutra, porque esto no es
una tesis ni un reporte de investigacin, y puedo darme el lujo de acercarme al lector hablando en
primera persona. El estudiante se abstendr de imitarme hasta que tenga tantos aos como yo.
Ing. Luis G. Uribe C.
Caracas, marzo de 2014.

Captulo

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

VON NEUMANN COMPUTERS


Quien no conoce la historia est condenado a repetirla, Jorge Santayana.

INTRODUCCIN

AS computadoras actuales (a m me encanta nombrarlas en femenino) pueden separarse en


trminos prcticos en dos clases: Harvard y Von Neumann. Muchas otras divisiones coexisten,
como CISC y RISC, siendo las ms utilizadas en la actualidad, por su cantidad, las CISC tipo
Von Neumann, aunque yo he trabajado con algunos RISC tipo Harvard: los Microchip de la
familia 16Fxxx.
La familia HC9S08 que nos ocupa es CISC de tipo Von Neumann, con instrucciones primordialmente
de una direccin, orientadas a Acumulador, como ya veremos.
QU ES UNA INSTRUCCIN

A las computadoras hay que programarlas, o instruirlas para que realicen sus actividades. Entienden,
para ese fin, un idioma propio de cada una de ellas, o Lenguaje de Mquina (Machine Language). El
programador emplea INSTRUCCIONES, compuestas de: a) una Voz Imperativa o COMANDO,
que le indica a la computadora qu operacin hacer en un instante determinado y b) la identificacin de
los operandos que deben participar en la accin.
Desde que estudibamos aritmtica aprendimos que un clculo largo, que inclua una cierta cantidad de
valores (operandos) y distintas operaciones aritmticas sobre ellos, poda descomponerse en una secuencia
ms simple de operaciones que incluyeran, como mximo, dos (2) operandos; as, por ejemplo:
F=A*BC/Dserealizacomo:
T1=A*B;T2=C/DyF=T1T2.
o:F=A*B;T=C/DyF=FT(seempleaunavariabletemporalmenos)

A las operaciones aritmticas elementales se las conoce como binarias, o didicas, porque
emplean dos operandos sobre los cuales actan para producir un (1) resultado. Lo mismo ocurre con
los operadores booleanos. Y aquellos que requieren un solo operando, como -5, o ~B (unarias o
mondicas) son un subconjunto y pueden recomponerse como binarios o didicos as: 0-5 o ~(0|B).

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Una computadora tiene una unidad Lgico Aritmtica (ALU: Arithmetic-Logic Unit) cuyos circuitos
realizan operaciones de suma y resta; otras incluyen multiplicacin y divisin y, las menos, soportan
-adems de nmeros Enteros representacin en punto flotante para nmeros Reales.
Para identificar los Comandos hay que codificarlos. Eso significa que si hubiera, por ejemplo, solo dos
operaciones (dos Comandos), podran representarse con un bit que, estando en 0 designara al primero
de ellos, y si valiera 1 sealara al otro. Si la Unidad de Control debe identificar 250 comandos dentro de
instrucciones (esa es la cantidad que tena el antecesor del HCS08) se necesitaran 8 bits, lo cual resulta
muy conveniente pues 8 son los bits que definen UN Byte, que es la cantidad mnima de bits que se
manipulan de una sola vez en las computadoras modernas.
Cuando tenemos procesadores con una cantidad superior a 256 Comandos (tal es el caso del nuevo
HCS08) podran codificarse con dos (2) bytes pero, como con 16 bits pueden individualizarse 65,536
entidades diferentes, se ve que habra una holgura innecesaria (dado que los computadores actuales no
tienen ms de alrededor de 1,000 y pico de cdigos de operacin, como orden de magnitud).
Entonces se usa un truco que codifica los Comandos ms empleados con un (1) byte, y para el resto usa
dos (2): uno llamado Escape, que advierte al procesador que, a continuacin, viene otro byte que es
el cdigo que en realidad identifica ese comando que por tanto requiere 2 bytes. Esta es la aproximacin
que se usa en el HCS08, y desde luego tambin en Intel.
As que para ver cuntos bits conforman una Instruccin tenemos que, para el Cdigo de Operacin, o
Comando (OpCode), se necesita un (1) byte.
Veamos ahora qu se requiere para codificar los operandos, que residen en la Memoria. La Unidad de
Control debe instruir a la memoria para que le suministre a la ALU cada operando, y para que reciba y
almacene el resultado. La Memoria o unidad de almacenamiento puede caracterizarse como un
dispositivo con dos dimensiones: qu se va a guardar (el Valor de la variable, consideradas ellas en el
sentido que se les atribuye al estudiar algn lenguaje de programacin), y dnde se va a almacenar ese
valor: Valor y Direccin. Sobre el Valor ya nos hacemos una idea de a qu corresponde. En cuanto a
la Direccin, las celdas o posiciones de memoria se numeran normalmente comenzando desde 0, en
incrementos comnmente de a uno, y cada una resulta as identificada mediante ese nmero, que se
conoce como la Direccin de la celda. Cuando decimos que debemos leer una variable (para hacer un
clculo), en lenguajes de programacin solemos identificarla mediante un Nombre, pero a la
computadora hay que sealrsela mediante un nmero, la Direccin sobre la cul la memoria debe
operar para entregarnos dicho Valor. As, una Variable identificada por el programador mediante un
Nombre, desde el punto de vista de la computadora equivale a una Direccin y un Valor.
Entonces, cuntos bits se requieren para identificar el Valor, y la Direccin? Ese nmero no tiene por
qu ser el mismo para ambos casos. Para el Valor, la mayora de los MCUs usan un (1) byte. Mquinas
ms nuevas emplean dos (2) bytes (16 bits), cuatro (4) bytes (32 bits); ahora se van imponiendo ocho
(8) bytes (64 bits) y ya llegarn hasta 16 bytes (128 bits). Ya eso me parece muy improbable.
Ahora, con una mquina comn de 32 bits, si cada dato es un nmero, ste puede representar enteros
hasta2^32=4,294,967,296 o, si llevan signo: de +2,147,483,647a2,147,483,648.

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

En el caso de las Direcciones se necesitan 4 bytes. Si tenemos dos (2) operandos que suministran
valores, y uno (1) para el resultado, y cada uno de ellos precisa cuatro (4) bytes para su identificacin, el
nmero de bytes de una instruccin sera de: 1 (OpCode) + 3 * 4 (Addresses) = trece (13) bytes.
Note que como son tres (3) operandos, a este tipo de computadoras se las conoce como Mquinas de
Tres Direcciones. Hay Instrucciones que tienen menos direcciones, como BORRE (Clear; V=0),
que tiene UNA sola direccin; y HALT, que no tiene ninguna.

MQUINAS DE 3, 2, 1 Y 0 DIRECCIONES

RECE (13) bytes son demasiados. Cada vez que se ejecuta una Instruccin, el CPU necesita
leer todos los bytes que la componen. Para obtener un alto rendimiento se requiere que se lea
la Instruccin con la menor cantidad de pasos posible; ojal UNA sola operacin. Para esto, el
Bus en el que se transfiere la informacin tendra un ancho exagerado, lo que resultara
costoso, adems de oponerse a los espacios pequeos que requieren los dispositivos modernos. Por
tanto, es importante ver cmo pueden eliminarse campos o elementos de la Instruccin. Recuerden
que con la codificacin del Comando hay poco que hacer, segn acabamos de describir.
El primer paso en este sentido se dio haciendo que uno de los 3 operandos de la Instruccin fuera, al
mismo tiempo, fuente de informacin y resultado; algo as como: A=A*B.
Eso, en realidad, elimina un operando (cuatro [4] bytes). Para que el sistema funcione hay que agregar
una instruccin que permita inicializar una variable con el contenido de otra; esta es un MOVE.
F=A*BC/Dserealizaahoracomo:
T=C(MOVETC;unasolaDireccin);T=T/D;F=A(MOVEFA);F=F*B;F=FT

A este tipo de computadora bien podra llamrsela Mquina de Dos Direcciones.


El segundo paso para eliminar de la Instruccin otro operando consisti en inventarse un dispositivo de
almacenamiento que al mismo tiempo fuera fuente de informacin y albergue del resultado; algo as
como: Acc = Acc * B en donde Acc, conocido como Accumulator, W [Working Register], H [Holding
Register] es un registro dentro del CPU, y es un elemento TCITO, que no requiere identificarse
porque es el nico que hay, con lo cual, la instruccin anterior slo tiene UNA Direccin. A estas
computadoras se las conoce como Mquinas de Acumulador, o, naturalmente, Mquinas de UNA
Direccin. Para que funcione el sistema hay que hacer que el Move anterior pueda llevar datos
DESDE la memoria hasta el Acumulador, y desde ste HACIA la memoria. Como ahora son dos
operaciones, reciben nombres diferentes: LOAD (AccMemory) y STORE (Memory Acc).
Nuestro ejemplo de siempre quedara resuelto de la siguiente manera:
F=A*BC/D,enunamquinadeAcumulador(UnaDireccin):
LOADC;(Acc=C).ObsrvesequenosemencionaelAcc;soloC
DIVIDED;(Acc=Acc/D:C/D)
STORET;(T=Acc:C/D)
LOADA;(Acc=A)
MULTIPLYB;(Acc=Acc*B:A*B)
SUBTRACTT;(Acc=AccT:A*BC/D)
STOREF;(F=Acc:A*BC/D)

10

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

ste ltimo result ser el sistema ms eficiente en relacin a los parmetros referidos al principio, y es el
que ms se usa en la actualidad: Instrucciones de Una Direccin; Mquinas de Acumulador.
Finalmente, se forz la barra y existen Mquinas de Cero Direcciones. Los computadores HP fueron
sus exponentes ms sobresalientes. Una aplicacin muy generalizada de esta aproximacin de Cero
Direcciones la encontramos en la evaluacin automtica de expresiones, principalmente como parte
de los Compiladores. La notacin ms divulgada se conoce como RPN, Reverse Polish Notation.
Los tipos generales de Direcciones: inmediata, directa, indirecta, modo registro, indireccin con
registros, desplazamiento, stack, basadas, segmentadas, deben consultarse en las referencias genricas.

HCS08 ARCHITECTURE: PROGRAMMING MODEL

L correspondiente diagrama puede verse en el Reference Manual del microcomputador:


CPU08RM.pdf, pgina 15.
Se tiene el Acumulador A, un registro de 8 bits con las caractersticas que acabamos de ver
para las Mquinas de Una Direccin.

Existe un registro ndice (H:X) de 16 bits, que fundamentalmente sirve como apuntador (pointer,
como en C); es decir, alberga: no el valor de una variable, sino la direccin de esa variable (exactamente
como en C). Se pueden realizar operaciones que mimeticen las equivalentes de alto nivel, tales como:
(*p se refiere al H:X):
*p=Acc;Acc=*p;*p++=Acc;Acc=*p++;p=*p;jump*p;...ysimilares.

Est tambin el Stack Pointer SP de 16 bits, que permite realizar el protocolo para la ejecucin de
Subrutinas o Funciones, as como el de las Interrupciones, y sirve para establecer la existencia de
variables dinmicas, como en el C, que se materializan con la llamada de una funcin y desaparecen a
su finalizacin.
Finalmente se encuentran otros 2 registros de uso ms especfico que los 3 anteriores: el PC o Program
Counter, de 16 bits, que en principio identifica la instruccin que habr de ejecutarse a continuacin,
y el Processor Status Word, cuyo nombre fue cambiado a CCR: Condition Code Register; es de 16
bits y almacena banderas (flags) individuales que identifican el estado del procesador en un instante
dado, y facilitan el control del flujo del programa (saltos condicionales, habilitacin de interrupciones).
El uso en detalle de todos estos elementos del MCU lo veremos ms adelante como parte del anlisis y
desarrollo de la secuencia de programas, objetivo principal de este texto.

MODOS DE DIRECCIONAMIENTO EN EL MC9S08 (CPU08RM Reference Manual)

El microprocesador HCS08 que se escogi en la USB para incluirlo como elemento de trabajo en sus
laboratorios de electrnica es casi perfecto para estudiar la Arquitectura de las Computadoras, por sus

11

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

enriquecidas caractersticas, casi todas tomadas de las minicomputadoras DEC de los 70s y siguientes.
(Motorola no fue la nica en adoptar tan bella tecnologa de las PDP-11; Intel incluye ms conceptos
an en sus microcomputadores). Ya vimos que, a diferencia de muchos dispositivos similares de sus
competidores, tienen un repertorio de instrucciones poderoso, variado y numeroso (no como las 35
instrucciones de los 16F8Xx). En cuanto a los modos en que emplea las direcciones, hay 17 distintos.
Aqu solo se enumeran; enfquese para su estudio en el Manual de Referencia del CPU: CPU08RM.
El uso en detalle de todos los modos de direccionamiento lo veremos ms adelante como parte del
anlisis y desarrollo de la secuencia de programas que presentaremos.
1) Inherent(noaddresses)
2) Immediate,8bitconstants
3) Immediate,16bitsconstants
4) Direct8bits(ZEROpage)
5) Extended16bits;"NATURAL"addressingmode:ABSOLUTE
6) Indexednooffset
7) Indexed,8bitoffset
8) Indexed,16bitoffset
9) Indexednooffsetwith(Indexregister)postincrement
10) Indexed,8bitoffsetwith(Indexregister)postincrement
11) SP,8bitoffset
12) SP,16bitoffset(noexisteSINoffset)
13) Relative(notforDATA!OnlyforCODEBranches)
MemorytoMemory,MM(Onlyadvanced++):
14) MM:ImmediatetoDirect
15) MM:DirecttoDirect
16) MM:IndexedtoDirect,with(Indexregister)postincrement
17) MM:DirecttoIndexed,with(Indexregister)postincrement
VARIACIONES Y OPTIMIZACIONES

Para optimizar el rendimiento del HCS08, maximizando velocidad y minimizando uso de memoria, se
incluyeron varias excepciones a la arquitectura convencional; primero, en el manejo de la memoria.
Normalmente la memoria de una computadora tipo Von Neumann consiste, como ya indicamos, en
una coleccin de celdas o elementos almacenadores, de informacin y programas, colocados en
Secuencia Lineal. (La unidad de almacenamiento de las mquinas tipo Harvard tiene la particularidad
de que la seccin que podemos usar para guardar datos emplea su propio conjunto de direcciones,
separado del grupo de direcciones de la memoria en la que se guardar el programa. Cada una de ellas
puede verse como un arreglo lineal, pero no estn contiguos el uno junto al otro. Es decir, que si por
ejemplo, se recorre la RAM o memoria de almacenamiento para variables, y se llega hasta el final, la
prxima posicin NO es la del cdigo del programa. En las mquinas tipo von Neumann hay UN solo

12

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

campo de direcciones. Al recorrerse todas las posiciones en secuencia, se habrn visitado tanto las
variables como el programa).

Si hay 2^16=65536posiciones(64 Kbytes) necesitamos desde luego 16 bits de Direccionamiento


para cada unidad elemental de almacenamiento, que en nuestro caso es el Byte (8 bits).
Motorola dividi la memoria, y a la primera seccin, compuesta de 256 posiciones (0x0000 a 0x00FF)
la llam Direct Page (Z RAM). Desde luego, si nicamente hubiera este grupo de unidades de
memoria, slo se necesitara 1 Byte (8 bits) para identificarlas, en lugar de los 16 bits que se requeriran si
la memoria fuera mayor. El truco consiste en multiplicar por 2 los cdigos de operacin, de tal manera
que se use, por ejemplo, Add0 para identificar la suma (Add) de una variable que est en Direct Page, y
que por lo tanto puede identificarse con un (1) solo Byte, y Add1 para indicar la suma de una variable
que no est localizada en Direct Page, y para la cual se necesitan dos (2) Bytes. As, si se coloca en
Direct Page la informacin ms utilizada, se puede lograr una economa en el tamao del programa,
que requiere menos bytes para accesar esas posiciones, y tiene mayor velocidad, porque hay que
cargar un byte menos. Si normalmente las instrucciones tienen un (1) byte para el OpCode y dos (2)
para la direccin (total: 3), que demoraran en su manipulacin 3 tiempos de lectura de Byte, tB; el
ahorro, al llevarlo a solo 2 bytes es de 1/3 en tB; as la velocidad aumenta en 50%: en el mismo
intervalo de tiempo se ejecuta un 50% ms instrucciones, si todos los accesos son en Direct Page.
As que podramos decir que dentro del Cdigo de Operacin para el Comando Add, hay un bit que
vale 0 o 1 e identifica si a continuacin de ese OpCode vienen 1 o 2 bytes de direccin. Es interesante
notar que el programa que nos ayuda a codificar a tan bajo nivel (inferior al C), llamado el Assembler, se
encarga de averiguar la posicin de las variables, de forma que el programador pueda usar un solo
cdigo, Add en este caso, y el Ensamblador incluye Add0 o Add1, segn corresponda a la ubicacin
de la informacin, en Page-0 o no. El programador queda as liberado de llevar la pista a las variables.

13

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

CODIDAC, VON URIBES COMPUTER


LA ARQUITECTURA

Consola de operador, con teletipo o tlex (Olivetti, Siemens), para el suministro de datos y
programa mediante el teclado, e impresin de resultados en papel. Automatizacin va lector
adjunto de cinta de papel. Tablero para despliegue de informacin interna: registros, direcciones,
instrucciones, botonera para encendido y dems funciones no realizables desde el teletipo.
LAS INSTRUCCIONES

14 instrucciones: Comandos para lectura de datos, impresin, 4 operaciones aritmticas, toma de


decisiones y bifurcacin en el flujo de control, desplazamientos de informacin a derecha e
izquierda, movimiento de datos entre diversas posiciones de memoria, borrado, espera y parada
codificadas en castellano. El CODIDAC deba realizar operaciones similares a las del FORTRAN.
El CODIDAC se diferencia de otros computadores porque tiene Clases de Informacin definidas
a nivel de mquina. En los computadores tipo Von Neumann la naturaleza de un elemento de
informacin no le es inherente; el significado se lo proporcionan las instrucciones que lo
manipulan. As, al sumar A con B, la instruccin de suma les otorga significacin numrica a las
variables; si hubiera a lo mejor texto en ellas, el computador no tendra forma de saberlo
Por ejemplo, para el CODIDAC la instruccin que desplaza informacin lo hace de una manera si
el operando es numrico y de otra muy diferente si representa un texto. En caso de nmeros, el
resultado siempre es un nmero; desplazar un nmero negativo produce siempre otro nmero
negativo. En caso de textos, el resultado siempre es un texto.
Incluso las Instrucciones pertenecen a una Clase! lo que permite realizar sobre ellas operaciones
aritmticas, en los campos de las direcciones de los operandos (numricos), para facilitar el manejo
de subndices, estructuras de datos, etc.
LOS MODIFICADORES

Un modificador cambia las operaciones, de simples a Repetitivas. Una sola instruccin de mquina, como
IM: IMprima, arroja un nico valor, o un Rango de resultados (IR: Imprima Repetitivamente).
EL SUBSISTEMA DE ENTRADA Y SALIDA

Forma parte esencial de la Arquitectura del CPU, con instrucciones especficas, ms poderosas que
el INPUT o PRINT del Basic y superiores al IN y al OUT de los microprocesadores.
CDIGOS DE OPERACIN

Como el aspecto didctico es preeminente, los cdigos tienen una base mnemnica de fcil
comprensin y recordacin: Cuando dos palabras designan un comando, se toma la primera letra
de cada una para conformar dicho cdigo. Por ejemplo, "Acepte Informacin" se codifica como
"AI", y las letras 'A' e 'I' se almacenan en la memoria, en cdigo baudot de 5 bits.

14

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Si el comando tiene una sola voz imperativa, como "SUME", el cdigo se conforma como "SU",
utilizando sus 2 primeras letras.
Si se requiere el modificador de iteracin, se reemplaza la segunda letra por una R: AR es Acepte
informacin de manera Repetitiva (desde, hasta), SR totaliza un rea completa de memoria, etc.
EL EDITOR

Para cargar el programa hay un editor de texto compuesto por circuitos (no es software). Para invocarlo
existe el interruptor "Funcin Programa", y el "Botn de Correccin" para corregir errores tipogrficos.
EL FORMATO DE LOS NMEROS

La informacin numrica se representa en BCD, en signo y magnitud, y es de "formato fijo": El


nmero de decimales se preestablece mediante selectores en la consola: desde 0 hasta 11 decimales.
Cada palabra de memoria almacena 12 dgitos BCD, o 16 letras. La unidad de salida imprime la Coma
de los nmeros en la posicin decimal designada, y obviaba la escritura de ceros no significativos, es
decir, el FORMAT est tambin incluido en la electrnica!
LA CALCULADORA

El CODIDAC puede operarse como calculadora, gracias al selector de Operaciones Inmediatas.


As, no hay que elaborar un programa para realizar operaciones aritmticas. Ningn otro computador
tiene esta caracterstica.
LA ESTRUCTURA

La mquina es del tipo serial, con lgica secuencial convencional, no microprogramada. Posee
selectores que permiten trabajar a mxima velocidad (600 KHz!) o en animacin lenta para
permitir el seguimiento del flujo de informacin. Tiene un interruptor de paso a paso; uno para
Detener la operacin del programa en cualquier instante, otro para Continuarla, y el Master Reset.
DATOS ESTADSTICOS

Est compuesto por ms de 4.000 circuitos integrados TTL, 300 transistores, 200 tarjetas de
circuito impreso; 160.000 puntos de soldadura, 155.000 agujeros perforados con taladro de mano;
16.000 cablecitos de alambre telefnico (2.500 metros) y ms de 5 kilos de soldadura de estao.
Diez fuentes de alimentacin, de 5 Voltios a 10 amperios, ms fuentecitas variadas para manejar las
luces de nen, el teleimpresor, etc., alojadas en un gabinete independiente. Dos disipadores principales
tienen como 1,70 metros de altura c/u. El consumo est por encima de los 3 kilovatios y para controlar
la generacin de calor hay una pequea turbina elctrica que fuerza la circulacin de aire en el gabinete
principal, as como un poderoso ventilador situado en la base del gabinete de alimentacin.
CIRCUITOS IMPRESOS

En los primeros dibujos para obtener los negativos fotogrficos se emplearon "rapidgrafos"; luego se
usaron cintas adhesivas, como pistas, y ojetes para las perforaciones.

15

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

FOTOS

1) VISTA GENERAL
A la izquierda se ve la consola formada por la mesa, el teclado y el impresor (tlex o teletipo) al
que se le alcanza a ver el rollo de papel de impresin y el perforador de cinta de papel, adosado al
lado izquierdo. Adems, el lector de papel. A la derecha se observa el panel de control (botonera)
y despliegue de informacin (luces).
El gabinete principal es el que est a la derecha, con 4 racks (se ven dos, uno arriba del otro). En el
de abajo alcanza a verse la memoria de ncleos magnticos de ferrita.
El tercer gabinete, pequeo, situado entre los otros dos, alberga las fuentes de alimentacin.

16

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

2) VISTA GENERAL DESDE OTRO NGULO


En el gabinete de las fuentes se ve un panel de control, con interruptores y borneras de
interposicin, as como las protecciones para sobrevoltaje, tipo Crowbar (un SCR quema un fusible).

17

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

3) ACERCAMIENTO
En esta foto no aparece el lector de cinta de papel.

18

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

4) MAYOR ACERCAMIENTO A LA CONSOLA

19

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

5) PRESENTACIN
Le enseo el proyecto a mi padre, y a mi hermano que es el fotgrafo.

20

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

6) CONSOLA DE CONTROL Y TELETIPO

21

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

7) CONSOLA DE CONTROL, VISTA DE FRENTE


Abajo a la izquierda, los contactores para encender el computador, y una luz piloto.
A la derecha, en dos grupos, los interruptores; los 7 primeros de la izquierda sirven para determinar el
nmero de decimales (0 a 11) con que trabajar un programa. A la derecha, la botonera de control: De
izquierda a derecha, los principales son Inicie; Funcin Programa; Corrija una lnea (borra y repite
la entrada); Arranque; Pare; Contine; Funcin Calculadora. Alcanzan a verse un botn para
mxima velocidad, otro para baja velocidad, y uno para paso a paso (el cono es una persona caminando).
En la parte baja del panel vertical, el despliegue de bits de cada registro. Con el selector de la izquierda se
escoge entre los registros A, B o C, o el de Instrucciones, para presentarlo mediante las luces de nen. La
informacin entra por la derecha y se desplazaba secuencialmente hacia la izquierda.
Ms arriba se indica el nmero del paso del micro-secuenciador. La instruccin ms larga tiene 18 pasos.
La siguiente franja tiene los conos que representan los catorce comandos:
Acepte Informacin, Compare por Igualdad, Compare por Magnitud, Lleve, Sume, Reste,
Divida, Multiplique, Desplace a la Derecha, Desplace a la Izquierda, Imprima, Borre,
Espere y Pare.
Los cuatro conos de la izquierda muestran errores de overflow, divisin por cero y dems. Y a la derecha,
la direccin de memoria que se est usando (000-999. Se est visualizando un 022)

22

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

8) GABINETE PRINCIPAL, VISTA ANTERIOR


Cuatro Racks con conectores (peines). Caben hasta 17 por fila, pero no todas estn completamente
pobladas Algunas tarjetas son de doble altura (dos conectores).
El rack inferior derecho es el de la memoria: los bastidores con los ncleos (entre lminas protectoras de
acrlico), las tarjetas controladoras (corrientes y sensores), y una fila con 100 palabras de almacenamiento
semiconductor, hechas con registros de desplazamiento normales que quedaron sin utilizar al terminar el
diseo.

23

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

9) GABINETE PRINCIPAL, VISTA POSTERIOR


Indicativo de la cantidad de cables de interconexin (no se utiliz Mother Board).

Resaltan los sensores remotos (cinco y cinco, en acrlico blanco) que leen a distancia el valor de las
10 alimentaciones y los llevan hasta los reguladores. As se garantizan el valor de los voltajes en el
destino, a pesar de la considerable separacin entre el gabinete de las fuentes y el de la electrnica.

24

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

10) GABINETE DE MEMORIA


Los ncleos estn localizados en cuatro (4) planos. Cada bastidor se alambr a mano, cruzando un
hilo de Excitacin (corriente) horizontal, llamado X, otro de Excitacin vertical, Y, uno de
Inhibicin, para cancelar la excitacin en las posiciones no seleccionadas, y el de Lectura. Los
ncleos magnticos son de 20 mils (milsimas de pulgadas de dimetro)

25

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

11) ACERCAMIENTO A LA MEMORIA DE NCLEOS MAGNTICOS

26

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

12) DETALLE DE LA UNIDAD DE CONTROL


Rack situado arriba a la izquierda en el gabinete.

27

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

13) DETALLE (POSTERIOR)

28

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

14) GABINETE DE FUENTES (VISTA ANTERIOR)


Se ven abajo los transformadores (nada pequeos!); un poco ms arriba, el ventilador para forzar
el aire y, a continuacin, las 10 fuentes.

29

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

15) GABINETE DE FUENTES (ACERCAMIENTO; VISTA ANTERIOR)

30

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

16) GABINETE DE FUENTES (VISTA POSTERIOR)


Se aprecia uno de los dos disipadores, con 5 transistores de potencia (de los 10 que eran en total).
Detrs de l se encuentra el segundo disipador. Puede observarse sus tamaos

31

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

17) MTODO DE ELABORACIN DE CIRCUITOS IMPRESOS (1)


Como ejemplo puede verse una seccin de la Unidad de Control.

32

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

18) MTODO DE ELABORACIN DE CIRCUITOS IMPRESOS (2)


Se escoge una parte de la seccin de la Unidad de Control, la que va a colocarse en una tarjeta de
circuito impreso. Se muestra la parte seleccionada, el dibujo tinta china y plumilla, hecho sobre
lmina flexible de acrlico (de las que se usan para el retroproyector), y el negativo fotogrfico que
se aplica sobre la tarjeta de cobre para realizar la exposicin, utilizando lmparas de luz muy fuerte.

33

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

19) MTODO DE ELABORACIN DE CIRCUITOS IMPRESOS (3)


Ejemplo de una tarjeta ya poblada de componentes (master clock, 16 fases). Vista anterior.

34

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

20) MTODO DE ELABORACIN DE CIRCUITOS IMPRESOS (4)


Master clock, vista posterior. Todas las tarjetas son de dos caras.

35

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

21) FORMATO DE LAS INSTRUCCIONES


Puede verse la codificacin de algunas instrucciones (as se escriben en el programa y as quedan
en la memoria): Acepte Informacin (AI), Acepte informacin de manera Repetitiva (AR),
Imprima (IM), Imprima Repetitivamente (IR), Sume (SU), Sume Repetitivamente (SR, que totaliza
un bloque de datos contiguos), Reste (RE), Multiplique (MU), Divida (DV; es la nica excepcin
de la codificacin, porque DI es Desplace a la Izquierda).
Ing. Luis Guillermo Uribe Catao
Revisin de Diciembre de 2012. Resumen de lo publicado por la Javeriana, 2011, y por Tekhne, en la UCAB.

36

Captulo

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

ASSEMBLER HCS08
"Perfection is finally attained, not when there is no longer

anything to add, but when there is no longer anything to take


away..." (Antoine De Saint-Exupry)

EJERCICIOS BSICOS EN ASSEMBLY LANGUAGE

ARA comprender los aspectos ms importantes de una computadora es imprescindible dar una
mirada a la manera como el programador le transmite lo que ella debe hacer, cmo se la
programa en forma nativa: su Conjunto de Instrucciones, cmo direcciona la memoria, cmo
usa el Stack, qu recursos tiene, tales como registros ndice, Stack. En nuestro empeo por
apoyarnos en el MC9S08QE128 de Freescale instalado en la tarjeta de desarrollo DEMOQE128,
hemos elaborado una serie de programas ilustrativos que presentamos a continuacin.
Estos ejercicios se dividen en 4: Introductorios; referentes a Timers, en donde explico la librera que
suministro siempre con mis cursos, para estudiarla y usarla; Comunicaciones con el PC, usando el SCI
(RS-232); aqu tambin analizamos una librera que desarroll para mis cursos, la estudiamos con detalle
y tambin debemos poder usarla en nuestros ejercicios y proyectos. Finalmente, ejercicios varios.
1) Primer Programa para el HCS08: MINIMUM Program for HCS08
Este es el programa ms pequeo que puede escribirse en el ambiente de desarrollo
CodeWarrior(laversinqueusoenlaactualidades:CodeWarrior10.5.TienesusBugs,
algunos reportados por m [enero de 2014], sin corregir, pero es lo que hay... NB:
MUCHOSambientesdedesarrollo,enelreadeMCUs,sondeJUGUETE)
Elobjetivodeesteprogramaesverificarquesuinstalacindelambientededesarrollo
funciona,ylosmnimosaspectosquedebeincluirensusprogramas.

["Laboratorios\Lab1\00a_L1.asm"]
01;********************************************************************
02;00a_L1.asm,MINIMUMProgramforHCS08,Rev.F,V08J2012M29E2013
03;LuisG.UribeC.,D27Y2007J09A2009.ForCodeWarrior10.2
04;===================================================================
05;BeginofCodeSection
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
07
08ORG$2080;ORG?Origin.Nextcode(bra)islocated
09;..atthisaddress!

37

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

10;$2080isHCS08ROMStart(Flash)
11;Main:symbolicforaddress$2080(bra)
12Main:bra*;Branchtohimself(BRA:BranchAlways;*:here!)
13
14;
15nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
16;This'nop'MAYberemovedforCW6.3...
17;********************************************************************
18;InterruptVectors
19
20ORG$FFFE;VECTORholdingaddressforHCS08startup
21DC.W$2080;...(RESET)DC.W:DefineCONSTANTWord
22END;ENDandnextlines,removedbyAssembler
23
24Note:NothingisreadafterEND...(cfr.'main.dbg')

COMENTARIOS a ["Laboratorios\Lab1\00a_L1.asm"]:

LaFORMAylaPRESENTACINdelCdigoennuestrareadetrabajooencualquierotra,
esFUNDAMENTALparalavidadelosproyectos.Losprogramasdebenpoderentenderse,por
quien los hace, cuando vuelva a mirarlos, y por las personas que vengan despus a
modificarlosorepararlos.
Paraesoserequierencomentariostiles,resaltantesyclaros.
Lo primero que hay que incluir siempre, en un programa, es el nombre del mismo, la
fecha o fechas en los que se hizo, o modific el programa. En este libro empleo
abreviaturasycomolasvariacioneshansidocosmticascasinuncalasrelaciono:
01;********************************************************************
02;00a_L1.asm,MINIMUMProgramforHCS08,Rev.F,V08J2012M29E2013
03;LuisG.UribeC.,D27Y2007J09A2009.ForCodeWarrior10.2

Enlaprimeralnea:
;00a_L1.asm,MINIMUMProgramforHCS08,Rev.F,

se coloca el nombre del programa, propsito del mismo, para qu plataforma y qu


revisin (identificacin que permite llevar la pista de las modificaciones que se le
hanhecho)
Adems, las fechas indican el comienzo del programa, cundo se lo modific y la
datacin de la revisin actual. Cuando es importante, hay que agregar una lista de
fechasycosasqueseaadieron,quitaronomodificaron.Tambin,lasinicialesdela
personaquehizocambiosenelcdigo,parasaberaquinpreguntarsifueranecesario.
02;..V08J2012M29E2013
03;..D27Y2007J09A2009.ForCodeWarrior10.2

EsteprogramasecomenzelDomingo27demaYode2007;eljueves09deAbrilde2009
se lo adapt al CodeWarrior 10.2 (ahora se sabe que funciona bien bajo la versin
10.5).Luego,elviernes08deJuniode2012selehizoalgunamodificacincosmtica
(porquenohaymayorreporte),ylaltimaedicinfueelmartes29deEnerode2013,
haceyaunao.
Ntese tambin la columna casi perfecta donde comienzan los comentarios. En Assembly
Languageserecomiendaqueel";"quemarcaelcomienzodeloscomentariossecoloque
EN la columna 32. A veces esto no es factible y hay que moverla, hacia atrs o

38

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

adelante,peroengeneraldebeutilizarseesaregla.SUSPROGRAMASTIENENQUEHACERSE
SIGUIENDOESTEYTODOSLOSLINEAMIENTOS.

Cuandounprogramasevaaejecutar(o,comotodoelmundodice,sevaaCORRER),hay
que indicarle al CPU dnde comienza el cdigo. Cada procesador tiene su propio
protocolo para esto. Por ejemplo, cuando se energizan los procesadores Intel, el PC
(ProgramCounter)asumeelvalor0xFFFF,paralosmicrosde16bits,y0xFFFFFFFFpara
losde32bits,comopartedeladefinicindesuEstadoInicial(unvalorde0x0000,
puros ceros, o 0xFFFF, puros unos, son cmodos de lograr, mediante las lneas
apropiadasdelosregistroscorrespondientes:ClearoPreset,respectivamente).Deesa
direccintomaelCPULAPRIMERAINSTRUCCINquehadeejecutarse.Comoesaubicacin
corresponde a la ltima posicin de la memoria, seguramente que all tiene el
programadorquecolocarunJUMPhaciasuverdaderaprimerainstruccin.
(Cmopuedecolocarseunainstruccinenlamemoria,sirecinseestenergizandola
mquina,yelestadoinicialdelaRAMesnormalmenteindeterminado,formapartedela
solucin al problema denominado IPL: Initial Program Loader. Revise en la literatura
delcursoenquconsisteconexactitudeseproblema,yculessonlassoluciones.Una
de ella consiste en que en la parte superior de la memoria de trabajo, voltil, se
coloca una ROM, o memoria de slo lectura, que contiene su programa, o un cdigo
destinadoabuscarsuprogramaylocalizarloenunsitioadecuado)
EnelHCS08,ustedtienequedecidirdndevaacolocarlaprimerainstruccindesu
programa.Esosehaceas:
SeleindicaalCodeWarriorquelaprimeradireccindesuprogramaes'Main'(tiene
queestarsegurodequeesasealaetiquetaapropiadadentrodesucdigo)
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)

Luego se le dice que coloque el cdigo de su primera instruccin, en la direccin


Hexadecimal$2080:

08ORG$2080;ORG?Origin.Nextcode(bra)islocated

ORG,porOrigin,leindicaalprogramaAssemblerqueelcdigoqueacontinuacinusted
vaaescribir,debecolocarlodemanerasecuencialapartirdeladireccinindicada;
$2080ennuestrocaso(queparaelHC9S08QE128queempleamos,eslaPRIMERAdireccin
de la memoria FLASH, que es su almacenamiento no voltil. Para una identificacin
precisadelasreasocupadasporlaRAMylaFlash,remtasealmanualMC9S08QE128RM
(ReferenceManual)
Luego,elprogramadortienequecolocarsu'Main'(ustedescogeasugustoelnombre;
notienequeserMain,siemprequeuseelmismoentodasaquellaspartesenlasqueyo
loincluenesteejemplo...)
11;Main:symbolicforaddress$2080(bra)
12Main:bra*;Branchtohimself(BRA:BranchAlways;*:here!)

Note que se enfatiza en que el smbolo mnemnico, alfabtico, 'Main', tiene una
equivalencia con el nmero $2080. Usted emplea 'Main'; el CPU usa $2080 (16 BITS EN
BINARIO,QUEESLONICOQUELASCOMPUTADORASENTIENDEN!)
Ahoraobservelalnea15;sehacolocadoeseNOPporqueserequiereenlasversiones
10.x(almenoshastala10.5;NOeranecesarioenlaversin6.xynorecuerdohaberlo
usadoenversionesanteriores,lasquecomencausarporallporla3.x,haceeones)
15nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
16;This'nop'MAYberemovedforCW6.3...

39

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Siestalneaseomite,elDebuggerproduceunerroraltratardeejecutarel'bra*'
(saltoinfinitoasmismo)delalnea12.EstoesunerrordelCodeWarrioractual.
Finalmentevienen losInterrupt Vectors de la lnea 20. Resulta que, a diferencia de
Intelque,comoyadijimos,inicializasusPCparaleerLAPRIMERAINSTRUCCINdesu
programaSIEMPREdesdelaltimadireccindememoria,elMotorola/Freescaleinicializa
tambinsuPChacialaltimadireccinWORD(16bits)delaFlash(16bitsqueocupan
$FFFE y $FFFF), PERO ALL LO QUE ESPERA encontrar es LA "DIRECCIN" DE LA PRIMERA
INSTRUCCINDESUPROGRAMA.Elmecanismoqueseempleaparaestablecerestevnculose
formadelasiguientemanera:
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
08ORG$2080;ORG?Origin.Nextcode(bra)islocated
...
12Main:bra*;Branchtohimself(BRA:BranchAlways;*:here!)
...
20ORG$FFFE;VECTORholdingaddressforHCS08startup
21DC.W$2080;...(RESET)DC.W:DefineCONSTANTWord

En06usteddefinelaEtiqueta(Main)enlaquevaacomenzarsuprograma,eindicaen
qu posicin (vlida) de Flash la va a colocar (el resto de su cdigo va a
continuacin!);luegoenla12estsu'Main'y,enla20ysiguientesseculminael
vnculo: cuando el PC asume su valor inicial, $FFFF, el CPU, que est en la fase de
inicializacin, usa ese PC para cargar un valor de 16 bits, que corresponde a la
direccindesuprimerainstruccin.Reemplazasu$FFFFporloqueestalmacenadoall
(elnmero$2080enelejemplo)ydeesaposicintomalaprimerainstruccinquevaa
ejecutar,deSUprograma.

Al espacio en donde se colocan los valores de arranque (o RESET), y otros que luego
estudiaremos, se loconoce comoel rea de Vectores de Interrupcin. Comienzan en la
LTIMA posicin de memoria, y va creciendo HACIA ABAJO, de a dos posiciones, porque
cadaelementodeinformacinallalmacenadocorrespondeadirecciones(dearranque,o
derutinasdeinterrupcin:ISR),ylasdireccionessiempretienen16bits.

TodoprogramafinalizaconunEND:

22END;ENDandnextlines,removedbyAssembler
24Note:NothingisreadafterEND...(cfr.'main.dbg')

Se ha incluido ex professo la lnea 24, con texto comn y corriente, para enfatizar
que,despusdelENDdelprogramaprincipal,elEnsambladorNOleeabsolutamentenada
ms.Puedeusarse,portanto,esareaparaincluirtextocualquiera,comocomentarios.

TengaCUIDADO:AlgunosensambladoressuspendenelanlisiscuandoencuentranCUALQUIER
END. A veces, si a un INCLUDE FILE, similar al que ya conoce del C, se le coloca
inadvertidamente un END, el programa queda procesado hasta all, y con mucha
probabilidadesonoesloqueelprogramadordesea...
2) Segundo Programa para el HCS08: Init COP & STACK
Hay un cdigo mnimo que SIEMPRE debe incluir en sus programas, y se indica a
continuacin:

40

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

["Laboratorios\Lab1\00c_L1.asm"]
01;********************************************************************
02;00c_L1.asm,MINIMUMProgramforHCS08,V08J2012
03;LuisG.UribeC.,J09A2009.ForCodeWarrior10.2
04;===================================================================
05;BeginofCodeSection
06ABSENTRYMain;Exportsymbol(DEBUGGERentry)
07
08ORG$2080;HCS08ROMStart(Flash)
09;
10;***ALWAYS***includethefollowing4instructions
11
12Main:lda#$42;$42(%0100_0010)?COPE(SOPT1b7)=0($1802)
13sta$1802;(SOPT1Pupinitto$C2=%1100_0010)
14ldhx#$1800;InitStackPointerSP(HCS08)
15txs;$1800?RAMEnd+1.SP=RAMEnd:$17FF
17;
18bra*;Branchtohimself(BRA:BranchAlways;*:here!)
19
20;
21nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
22;This'nop'MAYberemovedforCW6.3...
23;********************************************************************
24;InterruptVectors
25
26ORG$FFFE;"Vector"holdingstartingaddress,
27DC.W$2080;...(RESET)DC.W:DefineCONSTANTWord
28END

COMENTARIOS a ["Laboratorios\Lab1\00c_L1.asm"]:
Cuatrolneassehanaadidoporlassiguientesdosrazones:

PRIMERA: Casi todos los microcontroladores (MCU) incluyen un dispositivo que por
hardwareloinicializan(resetean)sinosehacumplidociertoprotocoloconl;selo
conocecomoel"WatchDog".Supropsitoeselderestaurarlamquina,talcomosise
hubieraactivadolasealdeRESET(osehubieraencendidoelMCUenesemomento).Bien
instrumentado, puede evitar costossimos desplazamientos a reinicializar nuestros
equipos,encasodequeporalgunafluctuacinenlaenergaelctrica,oimpactocon
unrayogammaopartculasalpha,elflujodelprogramatomeunderroteronoprevisto.
EnelMC9S08QE128alWatchDogseloconocecomoCOP:CpuOperatingProperly.Enlos
programas que se cubren en esta publicacin NO se utiliza el COP, pero hay que
DESACTIVARLO porque el MCU lo tiene activo al aplicrsele la energa. Ese es el
propsitodelcdigodelaslneas:
12Main:lda#$42;$42(%0100_0010)?COPE(SOPT1b7)=0($1802)
13sta$1802;(SOPT1Pupinitto$C2=%1100_0010)

SehanincluidovaloresenHexadecimal,peroluegoveremosquehayunmecanismoquenos
permitehacerreferenciasSIMBLICAS,queofrecenmayorclaridadaquiencodificaya
quienluegoquiereentenderelprograma.

41

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

EnelregistroSOPT1(SYSTEMOPTION1,ubicadoenlaposicin$1802)sedeshabilitael
COP: COPE=0: COP Enable=0. Como esta es una mquina de Acumulador, se necesitan dos
instruccionesparahacerelMOVEdeundatoaunavariable:LOADAccumulatorcon#$42y
STOREAccumulatoralaposicin$1802(lneas12y13).
Nteselasangradeunespacioqueheincluidoenlalnea13conrespectoala12.
Sirve para enfatizar que las dos instrucciones fsicas realizan una sola operacin
lgica.Usteddebetratardehacerlomismo.Luegoaprenderemosunmecanismo:MACROs,
que le permiten definir sus propias instrucciones, como MOVE, que reemplazan a la
secuenciadeLDAySTAsealadas.
SEGUNDA razn: Al encender el MCU el Stack Pointer (SP), al igual que el PC, se
inicializaenunvalortilparatodoslosmodelosdeMCUdelasfamiliasHC05yHC08,
algunosdeloscualesquepuedentenermuypequeaRAM.Ennuestrocasonoesas;en
el HC9S08QE128 hay mucha RAM (8064 bytes reporta el Reference Manual), as que el
manufacturanterecomiendainicializarelstack(vaelSP)as:
14ldhx#$1800;InitStackPointerSP(HCS08)
15txs;$1800?RAMEnd+1.SP=RAMEnd:$17FF

Observendenuevolasangra.

Debido a ciertas peculiaridades de la Arquitectura de este MCU, la instruccin TXS


(TransferindeXtoSp)RESTAunUNOalregistrondiceH:XANTESdetransferirelvalor
originalalSP.Poreso,dadoquelaltimaposicindeRAMesla$17FF,yqueelStack
arrancarah(ycrecerhaciaABAJO),hayquecolocarenH:Xelvalor$1800.

3) Programacin en Lenguaje de Mquina (HEX) para el HCS08:


Se presenta la forma ms elemental en la que se le pueden dar las instrucciones al
Microprocesador.Comoyadijimos,loscomandosdelasinstruccionesseindividualizany
diferencian unos de otros, identificndolos mediante la asignacin de un nmero, o
CdigodeOperacin(OpCode).EldiseadordelMCUhacelaasignacin,yhayunatabla
enlaquesecolocanloscomandosysuCdigodeOperacin.As,siqueremosborraruna
variablequehemoslocalizadoenlaprimeraposicindelaMemoriadeAccesoDirectoo
Pgina0(ZRam)necesitaremosbuscarelcdigodelCLEARyescribiralgoas:

Main:DC.B$3F;DefineConstantByte.$3F$80?CLR$80
DC.B$80;$80?DirectAddress

PorsuerteelprogramaAssemblerpermitereferirnosalosOpCodemediantelosSMBOLOS
queelmanufacturantedefiniparaellos(CLRparaBORRARmemoria,etc.),ynotenemos
niqumemorizarsuscdigoshexadecimalesnibuscarentablaslasequivalencias.

Setratadeemplear,alMXIMO,smbolosalfanumricos,losdelasinstrucciones,ya
las variables y ciertas posiciones de cdigo tambin les damos NOMBRES, ojal con
significadoclaroypreciso,talcomosehaceenC.Elobjetivoeseldehacernosms
fcil la composicin, lectura e interpretacin del cdigo, y ese mecanismo pretende
ELEVARELVALORSEMNTICODELLENGUAJE,queyadepors,esbastamteBAJO

Puedeversecompletoestetercerejemploacontinuacin:

42

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

["Laboratorios\Lab1\01a_L1.asm"]
01;********************************************************************
02;01a_L1.asm,MINIMUMHCS08ProgramRev.E,V08J2012>>HEXADECIMAL<<
03;LuisG.UribeC.,D27Y2007J09A2009.ForCodeWarrior10.2L21N2013
04;Minimumaspectsneededtowriteaprogram:
05;1.DefineprogramORG($2080andup)
06;2.Writetheprogram(lookupforeachinstructioncodeinHex)
07;3.DefineRESETAddress(vector$FFFE)
08;NOTE:Lookup"SortedHCS08_ISet2013U.pdf"forOp.Codes
09;===================================================================
10;BeginofCodeSection
11ABSENTRYMain;Exportsymbol(DEBUGGERentry)
12
13ORG$2080;HCS08ROMStart(Flash)
14Main:DC.B$3F;DefineConstantByte.$3F$80?CLR$80
15DC.B$80;$80?DirectAddress

16DC.B$3C;LOOP:$3C,$80?INC$80(directvariable)
17DC.B$80;$80?DirectAddress

18DC.B$20;BRALOOP
19DC.B$FC;$FC?Relativeoffset.BRA*:$202($FE)
20;$FC?4.PCpointstoNOP.PC4is'LOOP'
21;
22nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
23;This'nop'MAYberemovedforCW6.3...
24;********************************************************************
25;InterruptVectors

26ORG$FFFE

27DC.B$20;ResetVectorHIGH
28DC.B$80;ResetVectorLOW(HCS08isBIGENDIAN)
29
30END
31;
32Byteaddressableprocessorsmaybecategorizedasbigendian,
33littleendian,orbiendian.
35AmultibytenumericalvaluestoredwiththeMOSTsignificant
36byteintheLOWESTnumericaladdressisstoredinbigendian
37fashion.
39ThelittleendianstylestorestheMOSTsignificantbyteinthe
40HIGHESTnumericaladdress.IntelmicroprocessorareLITTLEENDIAN.
41
42Abiendianprocessorcanhandlebothstyles(Motorola'sPowerPC).

COMENTARIOS a ["Laboratorios\Lab1\01a_L1.asm"]:
Hay varios documentos en los que pueden encontrar la asociacin entre Comandos y
OpCodes.Porejemplo:

08;NOTE:Lookup"SortedHCS08_ISet2013U.pdf"forOp.Codes

43

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Primerosedefine,comosiempre,laasociacinparaelvectordeRESET:

11ABSENTRYMain;Exportsymbol(DEBUGGERentry)
13ORG$2080;HCS08ROMStart(Flash)
14Main...

El resto del programa inicializa la variable en cero, la incrementa y retorna a


incrementarlaporsiempre.Puedeverificarelcomportamientodelprogramamedianteel
Debugger, que permite correrlo paso a paso, e ir viendo cada vez el contenido de la
variableenlaposicin$80:

14Main:DC.B$3F;DefineConstantByte.$3F$80?CLR$80
15DC.B$80;$80?DirectAddress
16DC.B$3C;LOOP:$3C,$80?INC$80(directvariable)
17DC.B$80;$80?DirectAddress
18DC.B$20;BRALOOP
19DC.B$FC;$FC?Relativeoffset.BRA*:$202($FE)
20;$FC?4.PCpointstoNOP.PC4is'LOOP'

En cuanto a las lneas 18 y 19, que codifican un salto incondicional (BRA: Branch
Always)al"Loop"deIncremento,esinteresantenotarlosiguiente,queesdeusocomn
entrecasitodolosprocesadores:

Pararealizarunsaltoaalgunaposicindecdigodentrodelamemoria,elOpCodees
elquecorresponda,ennuestrocasounBRA,yluegohayqueidentificarlaposicina
lacualsaltar.ComoelprogramaenunamquinadeVonNeumannpuedeestarencualquier
parte de la memoria, se necesita identificar una direccin de 16 bits, en nuestro
micro,quedireccionaenformanatural,64KBytes.Deesamanera,lasinstruccionesde
ramificacin,quemodificanelflujodelprograma,yqueformanunodelosgruposms
usados,tendran3bytes:unoparaelOpCodeydosparaladireccin.

Unaformadeoptimizacinenestamateriaselogramediantelasiguienteobservacin:
la gran mayora de saltos se realizan en la "LOCALIDAD", que es un concepto que
identifica de manera genrica, las posiciones cercanas a la direccin del salto; sus
VECINAS. Y esa localidad es muy numerosa en un rango de 127 posiciones adelante, y
hasta 128 atrs. Lo cual es muy conveniente, ya que esa informacin es la que se
codificamediantebytesconsigno(signedchars).As,selograquelasinstrucciones
de ramificacin que ms se emplean tengan solo DOS bytes: uno para el OpCode, y uno
para el DESPLAZAMIENTO (no se indica a dnde, sino que se sealan cuntas posiciones
adelanteoatrs,medianteunOffset).Desdeluego,hayungrupodeinstruccionesque
permiten saltar a cualquier lado. En esta mquina, los BRANCHES son RELATIVOS, es
decir, emplean Desplazamientos que indican el offset en RELACIN a la instruccin. Y
losJUMPSsonabsolutos,empleandireccionesde16bits.

Lointeresanteeselmecanismoparacalcularladireccinefectiva,destinodelsalto:
Alaposicinactual(registradasiempremedianteelPC),seledebesumarelOffset
consignoparaobtenerasladireccindelaprximainstruccin.

Sedicebienperohaydoscosassutilesqueaclarar.Laprimeraesenrelacinaluso
delPC.Losegundo,vercmolasdirecciones,quesonnmerosSINsigno,sumanbiencon
losOffset,quesonnmerosCONsigno.

44

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

LaoperacindelPC,entodoslosmicrosqueconozco,escomosigue:secomienzaconel
PC apuntando a la prxima instruccin que se va a ejecutar. Cuando se trata de
instruccionesdevariosbytes,comoeselcasodelBRANCH,apuntaalOpCode.Cuandose
comienza a ejecutar la instruccin, en el ciclo de Fetch, el CPU lee, usando la
direccinalmacenadaenelPC,elOpCode,yapuntahaciaelsiguienteelemento.Estolo
hace incrementando el PC. Es decir, para cada lectura se produce la siguiente
secuencia:

InstructionRegister=*PC++;//secargaelOpCodeyseapunta
//..alsiguientebyte:elOffset
*DataBuf=*PC++;//secargaelOffsetyelPC,enestecaso,
//..apuntaalprximobyte:NextOpCode.

Ahora,siladireccindelcomienzodelainstruccinesN,alfinalizarlasecuencia
anteriorelPCalbergaN+2.Asqueunainstruccincomo:BR*,enlaquesedesea
haceruncicloinfinitodesaltosasmismo,elOffsetquehayquecolocares...2.
DeesamaneraelprximoPCserPC=N+22=N,queeraladireccinoriginal.

O sea, es importante al calcular el Offset, recordar que para el momento de la


aplicacindePC+Offset,elPCapuntadosbyteshaciaabajo.

ESTA ES LA FUENTE DEL ERROR EN EL CODEWARRIOR, para solucionar el cual tuve que
agregarelNOPdelqueyahemoshablado.CuandoseejecutaelBRANCH,elPCapunta
MSALLDELAMEMORIAQUELEHASIDOASIGNADAALPROGRAMA.AllNOhaycdigo,y
el Assembler cree que se ha cometido un error, cuando en realidad no es as. De
hecho,laversin6.3funcionamuybiensineseNOP.

Enrelacinalsegundopunto,unodelosproblemasdelcuestionariopidedemostrarque
aunnmerosinsigno(unadireccin)selepuedesumarunoCONsigno(elOffset),yel
resultado es perfecto: la direccin requerida, adelante o atrs, de la direccin
original.

ESTAPROPIEDADDELOSNMEROSCONSIGNO,CODIFICADOSENCOMPLEMENTOADOS,ESLARAZN
PRIMORDIAL POR LA CUAL SE USA ESTA REPRESENTACIN NUMRICA, y no se emplean el
complementoa1(nimuchomenosotrasmsengorrosas,comoSignoyMagnitud).

Enlapartefinaldelejercicioseejemplificaelordenenqueunainformacinde16
bits(2bytes)deberepresentarseenunamquinaBIGENDIAN,comoeselcasodelHC08:
Yendodesdelasdireccionesinferioreshastalassuperiores(de$FFFEa$FFFF),primero
se coloca el byte de Mayor valor y a continuacin, de ltimo, va el final: la parte
Menos significativa del nmero. La informacin termina (END) en la direccin mayor
(BIG);deaheltrminoBIGENDIAN.

(Si este fuera un microprocesador Intel, en la misma secuencia de direcciones los


valores almacenados seran, primero, $80 y luego, $20: LITTLE ENDIAN; es decir el
nmerotermina[END;$80]enlapartemasbajadememoria[LITTLE]):

25;InterruptVectors
26ORG$FFFE
27DC.B$20;ResetVectorHIGH
28DC.B$80;ResetVectorLOW(HCS08isBIGENDIAN)

45

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

4) Invente su propio Instruction Set para el HCS08:


InventeSUpropioInstructionSet.Estocasinuncaseusa,peroilustralamaneracomo
trabajaelAssembleraltraducirloscdigosqueustedlesuministra.

Ademshayalmenosunamaneramsavanzadadehacerloqueesteejercicionosmuestra,
abasedeMACROs,peroesovendrdespus.

["Laboratorios\Lab1\01b_L1.asm"]
01;********************************************************************
02;01b_L1.asmSymbolicProgram(Userdefined)Rev.FV08J2012M29E2013
03;LuisG.UribeC.,J09A2009
04;Aspectosmnimosnecesariosalescribirunprograma:
05;1.Definirposicininicialdelcdigo.$8000up
06;2.Escribirelprograma(buscarcdigoHEXdec/instruccin)
07;HacerSUpropioconjuntodeinstruccionesenSimblico.
08;3.DefinirDireccindeiniciodeejecucinluego
09;deReset(vector$FFFE)
11;
12;ParameterDefinitions(UserdefinedSYMBOLSvia'EQU')
13;Youmaydefinewhateversymbolsyoulike...YourownAssemblyLanguage!
14
15START:EQU$2080
16STARTh:EQU$20
17STARTl:EQU$80

18XCLR:EQU$3F;Instructionclr,tomadadelReferenceManual
19XOP1:EQU$80;Operand(1stvariable)forclrandinc
20XINC:EQU$3C;Instructioninc,delReferenceManual
21XBRA:EQU$20;Instructionbra,delReferenceManual
22XOFF:EQU4;Offsetforinstructionbra
23RESET:EQU$FFFE;VectordeInterrupciones
24
25;===================================================================
26;BeginofCodeSection
27ABSENTRYMain;Exportsymbol(DEBUGGERentry)
28
29ORG$2080;HCS08ROMStart(Flash)
30Main:DC.BXCLR;LaterTRAYTHIS:Stepsome,InsertBREAK
31DC.BXOP1;..POINTinMain.>>RUN<<CWwillstop..
32loop:DC.BXINC;..here.WHY?**BECAUSECOPisENABLED**!
33DC.BXOP1;loop
34DC.BXBRA
35DC.BXOFF
36;
37nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
38;This'nop'MAYberemovedforCW6.3...
39;********************************************************************
40;InterruptVectors
42ORGRESET
44DC.BSTARTh;ResetVectorHIGH
45DC.BSTARTl;ResetVectorLOW(HCS08isBIGENDIAN)

46

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

46
47;NOTE:IfyouremoveALLreferencestoRESET,STARThandSTARTl...
48;theprogramcontinuestobe"debugged"fine!
49;TheDEBUGGERusesthe'ABSENTRYMain'instead...
50;TheactualCPUNEEDstheRESETVector(Vreset)

COMENTARIOS a ["Laboratorios\Lab1\01b_L1.asm"]:
Lo primero es generar SUS propios OpCodes. Los hemos comenzado con una 'X' para
ayudarnosconladiferenciacinentresuscdigosylosdelmanufacturante.

18XCLR:EQU$3F;Instructionclr,tomadadelReferenceManual
19XOP1:EQU$80;Operand(1stvariable)forclrandinc
20XINC:EQU$3C;Instructioninc,delReferenceManual
21XBRA:EQU$20;Instructionbra,delReferenceManual
22XOFF:EQU4;Offsetforinstructionbra
23RESET:EQU$FFFE;VectordeInterrupciones

Lapartesiguienteesmuysimilaralejercicioanterior:01a_L1.asm:

29ORG$2080;HCS08ROMStart(Flash)
30Main:DC.BXCLR;LaterTRAYTHIS:Stepsome,InsertBREAK
31DC.BXOP1;..POINTinMain.>>RUN<<CWwillstop..
32loop:DC.BXINC;..here.WHY?**BECAUSECOPisENABLED**!
33DC.BXOP1;loop
34DC.BXBRA
35DC.BXOFF

40;InterruptVectors
42ORGRESET
44DC.BSTARTh;ResetVectorHIGH
45DC.BSTARTl;ResetVectorLOW(HCS08isBIGENDIAN)

5) Usando los OpCodes del Fabricante para el HCS08:

Elmismoejercicioanterior,01a_L1.asm,todoescritoenlenguajeSIMBLICO.Yausted
nousaSUSpropiosOpCodes,sinolosdeMotorola.

Usted(casi)NUNCAdebeemplearnmeros;lossmbolosalfanumricos,comoenelC,son
ms o menos descriptivos, dependiendo de lo bien que usted se aplique a hacer las
definiciones. Pero, un nmero como $40, difcilmente ser recordado como la cantidad
numricaqueseusaparadeshabilitarelCOP,cuandoseloalmacenaenel$1802(SOPT1)

["Laboratorios\Lab1\01c_L1.asm"]
01;********************************************************************
02;01c_L1.asmSymbolicProgram(Userdefined),Rev.EV08J2012
03;LuisG.UribeC.,J09A2009
04;Aspectosmnimosnecesariosalescribirunprograma:
05;1.Definirposicininicialdelcdigo.$2080up
06;2.Escribirelprograma(buscarcdigoSIMBLICOdec/instruccin)
07;3.DefinirDireccindeiniciodeejecucinluego

47

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

08;deRESET(vector$FFFE)
09
10;
11;ParameterDefinitions
12
13START:EQU$2080;comienzodelaFlash
14RESET:EQU$FFFE;vectorparaindicarcomienzodelcdigo
15
16;
17;Definicindevariables
18
19Var:EQU$80;unaformadeidentificarvariables
20
21;====================================================================
22;BeginofCodeSection
23ABSENTRYMain;Exportsymbol(DEBUGGERentry)
24
25ORGSTART;HCS08ROMStart(Flash)
26Main:clrVar;Ensayar:clrVAR(maysculas.Daerror)
27loop:incVar
28braloop
29;
30nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
31;This'nop'MAYberemovedforCW6.3...
32;********************************************************************
33;InterruptVectors
34
35ORGRESET
36DC.WMain;RESET:HCS08PowerOn(PON)procedure.
37END

COMENTARIOS a ["Laboratorios\Lab1\01c_L1.asm"]:
Loselementosimportantesson:

11;ParameterDefinitions
13START:EQU$2080;comienzodelaFlash
14RESET:EQU$FFFE;vectorparaindicarcomienzodelcdigo

Asociannmerosasmbolosalfanumricos.DicemuchomsRESET,que$FFFE.

17;Definicindevariables
19Var:EQU$80;unaformadeidentificarvariables
Muchomejorelsmbolodealtonivel'Var',ynotenerquerecordarquesudireccines
la$80,queademspuedecambiarsiseagreganoeliminanvariables.

25ORGSTART;HCS08ROMStart(Flash)
26Main:clrVar;Ensayar:clrVAR(maysculas.Daerror)
27loop:incVar
28braloop

48

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Luego usaremos el smbolo ROMStart, que es el definido por el manufacturante. Las


etiquetasdeprogramalucencomoenC.(Conustedesesunproblemahacerreferenciasal
C,cuandocontodaseguridadNINGUNOusnuncaetiquetasparaidentificarpartesdesu
cdigoenC.As,nopuedobasarmeensus(des)conocimientosdeCparaayudarmeenlas
explicacionesdeestecurso.Lstima...)

33;InterruptVectors
35ORGRESET
36DC.WMain;RESET:HCS08PowerOn(PON)procedure.

Todo en simblico. Tampoco usaremos 'RESET', pues hay una serie de smbolos para la
tabladeInterruptVectors,definidosporelmanufacturante.

6) Forma DEFINITIVA para programar el HCS08:

FULLUseofMotorola'sSymbolicLanguage

Ahoras;estaesLAformadefinitivaqueusteddebeusarparaescribirsusprogramas.

["Laboratorios\Lab1\01d_L1.asm"]
01;********************************************************************
02;01d_L1.asmUseofMotorola'sSymbolicLanguage,Rev.EV08J2012
03;LuisG.UribeC.,J09A2009
04;Aspectosmnimosnecesariosalescribirunprograma:
05;1.Definirposicininicialdelcdigo.$8000up
06;2.Escribirelprograma(buscarcdigoSIMBLICOdec/instruccin)
07;3.DefinirDireccindeiniciodeejecucinluego
08;deRESET(vector$FFFE)
09
10;
11;Includefiles:Workexactlylikein"C";defineprocessorsymbols:
12;..Z_RAMStart,ROMStart,INT_RESET,registers,I/Oports...
13;..derivative.incispreparedbytheProjectWizzard,foreachCPU.
14
15INCLUDE'derivative.inc'
16;
17;Definicindevariables
18
19ORGZ_RAMStart;$80
20
21Var:DS.B1;DS.B?1bytevariablesName&DataStorage
22
23;===================================================================
24;BeginofCodeSection
25ABSENTRYMain;Exportsymbol(DEBUGGERentry)
26
27ORGROMStart;HCS08ROMStart(Flash)
28Main:clrVar;ensayar:clrVAR(maysculas.Daerror)
29loop:incVar
30braloop
31;

49

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

32nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
33;This'nop'MAYberemovedforCW6.3...
34;********************************************************************
35;InterruptVectors
36
37ORGVreset
38DC.WMain;RESET:HCS08PowerOn(PON)procedure.
39END
40
41SEE'MC9S08QE128.inc'forSymbolsDefinitionslike:
42Z_RAMStart;$80
43ROMStart;HCS08ROMStart(Flash)
44Vreset
45
46'MC9S08QE128U.inc'was***COMPLETLY***REARRANGEDandBEAUTIFIEDby
47LuisG.UribeC.,J07J2012,forDOCUMENTATIONPURPOSESONLY.DoNOT
48REPLACEtheoriginal...

COMENTARIOS a ["Laboratorios\Lab1\01d_L1.asm"]:
Estecdigononecesitaexplicacinadicional.

7) CODE SECTION, DATA SECTION, en el HCS08:


Yahemosvistocmo,paracomenzaraescribirnuestroprograma,comenzamosdefiniendo
un ORG START (START, o su equivalente que cada vez usaremos menos: $2080). En
CodeWarriorestonorecibeunaidentificacinparticular,peroenotrosensambladores,
ydadoqueallseestdefiniendocdigo,selodenominaCODESECTION.Yhay,porlo
mismo, un DATA SECTION, cuando queremos definir variables de manera simblica (que
todavanohemosvisto).Unusomuyatractivoesquenospermitecomenzarescribiendo
cdigoenelCODESECTIONyluego,cuandoidentificamoslanecesidaddeusarunaoms
variables,cambiamosaDATASECTION,definimoslavariable,ynosdevolvemosalsitio
donde bamos con otro CONTROL SECTION. (Estas parejas reciben el nombre genrico de
PROGRAMSECTIONS.Unlenguajedealtonivelmuyfamosoquehizousodeestassecciones
fueelCobol,copiadoluegoporelPL1deIBM,enelqueyotrabajcuandohacami
maestraenSistemas,haycomounmillndeaos...)

Si quisiramos tener facilidad de hacer lo mismo en CodeWarrior (lo cual est en un


niveluntantomsavanzadodeloquecorrespondeaestecurso,queNOesuncursode
Lenguajes, sino de ARQUITECTURA), la forma es la que se indica en el ejercicio a
continuacin,nicoentocarseestetema.

["Laboratorios\Lab1\01e_L1.asm"]
01;********************************************************************
02;01e_L1.asmSymbolicAssemblyLanguage,Rev.EV08J2012
03;LuisG.UribeC.,J09A2009
04;ADVANCEDwaytodefinevariables...
05;
06;Includefiles
08INCLUDE'derivative.inc'
09;
10;Parameterdefinitions

50

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

12ram:setZ_RAMStart;Set'ram'to$80
13;
14;VariablesDefinicin(ADVANCED)
15
16ORGram;Startin$80
17
18Var:DS.B1;DS.B?1bytevariablesName&DataStorage
19Varend:
20ram:SETVarend;$81
21
22ORGram;Restartin$81
23Var2:DS.B1
24Var2end:
25ram:SETVar2end;$82
26
27ORGram;Restartin$82
28Var3:DS.B1
29Var3end:
30ram:SETVar3end;$83...andSOON.
31
32;====================================================================
33;BeginofCodeSection
34ABSENTRYMain;Exportsymbol(DEBUGGERentry)
36ORGROMStart;HCS08ROMStart(Flash)
37Main:ldhx#Var
38ldhx#Var2
39ldhx#Var3
40bra*
41;
42nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
43;This'nop'MAYberemovedforCW6.3...
44;********************************************************************
45;InterruptVectors
46
47ORGVreset
48DC.WMain;RESET:HCS08PowerUp(Pup)procedure.
49END

COMENTARIOS a ["Laboratorios\Lab1\01e_L1.asm"]:
LaprimeranovedadeselusodeINCLUDEfiles:

06;Includefiles
08INCLUDE'derivative.inc'

Esta parte deber incluirse SIEMPRE en sus ejercicios, de ahora en adelante. El


ambiente de desarrollo particulariza (customize) o parametriza una serie de
definiciones,afindehacerlomsportableposiblelosprogramas.Ynuestrainterfaz
coneseresultadoesatravsdeesalnea08:INCLUDE'derivative.inc'

Luego,ladefinicindevariables,empleandounORG,talcomoparaelcdigo,peroen
lasdireccionescorrespondientesalasvariables:laRandomAccesMemory,RAM:

51

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

ORGram:

10;Parameterdefinitions
12ram:setZ_RAMStart;Set'ram'to$80
13;
14;VariablesDefinicin(NORMAL,LAQUEUD.DEBEEMPLEAR)
16ORGram;Startin$80
18Var:DS.B1;DS.B?1bytevariablesName&DataStorage
23Var2:DS.B1
28Var3:DS.B1

Hastaalllapartecomndeladefinicindevariables,queustedSIEMPREusarensus
programas.

Ahora,sisedesearadefinirunavariable,ymsadelanteotra,yluegootra,eltruco
consiste en REDEFINIR la posicin 'RAM' para que lleve la cuenta hasta adnde hemos
llegadodefiniendovariables.Poreso,enelprogramaqueestamosanalizandoelcdigo
NO va como las 8 lneas anteriores, sino que en realidad es como se ilustra a
continuacin.

ComencemosdiciendoqueenelHC9S08QE128,lasreasdeRAMson:
Z_RAMStart:equ$00000080
Z_RAMEnd:equ$000000FF

RAMStart:equ$00000100
RAMEnd:equ$000017FF

RAM1Start:equ$00001880
RAM1End:equ$0000207F

NOTEquehayunAGUJERO,unespacionodefinidodentrodeesecampodedirecciones;lo
emplean REGISTROS usados en perifricos. En la $1800, por ejemplo, se encuentra el
registro

SRSSystemResetStatusRegister;0x00001800

Entonces,elcdigobajoanlisises,enrealidad,comosigue:

10;Parameterdefinitions
12ram:setZ_RAMStart;Set'ram'to$80
13;
14;VariablesDefinicin(ADVANCED)
16ORGram;Startin$80
17
18Var:DS.B1;DS.B?1bytevariablesName&DataStorage
19Varend:
20ram:SETVarend;$81
21
22ORGram;Restartin$81
23Var2:DS.B1
24Var2end:

52

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

25ram:SETVar2end;$82
26
27ORGram;Restartin$81
28Var3:DS.B1
29Var3end:
30ram:SETVar3end;$83...andSOON.

En realidad, en esta secuencia contigua SOLO HACE FALTA lo que ya se ilustr en las
lneasinmediatamenteanteriores:10,12,14,16,18,23,28.

Peroustedpuedehaceralgocomoesto:

ORGram;Startin$80
Var:DS.B1;DS.B?1bytevariablesName&DataStorage
Varend:
ram:SETVarend;ram=$81

ORGrom;Startin$2080
;...CDIGO,CDIGO,CDIGO
ActualRom:
rom:SETActualRom;rom=$20XX(dondesuprogramavaya)

ORGram;Restartin$81,enesteejemplo
Var2:DS.B1
Var2end:
ram:SETVar2end;ram=$82

ORGrom;Startin$20XX(dondesuprogramaiba)
;...MS_CDIGO1,MS_CDIGO1,MS_CDIGO1
ActualRom1:
rom:SETActualRom1;rom=$20XX(dondesuprogramavayaahora)

ORGram;Restartin$82
Var3:DS.B1
Var3end:
ram:SETVar3end;$83...andSOON.

ORGrom;Startin$20XX(dondesuprogramaiba)
;...MS_CDIGO2,MS_CDIGO2,MS_CDIGO2
ActualRom2:
rom:SETActualRom2;$20XX(dondesuprogramavayaahora...)

yyasehacenunaidea."THEPOOR'SMANPROGRAMSECTIONaproach"...

Elrestodelprogramanotiene,enesteejemplo,mayoresdificultades:

36ORGROMStart;HCS08ROMStart(Flash)
37Main:ldhx#Var
38ldhx#Var2
39ldhx#Var3
40bra*

53

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Trate usted de cambiar el programa para incluir cdigo de verdad, entremezclado con
definicindevariables.

Auncuandoleparezcaarrevesadoestemododeprogramacin(y,enrealidad,ases),lo
que ocurre es que cuando estamos haciendo uso de MACROs, que son rutinas que se
escribenenotraspartes,olibreras,yendondepuedenecesitarseagregarvariables,
queustednohaprevistoenelprogramaprincipal,esasMACROspuedenhacerusodeeste
mecanismo, si se establece un protocolo (ojal de aplicacin automtica) que permita
marcar el sitio en donde el programa principal iba al momento de llamar a la MACRO,
definir las variables a las que hubiera lugar, y luego dejar el CODE SECTION en el
precisovalorendondeelprogramalonecesita.

Programayconceptosmuyimportantes,peroquealniveldeestecurso,endondeNOse
estestudiandoenrealidadelAssemblerLanguage,noestanrelevante.Peroparam,
quedeboescribirlesrutinasybibliotecasdeellas,esfundamental.

PROGRAMAS AVANZADOS EN ASSEMBLY


LANGUAGE, PARTE I

8) Serie de Fibonacci.

EsteprogramaloadaptdelmanualdelAssemblerEclipse(lanuevaversin10.xsebasa
enEclipse,unIDEgratuito,construidoporIBM,yregaladoalacomunidad.Esusado
por Microchip, y ahora por Freescale, y otros. Est siendo adaptado en muchas
plataformas.Porejemplo,eldesarrolloparacelularesANDROIDsebasaenlaplataforma
Eclipse...)

No hay mayores comentarios sobre este programa. Usted debe ser capaz de decir cmo
funcionay,encasodeduda,acudaalDebuggerdelCodeWarrior,sigaelprogramapasoa
paso,ypodrhacerseunaideadelfuncionamiento).

["Laboratorios\Lab1\02Fibonacci.asm"]
01;********************************************************************
02;02Fibonacci.asm,LuisG.UribeC.,V10A2009V08J2012
03;ADAPTEDfrom:HCS08RS08_Assembler_MCU_Eclipse.pdf,Listing4.1
04;
05;Includefiles
06NOLIST
07INCLUDE'derivative.inc'
08LIST
09;
10;Parameterdefinitions
11
12ram:SETZ_RAMStart;$80
13initStack:EQU$1800
14COP_Disable:EQU%01000010;$42
15;
16;Definicindevariables(ds:bytepordefecto)

54

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

17ORGram
18
19Counter:DS.B1
20FiboRes:DS.B1;Aquvalarespuesta
21;===================================================================
22;BeginofCodeSection
23ABSENTRYMain;Exportsymbol(DEBUGGERentry)
24
25ORGROMStart;HCS08ROMStart(Flash)
26;
27;***ALWAYS***includethefollowing4instructions
28
29Main:lda#COP_Disable
30staSOPT1;SystemOptions1
31ldhx#initStack;InitSP
32txs
33;
34mainLoop:
35clra;UseAccumulatorasacounter
36;
37cntLoop:
38inca
39cbeqa#14,mainLoop;Largervaluescauseoverflow
40staCounter;Updateglobalvariable
41bsrCalcFibo
42staFiboRes;Storeresult
43ldaCounter;..ActivateBREAKPOINTheretosee...
44;..123581321345589144233
45bracntLoop;Nextround
46;====================================================================
47;FunctiontocomputeFibonaccinumbers.ArgumentisinA
48
49CalcFibo:
50dbnzafiboDo;FibonacciDo
51inca
52rts
53;
54fiboDo:
55psha;Thecounter
56clrx;Secondlast=0
57lda#$01;Last=1
58;
59FiboLoop:
60psha;Pushlast
61txa
62add1,sp
63pulx
64dbnz1,sp,FiboLoop
65
66;
67FiboDone:
68pulh;Releasecounter

55

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

69rts;ResultinA
70;
71nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
72;This'nop'MAYberemovedforCW6.3...
73;********************************************************************
74;InterruptVectors
75
76ORGVreset
77DC.WMain;RESET:HCS08PowerUp(Pup)
78END

COMENTARIOS a ["Laboratorios\Lab1\02Fibonacci.asm"]:
Unaspectoaresaltar:

05;Includefiles
06NOLIST
07INCLUDE'derivative.inc'
08LIST

NOLIST es una Pseudo operacin que indica al Assembler que el contenido del include
file NO lo incluya en los listados que se producen como resultado del proceso de
ensamblaje. De esta manera, slo queda en esos listados, para su documentacin,
informacinqueustedconsidererelevante.

Debajo del include file es menester rehabilitar la generacin de los listados, con
LIST,yaquedelocontario,TAMBINSUCDIGOsereliminado.

9) Empleo de Subrutinas; Identificacin de Modos de Direccionamiento.

Esteprogramaenfatizaenelusoelementaldellamadasafunciones,osubrutinas(BSR).
Adems, se identifican algunos modos de direccionamiento empleados. La tabla de
Vectores de Interrupcin se ha ampliado para incluir IRQ (Interrupt ReQuest, un pin
externo del MCU que al activarlo genera una interrupcin), SWI (una instruccin
diseada para servir de interfaz con el Sistema Operativo: SoftWare Interrupt, muy
valiosa)yelconsabidoRESET.SevuelveamencionareltemadesuspensindelPROGRAM
SECTIONparavolverdespus.

IRQySWIenrealidadNOjueganningnpapelenesteprograma;seescribisuentrada
enlatabladeInterruptVectorssimplementeparavercmoseincluiran.

["Laboratorios\Lab1\Lab1_M\03a_L1_M.asm"]
01;********************************************************************
02;Programa03a_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03;
04;NuevosAspectos:
05;
06;EmpleodeunaSUBRUTINAdentrodelprograma,mediante"bsr"parael
07;..llamadoy"rts"paraelretorno.Seusanlosdireccionamientos:
08;InherenteDirectoInmediatoRelativo
09;

56

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

10;Includefiles
11NOLIST
12INCLUDE'derivative.inc'
13LIST
14
15;
16;Parameterdefinitions
17ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
18rom:SETROMStart;$2080
19initStack:EQU$1800
20COP_Disable:EQU$42
21
22;
23;Definicindevariables(DS:DATASTORATE;Bytepordefecto)
24ORGram
25
26var:DS1;EquivalenttoDS.B
27
28;====================================================================
29;BeginofCodeSection
30ABSENTRYMain;Exportsymbol(DEBUGGERentry)
31
32ORGrom;$2080:HCS08ROMStart(Flash)
33
34;
35;***ALWAYS***includethefollowing4instructions
36Main:lda#COP_Disable
37staSOPT1;SystemOptions1
38ldhx#initStack;InitSP
39txs;..
40;
41loop:clrvar;DirectAddressingMode
42bsrrutina;RelativeAddressingMode
43braloop;..
44
45;====================================================================
46;Subrutinadeejemplo
47rutina:
48ldavar
49cbeqa#10,fin;Terminacuandovarllegaa10
50incvar
51brarutina
52fin:rts;COLOCARBREAKPOINTAQU(Debugger)
53
54
55;********************************************************************
56;*SpuriousInterruptServiceRoutine(UnwantedInterrupt)*
57;********************************************************************
58spurious:
59rti
60;
61;SivaacambiardeORG,yluegodebecontinuarconelCdigo:

57

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

63endrom1:
64rom:SETendrom1
66;********************************************************************
67;*InterruptVectors*
68;********************************************************************
69
70ORGVirq
71DC.Wspurious;IRQ
72DC.Wspurious;SWI
73DC.WMain;RESET
74
75;********************************************************************
76;IFyouneedtocontinuewiththeprogram...:
77
78ORGrom;rompointsto:endrom1.Notneededhere
79
80END

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03a_L1_M.asm"]:
Las pocas cosas nuevas seran, una rutina DUMMY (no hace nada), para efectos del
ejemplo:

58spurious:
59rti

LamarcaparacambiardeCODESECTION:

61;SivaacambiardeORG,yluegodebecontinuarconelCdigo:
63endrom1:
64rom:SETendrom1

LaasignacinparalatabladeVectoresdeInterrupcin:

67;*InterruptVectors*
70ORGVirq
71DC.Wspurious;IRQ
72DC.Wspurious;SWI
73DC.WMain;RESET

Y, por si necesitara seguir escribiendo el programa, aqu est la continuacin del


manejodelCODESECTION:

76;IFyouneedtocontinuewiththeprogram...:
78ORGrom;rompointsto:endrom1.Notneededhere
...(Contina...)

10) Introduccin a las INTERRUPCIONES


Este es nuestro primer ejemplo, aunque muy simple, en el que se toca el tema de las
Interrupciones, que son una gran adicin al modelo del computador, sin las cuales
seranimpensableslascomputadorasmodernas,yqueapesardeellosonelPEORDOLOR

58

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

DECABEZAdeunprogramadordesistemasEmbebidos...AsqueHAYQUEANDARSECONMUCHO
CUIDADOcuandoincluyamosInterrupcionesennuestroscdigos.Tienequehacersedeuna
maneraMUYDISCIPLINADA.LosSistemasOperativosaslohacen.

["Laboratorios\Lab1\Lab1_M\03b_L1_M.asm"]
001;********************************************************************
002;Programa03b_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013V22N13
003;
004;NuevosAspectos:
005;
006;UsodeRutinasdeInterrupcin:
007;a)InclusindelcdigodelarutinadeInterrupcin(Interrupt
008;ServiceRoutine,ISR),usando"RTI"pararetornardesta.
009;b)DefinicindelosVectoresdeInterrupcindeacuerdoconla
010;fuentedelainterrupcin;enestecaso:"IRQ".Suvectorde
011;interrupcionesestenVirq($FFFA$FFFB).Sehausadola
012;etiqueta"IRQISR"paradesignarladireccindelarutina
013;c)HabilitacindelperifricoparaInterrumpir
014;d)HabilitacindelCPU(CLI)paraqueacepteInterrupciones
015;(apartedeladelRESET)
016
017;
018;Includefiles
019NOLIST
020INCLUDE'derivative.inc'
021LIST
022
023;
024;Parameterdefinitions
025ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
026rom:SETROMStart;$2080
027initStack:EQU$1800
028COP_Disable:EQU$42
029
030;
031;Definicindevariables(ds:bytepordefecto)
032ORGram
033
034var:DS.B1;EquivalenttoDS
035
036;===================================================================
037;BeginofCodeSection
038ABSENTRYMain;Exportsymbol(DEBUGGERentry)
039
040ORGrom;$2080:HCS08ROMStart(Flash)
041
042;
043;***ALWAYS***includethefollowing4instructions
044Main:lda#COP_Disable
045staSOPT1;SystemOptions1
046ldhx#initStack;InitSP
047txs;..

59

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

048
049;
050;EnableInterruptsforIRQ
051;
052BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
053;
054;..Clearanypossibleprevious,false,interruptsbySetting
055;..IRQACKbitinIRQSC(IRQStatusandControlregister)
056BSETIRQSC_IRQACK,IRQSC
057;
058BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
059;
060
061cli;CPUInterruptENABLE
062
063;
064loop:clrvar;DirectAddressingMode
065bsrrutina;RelativeAddressingMode
066braloop
067
068;====================================================================
069;Subrutinadeejemplo
070rutina:
071ldavar
072cbeqa#10,fin;Terminacuandollegaa10
073incvar
074brarutina
075fin:rts;COLOCARBREAKPOINTAQU(Debugger)
076
077
078;====================================================================
079;EJEMPLOdeRutinadeInterrupcin(ISRforIRQsignal)
080;NOTE:EsnecesariorealizarunACKNOWLEDGEparaquelainterrupcin
081;vuelvaasuceder(InterruptHandshaking...differentforeach
082;peripheralequipment.NeedtoreadManualforeachone...:(
083IRQISR:
084clrvar
085BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
086;..(rearmIRQInterrupts)
087rti
088
089;********************************************************************
090;*InterruptVectors*
091;********************************************************************
092;(Estaparteesmsomenosestndar,
093;..exceptoquenormalmenteseincluyenTODOSlosperifricos...)
094spurious:
095rti
097ORGVirq;ChangeORG
098DC.WIRQISR;<<<IRQDefined
099DC.Wspurious;SWI
100DC.WMain;RESET

60

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

101
102END
103
104NOTE:IfinCW10.2,IRQdoesNOThaveanyeffectifyouare
105debugginginFullChipSimulation(FCS)andyouareusingstepby
106step(F5).YouneedtomakeabreakpointintheISRandthenRUNat
107fullspeed:F8.Now,IRQworks...
108
109GURIBE,M29E2013

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03b_L1_M.asm"]:
Cuando se trata del MCU hay varios pasos que se deben seguir al trabajar con
perifricos;alomejorhaydispositivosalosquenoseaplicantodoslospasos...Lo
primeroes,aveces,definirciertosvaloresoescoger,porejemplo,lafuentedeCLOCK
(comoenelcasodelascomunicaciones,SCI:SerialCommunicationInterface;perifrico
al que hay que definirle primero las caractersticas del canal de comunicaciones:
velocidad,nmerodebits,paridad,nmerodestopbits...ANTESdehacernadams).

Luego,hayque"ENERGIZAR"elperifrico.Muchosdispositivosnoestnconectadosala
alimentacinelctrica,dentrodelMCU,mientrasnoselosnecesite,conelpropsito
de ahorrar en consumo de energa. Esto es lo que yo denomin "ACTIVATE" en el
tratamiento del SCI. Ntese que cuando operamos con perifricos de comunicaciones en
realidadcadaunodeellospuedeversecomoDOScomponentes:eldetransmisinyelde
recepcin.AlomejorhayqueACTIVARcadaunodeellosporseparado(Revisarvezpor
vez el manual). En el caso del SCI es as, y en nuestros ejemplos yo ACTIVO ambos
transmisoryreceptoralmismotiempo,mediantelaoperacin'XmtRcvActivate'.
Despus, hay que habilitar las interrupciones (Peripheral Interrupt Enable) de los
dispositivosnecesarios,queyahansidoapropiadamenteinicializadosyACTIVADOS.

Por ltimo se debe habilitar al CPU para que procese interrupciones. Esa es la
secuencia genrica de actividades para habilitar perifricos para que interrumpan el
procesamientolinealdedatosdelCPU.

Ademsdetodo,hayqueestablecerlaidentificacinde:QUrutinadebeatenderCUL
interrupcin. El mecanismo que se emplea es mediante un link en el Vector de
Interrupciones, que tiene una posicin reservada para cada perifrico, o parte del
dispositivosqueestencapacidaddeinterrumpir.Porejemplo,enelcasodelSCI,el
transmisor tiene su propio vector de interrupciones; tambin lo tiene el receptor, y
asimismo lo posee el Control de Errores de Recepcin. En otros equipos, como los PC
compatiblesIBM/AT,hayunvectoradicionalparaelmanejodelModem,odispositivode
comunicacinconelcanaltelefnicoconvencional.

Finalmente, hay que escribir por aparte la rutina ISR que atender cada dispositivo
habilitado para hacerlo. Cada ISR tiene que responder de la manera convencional; por
ejemplo,unarutinadeinterrupcindeRecepcinenelSCI,tienealmenosqueleerel
datoqueestllegando,yquehaocasionadolainterrupcin,colocarloenelreade
memoriadispuestoparaeso(normalmenteunaCOLA,oQUEUE),indicarlealperifricoque
yaseloatendi(InterruptAcknowledge;estafuncionalidadenequiposmenosprimitivos
la suministra el hardware, pero en la mayora de los microcontroladores, el software
tiene que participar en mayor o menor grado en el protocolo de Aceptacin de
Interrupciones).

61

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Losconceptosnovedososaquson:elEnabledelIRQ(queNOdesusInterrupts,sinodel
PINdeIRQ):

052BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
054;..Clearanypossibleprevious,false,interruptsbySetting
055;..IRQACKbitinIRQSC(IRQStatusandControlregister)
056BSETIRQSC_IRQACK,IRQSC

Note que se le est dando, de entrada, un Acknowledge al perifrico, por si alguien


habaactivadoelinterruptorANTESdequelohubisemoshabilitadoparaelproceso...

Esta es una de las partes MAS COMPLICADAS en los sistemas reales (no de
laboratorio). Por ejemplo, cuando conectamos una Estacin Maestra (un PC) a un
grupo de dispositivos remotos que estn operando (RTUs, Remote Terminal Units),
probablemente, al habilitar la interfaz de comunicaciones del PC, ya las RTUs
estn comunicndose! Comenzar una comunicacin desde el PC, a la mitad de una
transmisindelaRTU,puededarlugaralosmsespinososproblemas...

LuegovienelahabilitacindelasINTERRUPCIONES,propiamentedicha:

058BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable

Y,finalmente,lahabilitacindelCPUparaqueaceptelasinterrupcionesexternas:

061cli;CPUInterruptENABLE

ESTOS SON LOS PASOS, EN ESE ORDEN, QUE DEBEN SEGUIRSE SIEMPRE PARA ACTIVAR LAS
INTERRUPCIONESDELOSPERIFRICOSQUENECESITEMOS.

Larutinaprincipalesmuysimpleenesteejercicio,conelnimodenooscurecerel
problemadelasinterrupciones;consisteenuncicloqueincrementalavariable'var'
de0a10,yrepite...

064loop:clrvar;DirectAddressingMode
065bsrrutina;RelativeAddressingMode
066braloop
068;====================================================================
069;Subrutinadeejemplo
070rutina:
071ldavar
072cbeqa#10,fin;Terminacuandollegaa10
073incvar
074brarutina
075fin:rts;COLOCARBREAKPOINTAQU(Debugger)

Cuando se interrumpe el proceso oprimiendo el botn de IRQ, la IRQISR (rutina de


interrupcin del perifrico IRQ) en este sencillo ejemplo, simplemente coloca la
variable'var'acero:

083IRQISR:
084clrvar

62

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Despus, le indica al perifrico IRQ que ha sido atendido (protocolo de Ack de


Interrupciones), de tal manera que el dispositivo perifrico pueda volver a
interrumpir, si fuera necesario (lo que se conoce como REARMAR la interrupcin), y
retornaalflujoprincipaldelprograma(RTI):

085BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
086;..(rearmIRQInterrupts)
087rti

Por ltimo se culmina con la parte estndar de las definiciones de los vectores de
interrupcin,yavistavariasvecesconanterioridad.

11) Ejercicio con ms Aspectos Nuevos:


DefinicindeconstantesenlaROM(Flash,memoriadeprograma)
DireccionamientoIndexadoconPostincremento(X+)enKBI1para
leerconsecutivamentede'Table'.

["Laboratorios\Lab1\Lab1_M\03c_L1_M.asm"]
001;********************************************************************
002;Programa03c_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
003;
004;NuevosAspectos:
005;
006;DefinicindeconstantesenlaROM(Flash,memoriadeprograma):
007;Unatabladevaloresconsecutivosenunazonadelamemoriade
008;programaDIFERENTEaladelcdigo(instrucciones).Paraestose
009;hautilizadoDC(defineConstant),Bytespordefault.Losvalores
010;correspondenalcdigoASCIIdeloscaracteres'Hola',seguidos
011;deun"nulbyte"(0)
012;
013;DireccionamientoIndexadoconPostincremento(X+)enKBI1para
014;leerconsecutivamentede'Table'.
015;
016;Includefiles
017NOLIST
018INCLUDE'derivative.inc'
019LIST
020
021;
022;Parameterdefinitions
023ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
024rom:SETROMStart;$2080
025initStack:EQU$1800
026COP_DisableEQU$42
027ROMTable:EQU$3000;Posicinarbitraria,encimadel
028;..programa;debajodelareaocupada
029;..(VERMapadeMemoria)
030
031;
032;Definicindevariables(ds:bytepordefecto)
033ORGram

63

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

034TPtr:DS.W1
035out:DS1;'DS'y'DS.B'sonsinnimos
036var:DS.B1;VerifiquecomparandoProject.abs.s19
037
038;===================================================================
039;BeginofCodeSection
040ABSENTRYMain;Exportsymbol(DEBUGGERentry)
041
042ORGrom;$2080:HCS08ROMStart(Flash)
043;
044;***ALWAYS***includethefollowing4instructions
045Main:lda#COP_Disable
046staSOPT1;SystemOptions1
047ldhx#initStack;InitSP
048txs;..
049
050;
051;EnableInterruptsforIRQ
052;
053BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
054;
055;..Clearanypossibleprevious,false,interruptsbySetting
056;..IRQACKbitinIRQSC(IRQStatusandControlregister)
057BSETIRQSC_IRQACK,IRQSC
058;
059BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
060;
061cli;CPUInterruptENABLE
062
063;
064loop:clrvar;DirectAddressingMode
065bsrrutina;RelativeAddressingMode
066braloop
067
068;====================================================================
069;Subrutinadeejemplo
070rutina:
071ldavar
072cbeqa#10,fin;Terminacuandollegaa10
073incvar
074brarutina
075fin:rts;COLOCARBREAKPOINTAQU(Debugger)
076
077;====================================================================
078;TransferALLtablecompleteto'out',witheachIRQactivation.
079;NOTE:Enunarutinadeinterrupciones**JAMS**useunregistrosin
080;..SALVARpreviamentesuvalorenelstack.Alfinalizar,debe
081;..RESTAURARsuvalordesdeelstack.
082IRQISR:
083pshh;SaveHreg;HardwaredoesNOTdothis
084ldhx#Table;Indexreg.pointsto'Table'start.
085;(Cuntovale'Table'?Y'#Table'?)

64

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

086loop2:movX+,out
087beqdone;ActivateBREAKPOINTheretosee...
088braloop2
089
090done:pulh
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti
094
095;====================================================================
096;Table
097ORGROMTable
098Table:DC.B'H'
099DC.B'O'
100DC.B'L'
101DC.B'A'
102DC.B0
104;********************************************************************
105;*InterruptVectors*
106;********************************************************************
107;(Estaparteesmsomenosestndar,
108;..exceptoquenormalmenteseincluyenTODOSlosperifricos...)
109spurious:
110rti
112ORGVirq;ChangeORG
113DC.WIRQISR;<<<IRQDefined
114DC.Wspurious;SWI
115DC.WMain;RESET
116
117END
118
119NOTE:IfinCW10.2,IRQdoesNOThaveanyeffectifyouare
120debugginginFullChipSimulation(FCS)andyouareusingstepby
121step(F5).YouneedtomakeabreakpointintheISRandthenRUNat
122fullspeed:F8.Now,IRQworks...
123
124GURIBE,M29E2013

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03c_L1_M.asm"]:
Elprogramacomienzadelamaneraordinaria.DefinalaROMTablearbitrariamenteenla
posicin$3000,quequedabienporencimadelreadeFlashutilizadaporelprograma:

027ROMTable:EQU$3000;Posicinarbitraria

DefineunAPUNTADORalatablaque,portanto,tienequetener16bits(DS.W:Define
StorageWORD):

032;Definicindevariables(ds:bytepordefecto)
033ORGram
034TPtr:DS.W1

65

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

HaceluegolahabilitacinqueyahemosrealizadoparaelIRQ,yelCLIparahabilitar
las interrupciones del CPU. La rutina de ejemplo es el mismo cdigo simple que
empleamosenelejercicioanterior.

LapartenovedosaconsisteentransferirTODAlatabla(queenelejemplocontienesolo
lasletrasHOLAyun'\0'queestamosusandocomoterminadordestrings,igualqueen
C),deunsologolpe,cadavezqueseinterrumpaelCPUmedianteelbotndeIRQ.

Laadvertenciamsimportantees:

079;NOTE:Enunarutinadeinterrupciones**JAMS**useunregistrosin
080;..SALVARpreviamentesuvalorenelstack.Alfinalizar,debe
081;..RESTAURARsuvalordesdeelstack.

AnalicemoslaIRQISR:

082IRQISR:
083pshh;SaveHreg;HardwaredoesNOTdothis
084ldhx#Table;Indexreg.pointsto'Table'start.
085;(Cuntovale'Table'?Y'#Table'?)

Lo primero es decir que el protocolo de atencin de interrupciones de este CPU,


almacenaloscincoregistros,conexcepcindelapartesuperiordelH:X(osea,elH).
AsqueesINDISPENSABLESALVARESEREGISTROPORPROGRAMA;deahelPSHH(PushH)

LuegosecolocaladireccindelatablaenelregistrondiceH:X
Acontinuacinvieneelcicloquemuevetodalatabla,letraporletra,alavariable
'out'(que,comoveremosluego,sinofueraunavariablesinoelregistrodesalidadel
perifricodecomunicaciones,enviaraelmensajealPC!)

086loop2:movX+,out
087beqdone;ActivateBREAKPOINTheretosee...
088braloop2

Parafinalizar,HAYQUERESTAURARPORPROGRAMALAPARTEALTADELREGISTRONDICEH:X(
o sea, H, que resguard en Stack al comienzo). Luego se culmina con el protocolo ya
conocido de Interrupt Acknowledge para este perifrico, y la rutina retorna de la
interrupcin.Sisevuelveaoprimirelbotn,vuelveatrasmitirselatabla:

090done:pulh
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti

Definicindelatabla:

096;Table
097ORGROMTable
098Table:DC.B'H'
099DC.B'O'
100DC.B'L'
101DC.B'A'

66

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

102DC.B0

...quetambinpuedeescribirsecomo:
Table:DC.B"HOLA",0

Lapartefinal,delosvectoresdeinterrupcin,eslamismaqueyahemosvisto.

12) Ejercicio con ms Aspectos Nuevos an:

Esteprogramaessimilaralanterior,peronoenvalatablacompletacadavezquese
oprimeelIRQ,sinoquemueveunaletraalavez,porcadainterrupcindeIRQ.

["Laboratorios\Lab1\Lab1_M\03d_L1_M.asm"]
001;********************************************************************
002;Programa03d_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
003;
004;NuevosAspectos:
005;
006;Usodeunavariable'pointer'(TPtr)paratransferirlatabla
008;
009;Includefiles
010NOLIST
011INCLUDE'derivative.inc'
012LIST
014;
015;Parameterdefinitions
016ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
017rom:SETROMStart;$2080
018initStack:EQU$1800
019COP_DisableEQU$42
020ROMTable:EQU$3000;Posicinarbitraria,encimadel
021;..programa;debajodelareaocupada
022;..(VERMapadeMemoria)
023
024;
025;Definicindevariables(ds:bytepordefecto)
026ORGram
027TPtr:DS.W1
028out:DS1;'DS'y'DS.B'sonsinnimos
029var:DS.B1;VerifiquecomparandoProject.abs.s19
030
031;===================================================================
032;BeginofCodeSection
033ABSENTRYMain;Exportsymbol(DEBUGGERentry)
034
035ORGrom;$2080:HCS08ROMStart(Flash)
036;
037;***ALWAYS***includethefollowing4instructions
038Main:lda#COP_Disable
039staSOPT1;SystemOptions1

67

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

040ldhx#initStack;InitSP
041txs;..
042;
043
044ldhx#Table;InitpointertoTable
045sthxTPtr;..
046
047;
048;EnableInterruptsforIRQ
049;
050BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
051;
052;..Clearanypossibleprevious,false,interruptsbySetting
053;..IRQACKbitinIRQSC(IRQStatusandControlregister)
054BSETIRQSC_IRQACK,IRQSC
055;
056BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
057;
058cli;CPUInterruptENABLE
059
060;
061loop:clrvar;DirectAddressingMode
062bsrrutina;RelativeAddressingMode
063braloop
064

065;====================================================================
066;Subrutinadeejemplo
067rutina:
068ldavar
069cbeqa#10,fin;Terminacuandollegaa10
070incvar
071brarutina
072fin:rts
073
074;====================================================================
075;TransferALLtableto'out',CHARBYCHARwitheachIRQactivation.
076;NOTE:Enunarutinadeinterrupciones**JAMS**useunregistrosin
077;..SALVARpreviamentesuvalorenelstack.Alfinalizar,debe
078;..RESTAURARsuvalordesdeelstack.
079IRQISR:
080pshh;SalvarH(elHardwarenolohace!)
081ldhxTPtr;CargarregistrondiceconPointer
082movX+,out;Mueveletra;apuntaalasiguiente
083beqresetPtr
084sthxTPtr;..Actualizaelpointerenmemoria
085bradone
086
087resetPtr:
088ldhx#Table;ReinicializaelpointerdeTable
089sthxTPtr;..
090done:pulh

68

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti;ActivateBREAKPOINTheretosee...
094
095;====================================================================
096;Table
097ORGROMTable
098Table:DC"HOLA",0;QUESEL'0'QUEAPARECEALFINAL?
099;(DCeslomismoqueDC.B)
100;********************************************************************
101;InterruptVectors
102;ALWAYSINCLUDEVERBATIMCOPY,EXCEPTOFORVECTORSYOUUSE...
103dummy_isr:;ThismustbeplacedinROMSpace
104rti
105
106orgVtpm3ovf;Increasingpriorityfrombottomup
107DC.Wdummy_isr;Vtpm3ovf:
108DC.Wdummy_isr;Vtpm3ch5:
109DC.Wdummy_isr;Vtpm3ch4:
110DC.Wdummy_isr;Vtpm3ch3:
111DC.Wdummy_isr;Vtpm3ch2:
112DC.Wdummy_isr;Vtpm3ch1:
113DC.Wdummy_isr;Vtpm3ch0:
114DC.Wdummy_isr;Vrtc:
115DC.Wdummy_isr;Vsci2tx:
116DC.Wdummy_isr;Vsci2rx:
117DC.Wdummy_isr;Vsci2err:
118DC.Wdummy_isr;Vacmpx:
119DC.Wdummy_isr;Vadc:
120DC.Wdummy_isr;Vkeyboard:
121DC.Wdummy_isr;Viicx:
122DC.Wdummy_isr;Vsci1tx:
123DC.Wdummy_isr;Vsci1rx:
124DC.Wdummy_isr;Vsci1err:
125DC.Wdummy_isr;Vspi1:
126DC.Wdummy_isr;Vspi2:
127DC.Wdummy_isr;Vtpm2ovf:
128DC.Wdummy_isr;Vtpm2ch2:
129DC.Wdummy_isr;Vtpm2ch1:
130DC.Wdummy_isr;Vtpm2ch0:
131DC.Wdummy_isr;Vtpm1ovf:
132DC.Wdummy_isr;Vtpm1ch2:
133DC.Wdummy_isr;Vtpm1ch1:
134DC.Wdummy_isr;Vtpm1ch0:
135DC.Wdummy_isr;Vlvd:
136DC.WIRQISR;Virq:
137DC.Wdummy_isr;Vswi:
138DC.WMain;Vreset:
139
140END

69

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\03d_L1_M.asm"]:
Usa una variable 'pointer' (TPtr) para transferir la tabla, letra por letra. En el
ejercicio11)tambinseuslavariable,perosetransferaTODAlatablaporcadaIRQ
interrupt.

LainicializacindeTPtrsehaceahoraenelprogramaprincipal(Main):

044ldhx#Table;InitpointertoTable
045sthxTPtr;..

LahabilitacindelasinterrupcionesparaelIRQquedaigual.La'rutina'yel'loop'
siguensiendolosmismosqueantes.

LaIRQISRcambiaunpoco,paratransferirletraporletra,notablaportabla:

079IRQISR:
080pshh;SalvarH(elHardwarenolohace!)
081ldhxTPtr;CargarregistrondiceconPointer

El Pointer TPtr fue inicializado en Main. Ahora, usando el modo de direccionamiento


indexadoconautoincremento:

semueveunaletra
082movX+,out;Mueveletra;apuntaalasiguiente

se aprovecha la propiedad de Conjunto de Instrucciones Enriquecido, que


fundamentalmentehacequemuchasinstruccionesrealicenmsfuncionesdelasqueindica
sunombre.Fundamentalmente,latransferenciadeinformacin,comoenlalnea
082: mov X+, out, aprovecha para realizar una comparacin TCITA con el operando
movido,loquepermitetomarunadecisinsiloqueacabadetransferirseesun'\0',
queeselsmboloqueestamosusandoparamarcarelfinaldelstring,comoenC:

083beqresetPtr

Sinosehaterminado,seguardaelnuevovalordePointer,quehasidoincrementado
paraapuntaralaprximaletraquedebetransferirse:

084sthxTPtr;..Actualizaelpointerenmemoria

yseterminalainterrupcin

085bradone

Si la instruccin 083 beq resetPtr, determina que ya se transfiri el NULL Byte, se


reinicializa el pointer para comenzar de nuevo la transferencia de la tabla, cuando
hayamsinterrupciones:

087resetPtr:
088ldhx#Table;ReinicializaelpointerdeTable
089sthxTPtr;..

70

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Lapartefinaleslamismahyaseterminadolatransmisinono.Serestauraelvalor
delregistroH,nosalvadoporelmecanismodeinterrupcionesyseejecutaelprotocolo
deAckparalainterrupcinylarutinaretornaalprogramaprincipal:

090done:pulh
091BSETIRQSC_IRQACK,IRQSC;AcnowledgeIRQInterrupt
092;..(rearmIRQInterrupts)
093rti;ActivateBREAKPOINTheretosee...

Latablatienelamismaestructuradeantes:
097ORGROMTable
098Table:DC"HOLA",0;QUESEL'0'QUEAPARECEALFINAL?
099;(DCeslomismoqueDC.B)

Comoejemplo,seincluyenTODOSlosvectoresdeinterrupcin,conlosnombresdefinidos
porelmanufacturante.Nolarepitoaquparaconservarelespacio.

13) Aspectos Cosmticos en el trato de los Vectores de Interrupcin:

Latablacontodoslosvaloresdelosvectoresdeinterrupcin,queseincluyenel
ejercicio anterior, se acomoda dentro de un INCLUDE FILE que se invoca al final del
problema.Elejercicioesmuysimpleynodesarrollaningncdigoespecial.

["Laboratorios\Lab1\Lab1_M\04b_L1_M.asm"]
01;********************************************************************
02;Programa04b_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03;
04;NuevosAspectos:
06;SeempleaunIncludeFile:'InitU_M.inc'(ALLInterruptVectors)
07
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;Parameterdefinitions
15
16ram:SETZ_RAMStart;$80
17rom:SETROMStart;$2080
18initStack:EQU$1800
19COP_Disable:EQU$42
20ROMTable:EQU$3000;Posicinarbitraria,encimadel
21;..programa;debajodelareaocupada
22;..(VERMapadeMemoria)
23;
24;Definicindevariables(ds:bytepordefecto)
25
26ORGram
27
28TPtr:DS.W1

71

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

29out:DS.B1
30var:DS.B1
31
32;===================================================================
33;BeginofCodeSection
34ABSENTRYMain;Exportsymbol(DEBUGGERentry)
35
36ORGrom;$2080:HCS08ROMStart(Flash)
37
38;
39;***ALWAYS***includethefollowing4instructions
40Main:lda#COP_Disable
41staSOPT1;SystemOptions1
42ldhx#initStack;InitSP
43txs;..
44
45;
46;Branchforever
47
48bra*
49
50;
51;InitU
52NOLIST
53INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
54LIST
55
56END

14) Ejemplo: Rutina de MULTIPLICAR, por Sumas Sucesivas:

El HCS08 TIENE una instruccin de multiplicar..., as que no se precisara hacer la


operacinmediantesumas.Essolounejemplo:

["Laboratorios\Lab1\Lab1_M\05a_L1_M.asm"]
01;********************************************************************
02;Programa05a_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03;LuisG.UribeC.,D12A2009
04;
05;EJEMPLO:RutinadeMULTIPLICAR,porsumassucesivas
07;NOTE:ElHCS08TIENEunainstruccindemultiplicar...
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;Parameterdefinitions
15ram:SETZ_RAMStart;$80
16rom:SETROMStart;$2080

72

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

17initStack:EQU$1800
18COP_Disable:EQU$42
19;
20;Definicindevariables(DS:DefineStorageBYTE,pordefecto)
21ORGram
22m_ando:DS.B1;Multiplicando
23m_ador:DS1;Multiplicador
24prod:DS.B1;Producto(RESULTADO)
25cnt:DS1;Contador
26;===================================================================
27;BeginofCodeSection
28ABSENTRYMain;Exportsymbol(DEBUGGERentry)
29ORGrom;$2080:HCS08ROMStart(Flash)
31;
32;***ALWAYS***includethefollowing4instructions
33Main:lda#COP_Disable
34staSOPT1;SystemOptions1
35ldhx#initStack;InitSP
36txs;..
37;
38;Inicializacindeparmetros
39mov#5,m_ando;Main:Etiquetadelprogramappal.
40mov#3,m_ador;Pasarparmetrosalarutina
41;
42;RutinadeMultiplicacinporsumassucesivas
43clrprod
44clrcnt
45mply:ldam_ador
46cbeqcnt,fin
47ldaprod
48addm_ando
49staprod
50inccnt
51bramply
52
53fin:bra*;SimulaunHALT
54;
55nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
56;This'nop'MAYberemovedforCW6.3...
57
58;
59;InitU
60;NOLIST
61INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
62;LIST
63
64END

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05a_L1_M.asm"]:
LaspartesnuevascomienzanconlaInicializacindeparmetros.Semultiplicarn,como
ejemplo,5*3(constantes):

73

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

39mov#5,m_ando;Main:Etiquetadelprogramappal.
40mov#3,m_ador;Pasarparmetrosalarutina

LaRutina(queanNOSubrutina)deMultiplicacinporsumassucesivasescomosigue:

43clrprod
44clrcnt
45mply:ldam_ador
46cbeqcnt,fin
47ldaprod
48addm_ando
49staprod
50inccnt
51bramply
53fin:bra*;SimulaunHALT
54;
55nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
56;This'nop'MAYberemovedforCW6.3...

El ejercicio termina con en la lnea 53 fin: bra *, que simula un HALT, para
permitirnosmirarelresultadoconelDebugger.

15) "SUBRUTINA" de MULTIPLICAR, por sumas sucesivas:

Es un ejemplo muy parecido al anterior, pero el cdigo se ha colocado dentro de una


SUBRUTINA que el programa principal llama. Esta es la forma ms corriente de
codificacin.

["Laboratorios\Lab1\Lab1_M\05b_L1_M.asm"]
01;********************************************************************
02;Programa05b_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
03
04;EJEMPLO:RutinadeMULTIPLICAR,porsumassucesivas
06;NuevosAspectos:
07;
08;IncluyeunaSubrutina
09;
10;Includefiles
11NOLIST
12INCLUDE'derivative.inc'
13LIST
14;
15;Parameterdefinitions
16ram:SETZ_RAMStart;$80
17rom:SETROMStart;$2080
18initStack:EQU$1800
19COP_Disable:EQU$42
20;
21;Definicindevariables(DS:DefineStorageBYTE,pordefecto)
22ORGram
24m_ando:DS.B1;Multiplicando

74

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

25m_ador:DS1;Multiplicador
26prod:DS.B1;Producto(RESULTADO)
27;===================================================================
28;BeginofCodeSection
29ABSENTRYMain;Exportsymbol(DEBUGGERentry)
30ORGrom;$2080:HCS08ROMStart(Flash)
31;
32;***ALWAYS***includethefollowing4instructions
33Main:lda#COP_Disable
34staSOPT1;SystemOptions1
35ldhx#initStack;InitSP
36txs;..
37;
38;Inicializacindeparmetros
39mov#5,m_ando;Main:Etiquetadelprogramappal.
40mov#3,m_ador;Pasarparmetrosalarutina
41
42bsrmply;BranchtoSubroutinemply
43final:brafinal;Halt
44
45;===================================================================
46;RutinadeMultiplicacinporsumassucesivas
47mply:clrprod
48ldam_ador;RICHInstructionSet:Loadandmake
49;..tacit&automaticCOMPAREwith'0'
50beqfin
51;
52;Loop
53mply2:ldaprod
54addm_ando
55staprod
56decm_ador
57beqfin
58bramply2
59fin:rts
60;
61nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
62;This'nop'MAYberemovedforCW6.3...
63
64;
65;InitU
66NOLIST
67INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
68LIST
70END

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05b_L1_M.asm"]:
Lasnovedadescomienzanaqu:

42bsrmply;BranchtoSubroutinemply
43final:brafinal;Halt

75

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

SetrasladelcdigodelprogramaprincipalalaSUBRUTINAMPLY:

47mply:clrprod
48ldam_ador;RICHInstructionSet:Loadandmake
49;..tacit&automaticCOMPAREwith'0'
50beqfin
52;Loop
53mply2:ldaprod
54addm_ando
55staprod
56decm_ador
57beqfin
58bramply2
59fin:rts

16) Ejemplo PRIMORDIAL del uso de Variables Dinmicas:


Las variables dinmicas, en C, son aquellas que no existen antes de llamarse la
subrutinaendondesevanautilizar;segenerancomopartedelmecanismodellamadaa
la funcin(Stack FRAME), duran hasta que la subrutinatermine, ydesaparecen con la
finalizacindelafuncin,liberandoelespacioutilizado.

Estemecanismotienedosaspectosimportantes:

Primero, emplea de una manera muy eficienteel espacio, segn acabo de explicar. Las
variables estticas o globales, conservan el espacio desde su asignacin hasta la
terminacindelprograma.Nuncaloliberanhastaentonces.
Segundo, permiten la codificacin de FUNCIONES RECURSIVAS, al estilo de FACTORIAL, o
lasTORRESDEHANOIysimilares.

EsMUYimportanteentenderypoderaplicarlastcnicasqueaquexpongo.

El ejemplo que usaremos como vehculo para aplicar y demostrar la forma de definir
variables dinmicas ser otra vez el Ejemplo de EXPONENCIACIN, por multiplicaciones
sucesivasqueasuvezsehacenporsumassucesivas...PeroTODASlasvariablesestarn
enelStack.

Esimportante,parasucomprensin,quesehagapasoapasoundibujodelStackyel
valor del SP, a medida que se ejecuta el programa. Puede ayudarse con el Debugger,
siguiendoelprogramapasoapasoymonitoreandoelSPyelreaasignadaalStack.

["Laboratorios\Lab1\Lab1_M\05d_L1_M.asm"]
001;********************************************************************
002;Programa05d_L1_M.asm,HCS08_CPU,LuisG.UribeC.,M29E2013
003
004;EJEMPLO:EXPONENCIACIN,pormultiplicacionessucesivas;
005;..queasuvezsehacenporsumassucesivas...
006;
007;NuevosAspectos:
008;
009;**USASOLOELSTACK;NOVARIABLESLOCALES**
010;

76

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

011;Includefiles
012NOLIST
013INCLUDE'derivative.inc'
014LIST
016;
017;Parameterdefinitions
018mantisa:EQU2;Resultado:2^5=32(0x20enelACC)
019exponente:EQU5;Cambieaqusisedesamsvalores
020;
021ram:SETZ_RAMStart;$80
022rom:SETROMStart;$2080
023initStack:EQU$1800
024COP_Disable:EQU$42
025
026STD:EQU4;PosicinSTandarDdela1avariable
027
028;===================================================================
029;DEFINICIONDEVARIABLESLOCALES:
031;Enlugardelasvariables(globales),seespecificael"Offset"
032;..quecadaunatendrenelStack(Frame)almomentodellamara
033;..unasubrutina.Deestamanera,talcomohaceelIJVM,cada
034;..subrutinaofuncinpuededireccionar"simblicamente"sus
035;..variableslocales,ydeidnticaforma,susparmetros.Seemplea
036;..paraello,demaneraextensiva,eldireccionamientoindexado.
037;
038;ObservequeestedireccionamientopuedehacerseenrelacinalSP,
039;..peroresultapreferibleenfuncindelH:X,yaqueelSPva
040;..movindosecadavezquesehaceunPUSH,unllamadodesubrutina,
041;..yestocomplicaelseguimientodelaposicindecadavariable.
042;
043;Losnmeros,talescomo:"resultEQUSTD",indicanacuntosbytes
044;..seencuentralavariableequivalente.As,"result"estsituada
045;..4bytesporencimadeX,alllamarlasubrutina'exp'
046;
047;Hganseungrficoquesealelaposicindec/variableenelstack
048;..Esoayudabastantealacomprensindeestecdigo
049;
050;==========================
051;subrutina'exp'(exponenciar)
052;
053;
054;(1)VariablesLOCALES(EnelSTACK):
055
056result:EQUSTD;nicavariable"local"de'exp'
057;Otrasvariablessedefiniranaqu.Porejemplo:
058;var2:EQUresult+1;1eseltamaoenbytesde'result'
059;var3:EQUvar2+1;1eseltamaoenbytesde'var2',etc.
060
061EXP_Vars:EQUresultSTD+1;Cantidaddevariableslocalesen'exp'
062;Laexpresines:PRIMERA_variableSTD+1
063;(*)NOTA:
064;Sifuera'result'laquemidiera2bytes,var2sera:

77

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

065;var2:EQUresult+2;etc.
066
067;
068;(2)PARMETROS(ENELSTACK,enrdenINVERSOacomoseapilan.
069;..Sisehace*PushBASE*yluego*PushEXP*,elordeneselquese
070;..indicaacontinuacin;primeroEXPyluegoBASE):
071
072exp:EQUresult+1;segundoparmetro
073base:EQUexp+1;PRIMERparmetro.Aplica(*)NOTAarriba
074
075EXP_Stack:EQUbaseSTD+1;usodelstack(vars+param)
076;LaexpresinesLTIMO_parmetroSTD+1
077
078;==========================
079;subrutina'mply'
080;(1)VARIABLESLOCALES(EnelSTACK):
081
082prod:EQUSTD;nicavariable"local"de'mply'
083
084MUL_Vars:EQUprodSTD+1;Cantidaddevariableslocalesen'mply'
085
086;
087;(2)PARMETROS(ENELSTACK):
088
089m_ador:EQUprod+1;segundoparmetro
090m_ando:EQUm_ador+1;primerparmetro
091
092MUL_Stack:EQUm_andoSTD+1;usodelstack(vars+param)
093
094;===================================================================
095;BeginofCodeSection
096ABSENTRYMain;Exportsymbol(DEBUGGERentry)
097
098ORGrom;$2080:HCS08ROMStart(Flash)
099
100;
101;***ALWAYS***includethefollowing4instructions
102Main:lda#COP_Disable
103staSOPT1;SystemOptions1
104ldhx#initStack;InitSP
105txs;..
106
107;
108;InitU
109;NOLIST
110INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'
111;LIST
112
113;============================================================
114;Pasaparmetrosalarutina"expo"
115lda#mantisa;base
116psha

78

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

118lda#exponente;exp(2^5=32:0x20)
119psha
120
121ais#EXP_Vars;reservaVARIABLESlocalesen"expo"
122bsrexpo;JSRexpo.ResuladoenACC
123ais#EXP_Stack;recuperastack***ResuladoenACC***
124
125;
126bra*;SimulaunHALT.2^5=32:$20(seeACC)
127
128;===================================================================
129;RutinadeExponenciacinpormultiplicacionessucesivas
130expo:pshx;guardastackframeanterior
131pshh
132;
133tsx;MarkVariableFrameinstackwithH:X
134
135lda#1
136staresult,x
137
138ldaexp,x
139beqex_fin
140;
141;Pasarparmetrosalarutina"mply"
142expo2:ldaresult,x;pasaparmetrosalarutina"mply":
143psha;..m_ando
144
145ldabase,x;m_ador
146psha
147;
148ais#MUL_Vars;reservaareaparaVARIABLESlocales
149bsrmply;***ResuladoenACC
150ais#MUL_Stack;recuperastack
151;
152staresult,x
153ldaexp,x
154deca
155staexp,x
156beqex_fin
157braexpo2
158ex_fin:
159ldaresult,x;ResultinACC
160pulh;recuperastackframeanterior
161pulx
162rts
163;
164;RutinadeMultiplicacinporsumassucesivas
165mply:pshx;guardastackframeanterior
166pshh
167;
168tsx;MarkVariableFrameinstackwithHX
169clra

79

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

170staprod,x
171ldam_ador,x
172beqs_fin
173;
174;Loop
175mply2:ldaprod,x
176addm_ando,x
177staprod,x
178ldam_ador,x
179deca
180stam_ador,x
181beqs_fin
182bramply2
183s_fin:ldaprod,x;ResultinACC
184pulh;recuperastackframeanterior
185pulx
186rts
187
188END

COMENTARIOS a ["Laboratorios\Lab1\Lab1_M\05d_L1_M.asm"]:
La primera modificacin al ejercicio que ya hemos presentado con anterioridad, es la
definicin de los valores que van a multiplicarse. Hasta ahora se usaron como
constantesnumricas:#3y#5.Aquselesdaunaidentificacinsimblica:

017;Parameterdefinitions
018mantisa:EQU2;Resultado:2^5=32(0x20enelACC)
019exponente:EQU5;Cambieaqusisedesamsvalores

Yluegovieneladiferenciafundamental:DEFINICIONDEVARIABLESLOCALES:

En lugar de las variables (globales) con las que se trabaj en los ejercicios
anteriores,seespecificaaquel"Offset"quecadaunatendrenelStack(Frame)al
momento de llamar a una subrutina. De esta manera, cada subrutina o funcin puede
direccionar "simblicamente" sus variables locales, y de idntica forma, sus
parmetros.Seempleaparaello,demaneraextensiva,eldireccionamientoindexado.

Elhechodequevariablesyparmetrosdeunafuncin,puedanmanipularseDELAMISMA
MANERA (en este caso, ambos con NOMBRES), fue una de las cosas importantes de los
lenguajesdealtonivel,comoelC.Cuandohacemosalgoascomo:

intexample(inta,intb)
{inttmp;
tmp=a*b;//mirandoestalnenopuedediferenciarseentrelos
//..parmetrosaybylavariablelocaltmp.Esel
...//..mismotratamientoparavariablesyparmetros!
}

Este direccionamientode variables en el Stack puede hacerse en relacin alSP, pero


resultapreferibleenfuncindelregistrondiceH:X,yaqueelSPvamovindosecada
vezquesehaceunPUSH,ounllamadodesubrutina,yestocomplicaelseguimientode

80

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

la posicin de cada variable. En cambio, una vez marcado el STACK FRAME, con el
registro ndice, el H:X queda esttico y los desplazamientos en consecuencia no se
mueven.

Enelejercicio,losnmeroscomoeldelalnea056:
056result:EQUSTD;nicavariable"local"de'exp'

indicanacuntosbytesseencuentralavariableequivalentedentrodelStack(odentro
delSTACKFRAME,queeselreamarcadaporelregistrondiceH:X).As,"result"est
situada4bytesporencimadeH:X,alllamaryejecutarlasubrutina'exp'.Recuerde
queSTDhasidodefinidocomo:

026STD:EQU4;PosicinSTandarDdela1avariable

Haga un grfico que seale la posicin de c/variable y cada parmetro en el stack,


siguiendo el orden de los push de los parmetros, la reserva del rea de trabajo en
stack, las posiciones que se lleva guardar el PC, segn el protocolo de llamada a
subrutinasy,finalmente,elespacioqueserequiereparasalvarelvaloranteriordel
registrondice:H:X;esoayudabastantealacomprensindeestecdigo.

Ladefinicindevariablesyparmetrosparalaprimerasubrutina,'exp'(exponenciar)
escomosigue:

051;subrutina'exp'(exponenciar)
054;(1)VariablesLOCALES(EnelSTACK):
056result:EQUSTD;nicavariable"local"de'exp'

Sihubieramsvariablessedefiniranaquas:

058;var2:EQUresult+1;1estamaode'result'
059;var3:EQUvar2+1;1estamaode'var2',etc.

Sehaasumidoquevar2yvar3tendranuntamaodeunbyte.Silasvariablesfueran
WORDS,de2bytes,lasdefinicionesseranas:

058;var2:EQUresult+1;1estamaode'result'
059;var3:EQUvar2+2;2estamaode'var2'

MedicindelespaciodeStackocupadoporlasubrutina'exp':

061EXP_Vars:EQUresultSTD+1;CantidaddeVARIABLESlocalesen'exp'
062;Laexpresines:PRIMERA_variableSTD+1

AcontinuacinsedefinenlosPARMETROS(escostumbreponerlosenelStack,enorden
INVERSO a como se apilan. As se hace en C, de tal manera que una expresin como
printf( "%d", i ); introduce 'i' en el Stack y luego el FORMAT: %d. De esta manera,
como el nmero de parmetros de printf es VARIABLE, se puede averiguar con cuntos
parmetrosselallam,inspeccionandoelStringdeFORMAT,queconvenientementeesel
queesteneltechodelStack(apuntadodirectamenteporelSP1.RecuerdequeelSP
en esta mquina se dise para que apuntara a la prxima posicin VACA dentro del
Stack,adiferenciadetodaslasdemsmquinasdelorbe...)

81

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

RecuerdequeSTDhasidodefinidocomo:

026STD:EQU4;PosicinSTandarDdela1avariable

Repitoporclaridadlalnea56:

056result:EQUSTD;nicavariable"local"de'exp'
060
061EXP_Vars:EQUresultSTD+1;Cantidaddevariableslocalesen'exp'
062;Laexpresines:PRIMERA_variableSTD+1

067;
068;(2)PARMETROS(ENELSTACK,enrdenINVERSOacomoseapilan.
069;..Sisehace*PushBASE*yluego*PushEXP*,elordeneselquese
070;..indicaacontinuacin;primeroEXPyluegoBASE):
072exp:EQUresult+1;segundoparmetro.
073base:EQUexp+1;PRIMERparmetro.Aplica(*)NOTAarriba
075EXP_Stack:EQUbaseSTD+1;usodelstack(vars+param)

Elsegundosmboloauxiliarparalaliberacindeespacioenestasubrutinaes:

075EXP_Stack:EQUbaseSTD+1;usodelstack(vars+param)

Enlaexpresindelalnea072:
072exp:EQUresult+1;

'result'eslaLTIMAVARIABLEdelmtodo,ANTESdelosparmetros.(Aqu,ademsde
serlaltima,tambineslanica...)

Paralasubrutina'mply'sesigueelmismoprocedimiento:

079;subrutina'mply'
080;(1)VARIABLESLOCALES(EnelSTACK):
082prod:EQUSTD;nicavariable"local"de'mply'
084MUL_Vars:EQUprodSTD+1;Cantidaddevariableslocalesen'mply'

Lalnea084mideelnmerodevariableslocalesenestasubrutina,

084MUL_Vars:EQUprodSTD+1

Luegosedefinenlosparmetros,similarmenteacomosehizoenlasubrutinaanterior:

087;(2)PARMETROS(ENELSTACK):
089m_ador:EQUprod+1;segundoparmetro
090m_ando:EQUm_ador+1;primerparmetro
092MUL_Stack:EQUm_andoSTD+1;usodelstack(vars+param)

Estevalordelalnea092mideelUSOdelstackparaestasubrutina:
092MUL_Stack:EQUm_andoSTD+1;usodelstack(vars+param)

Note:LosvectoresdeInterrupcinestndefinidosparaarrancarenMain,enelINCLUDE
file:'InitU_M.inc',en:

82

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

110INCLUDE'InitU_M.inc';InterruptVectors;Restartin'Main'

Observemos cmo se pasan los parmetros a 'expo', y cmo se reservan las variables
locales:

113;============================================================
114;Pasaparmetrosalarutina"expo"
115lda#mantisa;base
116psha
117
118lda#exponente;exp(2^5=32:0x20)
119psha

Aestasalturas,sehanacomodadolosdosparmetrosenelStack.Ahorasereservael
espacioparalasvariableslocales,decrementandoelSPporlacantidaddefinidaarriba
comolacantidaddebytesdelasvariableslocales:

121ais#EXP_Vars;reservaVARIABLESlocalesen"expo"

Luegosesaltaalasubrutina,locualalejanuestrareadealmacenamiento,DOS(2)
bytesdelSP(porqueelsaltoasubrutinaimplicaguardarelPCderetornoenelStack,
yelPCmide2bytes)

122bsrexpo;JSRexpo.ResuladoenACC

Alretornar,deunasolaoperacinserecuperatodoelStack,tantoelcorrespondiente
alosparmetroscomoelocupadoporlasvariables:

123ais#EXP_Stack;recuperastack***ResuladoenACC***

Ahoraanalicemoslaprimerasubrutina,'expo'.LoprimeroquehaceesguardarelStack
Frame Anterior, que se encuentramarcado por el registro ndice: H:X. La cantidad de
bytes que ocupa el registro ndice guardado en el Stack (2 bytes) nos aleja justo 2
posicionesmsdenuestrosdatos,PARAUNTOTALDECUATRO(4)queeselvalordefinido
arribaparaelsmbolo'STD'.

130expo:pshx;guardastackframeanterior
131pshh

AhoraprocedeagenerarunNUEVOSTACKFRAME:

132;
133tsx;MarkVariableFrameinstackwithH:X

Deahenadelantelasecuenciadeoperacionesesbastantelegible:

135lda#1
136staresult,x;definidoen056result:EQUSTD
138ldaexp,x;definidoen072exp:EQUresult+1
139beqex_fin

83

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Recuerdenqueelmododedireccionamientoindexadocondesplazamientode8bits,suma
elregistrondiceH:Xconeldesplazamientoparaobtenerlaposicindelavariable,
por encima de los 4 bytes (STD) que estn ocupando el PC y el antiguo H:X. Recuerde
tambin que cada push DECREMENTA el SP. Por eso para reservar el espacio de las
variables,selesumaSPunnmeronegativo(repitolalnea121):

121ais#EXP_Vars;reservaVARIABLESlocalesen"expo"

Elcomportamientodelasiguientesubrutina,"mply",estansimilaralanterior,queno
voyacomentarmssobrel.

PROGRAMAS AVANZADOS EN ASSEMBLY


LANGUAGE, PARTE II

A continuacin voy a presentar un ejemplo clsico de la literatura computacional, en


donde se muestra el podero de la PROGRAMACIN RECURSIVA a la solucin de aquellos
problemas que pueden expresarse de esa manera, como son el clculo de factoriales,
bsquedadePalndromos,exploracinderbolesdeinformacin(comolosdirectoriosde
unsistemadearchivos),lageneracindecombinacionesypermutacionesentreelementos
(noelclculodecuntasson,sinoculesson),elclculodelMximoComnDivisor,
segnelalgoritmodeEuclides,pormencionaralgunosdelosmsconocidos.

EnprimerlugarmostrarelejemploenC,paraWindows(compilarconVisualStudio10+)
y luego en Assembly Language para el HCS08. Cuando veamos todos estos programas
reescritosenCparaelHC9S08QE128,volveremosaverlo.

El ejercicio de las Torres de Hanoi supone 3 torres, en las que se han colocado N
discos, comenzando por el ms grande abajo, y colocando encima discos cada vez ms
pequeos. El ejercicio requiere pasar todos los discos de la torre 1 a la torre 3,
empleandolatorre2comoauxiliar.Lanicareglaesquenosepuedecolocarnuncaun
discograndesobreunomspequeo.

La solucin es muy simple: pasar N1 discos de la torre 1 a la 2; pasar EL disco


restantedelatorre1ala3,yfinalmentepasarlosN1queestnenlatorre2,ala
3.LISTO.Desdeluego,parapasarN1discosdeunatorreaotra,sepasanN2alaque
sirvaahoradetorreauxiliar,empleandoelMISMOprocedimiento...demanerarecursiva.
Esdecir,cuandoslohayaUNdisco,habrquepasarlodesdelafuentehastaeldestino
final.Encasocontrario,llamarelprocedimientodemanerarecursiva.

17) Torres de Hanoi, MNIMO, en C:


A)ProgramaHanoiMin.c

["Temarios\Ex#1HanoiMin\HanoiMin.c"]
01#include"hanoimin_.h"//hanoimin.cLGUribeCL12D2011J12D2013
02voidmain(intargc,char**argv)/*HANOImin.C*//*()*/
03{uintN;
04get(NDisks);

84

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

05hanoi(N,1,3);//MOVENdisksfromtower1to3.
06}/*main()*///..That'sall!

07//==================================================================
08voidhanoi(uintN,uinta,uintb)/*()*/
09{
10if(N==1)//GOTONLY1DISK?IT'SEASY!JUSTMOVEITON
11PrintW("Paseeldiscodelatorre'%d'ala'%d'",a,b);
12hanoi(N1,a,TowerTmp);//SEVERALDISKS?CALLITSELFRECURSIVELY:
13hanoi(1,a,b);
14hanoi(N1,TowerTmp,b);
15}/*hanoi()*/

B)IncludeFilehanoiMin_.h:

["Temarios\Ex#1HanoiMin\hanoiMin_.h"]
//HANOImin_h.h,LuisG.UribeC.:Playwithpaperdisks!
//S12N2005J23M2006L29G2011J12D2013
16#include<assert.h>
17#include<stdio.h>
18#include<stdlib.h>

19enum{DEFAULT=3,MAX=10};
20typedefunsignedintuint;

21voidhanoi(uintn,uinta,uintb);

22#defineget(NDisks){if(argc<2)N=DEFAULT;\
23elseif((N=atoi(argv[1]))==0)N=DEFAULT;\
24if(N>MAX){\
25puts("#Discosdebeser<=10.Asume3\n");\
26N=DEFAULT;}}

27//Printfmessage,andWaittheusertohitENTER,tocontinue
28#definePrintW(s,a,b){printf(s,a,b);getchar();return;}

29//MagicNumber!ie:fora=1&b=3,=>TowerTmp=2ETC!Sleeponit...
30#defineTowerTmp(6ab)

COMENTARIOS a ["Temarios\Ex#1-HanoiMin\HanoiMin--.c"]:
Desdeluego,meesforcenpresentarunalgoritmoMNIMO.Difcilmentepuedencolocarse
menosinstrucciones.

De'main'podemosolvidarnos:NOformapartedelalgoritmo;sirveparaleerdelusuario
el nmero de discos, N, y llamar a la respectiva funcin 'hanoi()', que es la que
realmente materializael algoritmo: Mover N discos desde la torre 'a' hasta la torre
'b':

08voidhanoi(uintN,uinta,uintb)/*()*/
10if(N==1)//GOTONLY1DISK?IT'SEASY!JUSTMOVEITON
11PrintW("Paseeldiscodelatorre'%d'ala'%d'",a,b);

85

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Como ya dijimos, si en un momento dado hay que mover UN disco (N==1), se lo pasa
simplementedelatorreFUENTE(SRC)allatorreDESTINO(DST).Esaparteesfcil:'a'
y'b'SONlastorresSRCyDST.

Ahora, si hay ms de un disco para mover entre la torre 'a' y la torre 'b', pues
tambinesmuysencillo,comoseexpresaacontinuacin:

12hanoi(N1,a,TowerTmp);//SEVERALDISKS?CALLITSELFRECURSIVELY:
13hanoi(1,a,b);
14hanoi(N1,TowerTmp,b);

...mover N 1, de la torre 'a' a la 'TowerTmp', mover el disco que queda slo (1


disco),obviamentedelatorreSRC,'a',alaDST,'b'y,finalmentemoverlasN1
quetenamosenlatemporal,desdeesa'TowerTmp'hastala'b'.

LISTO.ESOESTODO.Juguenlocon12cartas(4095movimientos)yvernqueinventarse
unalgoritmoNORECURSIVO,noesnadasencillo...

B)IncludeFile

En este archivo se han colocado las cosas accesorias, que no forman parte del
algoritmo.Lonicoresaltantees:

//HANOImin_h.h,LuisG.UribeC.:Playwithpaperdisks!J12D2013
29//MagicNumber!ie:fora=1&b=3,=>TowerTmp=2ETC!Sleeponit...
30#defineTowerTmp(6ab)

ElMagicNumber,segnseseala,seobtienedeunafrmulasencillaquenospermite
saber:

Sivamosdelatorre1ala3,latemporalserla2.
Parairdela1ala2,latemporalserla3.
Y,dela2ala3,latemporalserla1.

EsafrmulaproduceelnmerodelatorreTEMPORAL,dadoslosotrosdosnmeros:SRCy
DST.

18) Torres de Hanoi, MNIMO, en ASSEMBLY LANGUAGE:

Es un tema recursivo de mi tratamiento acerca de este curso, la separacin que debe


hacerse entre POLTICA y MECANISMOS. Las POLTICAS definen LO QUE HAY QUEHACER, sin
hacernfasisenelCMO,quesonprecisamentelosMECANISMOS.

Cuando veamos los Timers, las rutinas de comunicaciones, este ejercicio... siempre
resaltoladefinicindelasPOLTICASy,aparte,laimplementacindelosmismos:los
MECANISMOS.

Otrofactorimportantequedebetenerseencuentaeseldiseo:TOPDOWN,esdecir,las
funcionalidadesdebenincluirsedesdeelnivelmsaltodelSISTEMA,eirbajandohasta
llegar a definir lo ms elemental que se requiere. Y luego, probablemente la

86

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

IMPLEMENTACIN se realice de abajo hacia arriba: BUTTOMUP, codificando primero las


cosas ms sencillas, o elementales, que quedaron colocadas en la base jerrquica del
diseo, y luego se va subiendo con los mdulos ms complejos, hasta llegar a los
nivelessuperiores.

A) Programa HanoiMin--.asm:

["Temarios\Ex#1HanoiMin\HanoiMin.asm"]
001;hanoimin.asm,LuisG.UribeC.HanoiMinimumV27D2013
002;
003;Includefiles;Parameterdefinitions
004NOLIST
005INCLUDE'derivative.inc'
006INCLUDE'hanoimin_.inc'
007LIST
008;;<<<<<<Changehere'ND',NumberofDisks
009NDEQU3;TODO:Get"ND"frompushbuttons,orfromPC,viaSCI
010;====================================================================
011;GLOBALVariables
012ORGram
013tmpAcc:DS1;helpertocalculateMagicNumber
014;********************************************************************
015;MAINPROGRAMHEADER:
016ABSENTRYMain;Export'Main'symbol
017ORGrom
018Main:InitSys

019HanoiM#ND,#1,#3;MOVENDdisksfromtower1>3THAT'SIT!

020BRA*;Simulate"C"EXITfromMain.
021;====================================================================
022;byteHanoi_(byteN,byteTa,byteTb)//NfromTower_atoTb/*()*/
023Hanoi_:;CalledfromHanoiM(Main),andHanoi(below)recursively
024CreateNewStackFrame
025;
026ldaN,X;Acc="N",numberofdiscs(NisND
027cmp#1;..pushedbyHanoiMabove)
028bneSeveral;..if(N!=1)gotoSeveral
029;
030OnlyOne:;Only1disktomovefroma>b?MOVEIT,showtheANSWER:
031MoveOneFromSrcToDst;Acc=00Ta_00Tb
032brafin;<<<BreakheretoseeRESULTSinAcc
033;ND=3Seq:1_31_23_21_32_12_31_3
034;TODO:DisplayACCinLEDsorshowitsomehowinthePC(SCI)
035;
036Several:;GotSeveraldisks?Callitselfrecursively!
037EvalTowerTmpSrc,Dst;Acc=Temp.Towernumber:6ab
038staTowerTmp,X;..TowerTmp=6ab

039ldaN,X;n_1=n1
040deca;..

87

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

041stan_1,X;..
042;
043Hanoin_1,Src,TowerTmp
044HanoiK#1,Src,Dst
045Hanoin_1,TowerTmp,Dst
046;
047fin:RestoreOldStackFrame
048RTS
049;
050nop;<<<NEEDEDbyCodeWarrior10.15(not6.3).INCREDIBLE<<<
051;This'nop'MAYberemovedforCW6.3...
052;
053;InterruptVectors
054ORGVreset
055DC.WMain;RESET.Maximumpriority.Asynch.
056END

B) Include File HanoiMin_.inc:

["Temarios\Ex#1HanoiMin\HanoiMin_.inc"]
057;HANOImin_.inc,LuisG.UribeC.:V27D2013M27Y2014
058rom:SETROMStart;$2080
059ram:SETRAMStart;PutTHISinMainprogram
060initStack:EQU$1800
061COP_Disable:EQU%01000010;$42
062STDEQU4;1stvariablepositioninStack
063;
064;Macros
065InitSysMACRO
066lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
067staSOPT1;..SystemOptions1
068ldhx#initStack;SetupSP(andH:XforStacFrame)
069txs;...
070ENDM
071;
072CreateNewStackFrameMACRO
073pshx;SavepreviousStackFrame,orderX,H
074pshh
075tsx;useH:XtopointtoStackFrame
076ENDM
077;
078RestoreOldStackFrameMACRO;intoHX.Order:H,X
079pulh;*RECOVER*oldStackFrame
080pulx
081ENDM
082;
083EvalTowerTmpMACROA,B;"ACC=6AB":MAGICNUMBER,i.e,for
084lda\1,X;tmpAcc=A
085statmpAcc;..
086lda\2,X;Acc=B
087addtmpAcc;Acc=B+A

88

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

088sub#6;Acc=B+A6
089nega;Acc=6AB
090ENDM
091;
092PushMACROPushValue;i.e:Push#3(Acc<=#3;pushAcc)
093lda\1
094psha
095ENDM
096;
097PopMACROVar;i.e:Popvar:popAcc;var<=Acc
098pula
099sta\1
100ENDM
101;
102PushHMACROPushValue;i.e:Pushdst(Acc<=dst;pushAcc)
103lda\1,X
104psha
105ENDM
106;
107PopHMACROVar;i.e:Popvar:popAcc;var<=Acc
108pula
109sta\1,X
110ENDM
111;
112HanoiMMACROn,SrcTower,DstTower;UseinMain
113Push\3;DstTower
114Push\2;SrcTower
115Push\1;nDisks
116ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
117bsrHanoi_
118ais#HANOI_Stack;RestoreStack.***ResultinACC***
119ENDM
120;
121HanoiMACROn,SrcTower,DstTower;UseRecursively
122PushH\3;DstTower
123PushH\2;SrcTower
124PushH\1;nDisks
125ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
126bsrHanoi_
127ais#HANOI_Stack;RestoreStack.***ResultinACC***
128ENDM
129;
130HanoiKMACROn,SrcTower,DstTower;1stparameterisConstant#1
131PushH\3;DstTower
132PushH\2;SrcTower
133Push#1;ONEDisk
134ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
135bsrHanoi_
136ais#HANOI_Stack;RestoreStack.***ResultinACC***
137ENDM
138;

89

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

139MoveOneFromSrcToDstMACRO
140ldaSrc,X;..(Acc)andRETURN.Acc=0000_00Ta
141nsa;..NibbleSwapAcc.:Acc=00Ta_0000
142statmpAcc;Tmp=00Ta_0000
143ldaDst,X;Acc=0000_00Tb
144oratmpAcc;..Acc=00Ta_00Tb
145ENDM
146;==============================
147;Subroutine'hanoi_'
148;In"C"itwouldbe:BYTEhanoi_(BYTEN,BYTESrc,BYTEDst);
149;
150;(1)LOCALVariables(inSTACK):
151TowerTmpEQUSTD;remembernumberoftemporaltower
152n_1EQUTowerTmp+1;store"n1"
153HANOI_VarsEQUn_1STD+1;#deBYTESlocalesen'hanoi_'

154;(2)PARAMETERS(INSTACK,in>>REVERSE<<ordertostack.
155;..Ifyoumake*PushDST*,*PushSRC*andthen*PushN*,orderisas
156;..follows:firstN,thenSRCandlastDST
157NEQUn_1+1;tercerparmetro(1byte)
158SrcEQUN+1;segundoparmetro(1byte)
159DstEQUSrc+1;PRIMERparmetro.(1byte)
160HANOI_StackEQUDstSTD+1;UsodelStack(vars+param)

COMENTARIOS a ["Temarios\Ex#1-HanoiMin\HanoiMin--.asm"]:
Bueno, analicemos primero el programa principal. Esta es la parte donde se define
cuntosdiscosvanajugar(alambradodentrodelcdigo,parahacerlosimple...)

009NDEQU3;TODO:Get"ND"frompushbuttons,orfromPC,viaSCI

Yahemosdichoquelosmtodosrecursivossebasanfundamentalmenteenvariablestipo
dinmicas(comoenelC),quesonlasquesedefinenenelStack(yahicimosejercicios
de eso). Pero aqu se necesita una variable global, visible por todas las instancias
delprocedimientorecursivo,yquesirveparadefinirculeslatorretemporal,enun
instantedado:

013tmpAcc:DS1;helpertocalculateMagicNumber

ElprogramasedefineexpresandoalmximoSLOlaspolticas.VeamosMain,quecomoen
elejemplocodificadoenC,sirvesolocomoinicializacinyllamadoalarutinaque
realizademanerarecursiva,todoeltrabajo:

018Main:InitSys
019HanoiM#ND,#1,#3;MOVENDdisksfromtower1>3THAT'SIT!

Y,ahoras,veamoslarutinarecursiva:

021;====================================================================
022;byteHanoi_(byteN,byteTa,byteTb)//NfromTower_atoTower_Tb/*()*/
023Hanoi_:;CalledfromHanoiM(Main),andHanoi(below)RECURSIVELY
024CreateNewStackFrame

90

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Se requiere definir un nuevo Stack Frame cada vez que llamamos la rutina. Ese es el
propsitodelaMacro'CreateNewStackFrame'(versuimplementacinenelINCLUDEfile).

Ahora,mirasilacantidaddediscosquetienequetransferiresUNO.Recuerdequeese
casoeselsencillo;sihayunsolodiscoparasermovidodelatorre1ala3,LISTO:
Moverlo...con'MoveOneFromSrcToDst'

026ldaN,X;Acc="N",numberofdiscs(NisND
027cmp#1;..pushedbyHanoiMabove)
028bneSeveral;..if(N!=1)gotoSeveral
029;
030OnlyOne:;Only1disktomovefroma>b?MOVEIT,showtheANSWER:
031MoveOneFromSrcToDst;Acc=00Ta_00Tb
032brafin;<<<BreakheretoseeRESULTSinAcc
033;ND=3Seq:1_31_23_21_32_12_31_3

Delocontrario,aplicarelmismoprocedimientodemanerarecursiva.Primeroobtengala
identificacin de la torre temporal (EvalTowerTmp), dadas las actuales torres SRC y
DST:

036Several:;GotSeveraldisks?CallitselfRECURSIVELY!
037EvalTowerTmpSrc,Dst;Acc=Temp.Towernumber:6ab
038staTowerTmp,X;..TowerTmp=6ab

LuegoobtengaelactualN1,quesonlosdiscosquedebenmoversealatorretemporal

039ldaN,X;n_1=n1
040deca;..
041stan_1,X;..

Y,finalmente,apliqueelprocedimientorecursivo:

043Hanoin_1,Src,TowerTmp
044HanoiK#1,Src,Dst
045Hanoin_1,TowerTmp,Dst

Porltimo,reestablezcaelvalordelantiguoStackFrame,yRETORNE:

047fin:RestoreOldStackFrame
048RTS

B)IncludeFilehanoiMin_.inc:

COMENTARIOS a ["Temarios\Ex#1-HanoiMin\hanoiMin_.inc"]:
057;HANOImin_.inc,LuisG.UribeC.:V27D2013

Las primeras lneas no necesitan especial mencin. Push y Pop se entiende con
facilidad.

EstnlasequivalentesqueusanelregistrondiceH:Xparaapuntaralvaloralquese
requierehacerpushopop:

91

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

102PushHMACROPushValue;i.e:Push#3(Acc<=#3;pushAcc)
103lda\1,X
104psha
105ENDM
106;
107PopHMACROVar;i.e:Popvar:popAcc;var<=Acc
108pula
109sta\1,X
110ENDM

La prxima Macro guarda los parmetros: DST, SRC y N en es stack, reserva (AIS) el
espacio para las variables, llama a la subrutina y al regresar, libera el espacio
ocupado en el Stack (AIS). Esta se dise para su uso en MAIN (HanoiM): (hace
referenciaalosparmetrosenformadirecta:Push):

112HanoiMMACROn,SrcTower,DstTower;UseinMain
113Push\3;DstTower
114Push\2;SrcTower
115Push\1;nDisks
116ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
117bsrHanoi_
118ais#HANOI_Stack;RestoreStack.***ResultinACC***

Hanoieslaqueseusademanerarecursiva(hacereferenciaalosparmetrosempleando
elregistrondice:PushH):

121HanoiMACROn,SrcTower,DstTower;UseRecursively
122PushH\3;DstTower
123PushH\2;SrcTower
124PushH\1;nDisks
125ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
126bsrHanoi_
127ais#HANOI_Stack;RestoreStack.***ResultinACC***
128ENDM

Finalmente,cuandoserequierepasarelnmero1(#1)comodisco,unodelosPushHde
'Hanoi'tienequecambiarseporPushsimple:

130HanoiKMACROn,SrcTower,DstTower;1stparameterisConstant#1
131PushH\3;DstTower
132PushH\2;SrcTower
133Push#1;ONEDisk
134ais#HANOI_Vars;*RESERVA*VARS.localesen"Hanoi_"
135bsrHanoi_
136ais#HANOI_Stack;RestoreStack.***ResultinACC***
137ENDM

Estas 3 Macros se necesitan porque al programa Assembler del CodeWarrior le falta


EXPRESIVIDAD. En otros ensambladores, bastara una Macro, y ella determinara con
facilidad el curso de accin, si es el que se requiere en Main, o en las llamadas
recursivas,osisevaaincluirunaconstantecomoelnmero#1.

92

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

LaMacroMoveOneFromSrcToDsteslaquerealizaelmovimiento(que,ennuestroejemplo,
consiste simplemente en mostrar en el ACUMULADOR los nmeros de las torres que
participan en cada jugada. (Esta parte debera modificarse para presentar la
informacin en los LEDs de la tarjeta DEMOQE128, o enviarla por el canal de
comunicacinserialalPCdellaboratorio,parasupresentacinporpantalla.

139MoveOneFromSrcToDstMACRO
140ldaSrc,X;..(Acc)andRETURN.Acc=0000_00Ta
141nsa;..NibbleSwapAcc.:Acc=00Ta_0000
142statmpAcc;Tmp=00Ta_0000
143ldaDst,X;Acc=0000_00Tb
144oratmpAcc;..Acc=00Ta_00Tb
145ENDM

Adems de las Macros, est la subrutina, que es el VERDADERO MOTOR DEL PROCESO
RECURSIVO,graciasasumanejodevariablesdinmicasenStack:

147;Subroutine'hanoi_'
148;In"C"itwouldbe:BYTEhanoi_(BYTEN,BYTESrc,BYTEDst);
149;
150;(1)LOCALVariables(inSTACK):
151TowerTmpEQUSTD;remembernumberoftemporaltower
152n_1EQUTowerTmp+1;store"n1"
153HANOI_VarsEQUn_1STD+1;#deBYTESlocalesen'hanoi_'

154;(2)PARAMETERS(INSTACK,in>>REVERSE<<ordertostack.
155;..Ifyoumake*PushDST*,*PushSRC*andthen*PushN*,orderisas
156;..follows:firstN,thenSRCandlastDST
157NEQUn_1+1;tercerparmetro(1byte)
158SrcEQUN+1;segundoparmetro(1byte)
159DstEQUSrc+1;PRIMERparmetro.(1byte)
160HANOI_StackEQUDstSTD+1;UsodelStack(vars+param)

SiustedentiendelaimportanciadelejerciciodelasTorresdeHanoi,yescapazde
reescribirlo por su cuenta, habr logrado culminar la parte genrica del Curso de
ArquitecturadelComputador.

TIMERS

Gran cantidad de problemas requieren 'temporizadores' que permitan establecer en un


momentodeterminado,sitranscurrionociertolapso.Los"timers"sonelcoraznde
losSistemasOperativosydelossistemasEmbebidos...

NMERO DE TIMERS:

PorqunohacerunarutinaqueactiveydesactiveelTimer:RTC,TPM(oTIMER0enlos
PIC)deacuerdoalacantidaddemilisegundosquesequieremedir?

93

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Puesporque,comonormalmenteslohay*UN*mdulotemporizadorbsico(RTC),ysiempre
serequierenVARIOS(oMUCHOS)contadores,senecesitaranmsrecursosdehardwarede
losqueexisten!Lasolucincomnofrecevarioscontadoresporsoftware,basadosenun
slodispositivodehardware.

Anexohayunconjuntoderutinasparamanejar8temporizadoresdiferentes(quesonun
nmero razonable pero, si no le alcanzan, usted puede aumentarlos con relativa
facilidadparaajustarlosasusnecesidades!)

El conjunto de Rutinas de Soporte para 8 Timers est en el archivo 'timers8HS.inc',


versinparaCodeWarrior10.6,MC9S08QE128,DEMOQE128(Heslasecuencia,contadadesde
laversinAquehiceenNoviembredel2003.SeslaactualizacinparaelMC9S08.

Estas rutinas fueron publicadas en EDN, en la versin que realic para MICROCHIP
PIC16F84A,operandoa4MHz.

EnInternet:
http://edn.com/design/URIBE:UseeighttimerswithPIC16Fxxxmicrocontrollers

OPERACIN Y USO DE LA BIBLIOTECA DE TIMERS:

1.Seactivaelprocesodelos8temporizadoresempleandolaMacro:

Init8Timers

Lamaneracomooperaneslasiguiente:'Init8Timers'genera8variables,desde'Timer0'
hasta'Timer7',queocupanDOS(2)bytescadauna,(16bits,sinsigno).

Cada 'Timer' cronometrar una cierta cantidad de tiempo, en milisegundos. Por tanto,
podrnmedirseintervalosentre1msy65,536segundos(unpocomsdeunminuto;si
necesitaextenderlomsan,ustedtienequeprogramarcontadoresdeminutos...)

ExistetambinunbyteenelqueCADABITrepresentaelestadodeUNtimer,del0al7:
lavariablellamada'TimerFlags',y8SMBOLOSquefacilitanlalecturadelestadode
cadaunodeesosbits:'Timer0Ready'a'Timer7Ready'

2.Parainicializaruntemporizador(enMiliSegundos)seusalamacro
SetimerMS.Unopuededecir:

SetimerMS0,#2;activetemporizador0conlaconstante#2:2milisegundos,o:

SetimerMS 0, var ;active el timer 0 con el contenido de la variable var, en


milisegundos

Enelprogramadepruebatimer8HS.asm,incluidomsadelante,seempleanas:

SetimerMS0,#50;Timer0:50mSecondsthroughCONSTANT
SetimerMS1,var;Timer1:25mSecondsthroughVARIABLE(varholds#25)

94

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

3.LamacroSetimerMSinicializauntimer,peroelflujodeprogramaNOSEDETIENEA
ESPERAR a que pase el tiempo programado. La macro WaitMS_on hace ambas cosas:
Inicializauntimer_Y_esperahastaquetranscurraellapsoindicadoenMiliSegundos:
esunarutinaBLOQUEANTE.

4. En elprimer caso(SetimerMS), para averiguar subsecuentemente si ya secumpli o


no, el tiempo deseado, podran emplearse las instrucciones 'brset' o 'brclr', de la
siguienteforma:

brsetTimer0Ready,TimerFlags,labelYES
;SielbitestSET,esporqueYAsecumplieltiempo

brclrTimer1Ready,TimerFlags,labelNOT
;SielbitestCLR,esporqueNOse;cumplieltiempo
Sin embargo usted no tiene que hacer necesariamente eso, ya que he incluido esta
funcionalidad,perfectamenteencapsuladaenlasdosmacrosadicionales,quesemuestran
acontinuacin:

TimeOuttimer,gotoAddress
;(JUMPtogotoAddressiftimerexpired.Returnwithjump/br)

TimeOutStimer,bsrAddress
;(BRANCHTOSUBROUTINEbsrAddressiftimerexpired.Returnwithrts)

Estas Macros inspeccionan el temporizador timer y, en caso de haber expirado


(Timeout),ejecutanlarutinacorrespondiente,saltandoconBRANCHagotoAddress,ocon
BSRabsrAddress,segncorresponda.

TambinseincluyenlasMacrosComplementarias,parasuconveniencia:

NTimeOuttimer,gotoAddress
;..gotoAddressIFtimerhas*NOT*expired

NTimeOutStimer,callAddress
;..branchtoSubroutinecallAddressIFtimerhasNOTexpired

Antes de mostrar los programas en Assembly Language, voy a ilustrar el tema en "C"
(Windows). Luego tendrn la oportunidad de ver que las funcionalidades definidas en
EnsambladorsonEXACTAMENTELASMISMAS.Enesencialonicoquecambiaesellenguaje
deprogramacin.

19) Timers for Windows (timers.cpp):

Comoyahemosvistolaaproximacinalainclusindefuncionalidades,enformadeTop
DownDesign,voyapresentarenprimerlugarelincludefiletimers_h.h,quedefinelos
MECANISMOS. Despus, el programa que materializa la librera, Timers.cpp, y que
implementa los MECANISMOS. Por ltimo, un ejemplo para que se pueda visualizar el
empleodelasdiferentesfuncionalidades.timtst2.cpp:

95

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

["Laboratorios\Lab2\_New\timers_h.h"]
001/*****************************************************************/
002//timers_h.h:Windows,timeusage;LuisG.UribeC.
003//L13M2006L16O06MSVCJ01Y08C31G11V09S11S05E2013L21O2013
004/**/
005//IncludeFiles
006#include<windows.h>
007#include<conio.h>
008#include<stdio.h>
009usingnamespaceSystem;
010usingnamespaceSystem::Threading;

011#defineNTIMERS8//ThisMUSTbeapowerof2:2,4,8,16...

012/**/
013//FunctionPrototypes

014#defineTimeoutTimeouT//AvoidSystem::Timeoutconflict

015voidIniTimers(intntimers);
016voidSetimerMS(inttimer,inttimeMS);
017intTimeout(inttimer);
018voidWTimer(inttimer);
019voidWaitMS_on(inttimer,inttimeMS);

["Laboratorios\Lab2\_New\timers.cpp"]:
020/*****************************************************************/
021//Timers.cpp,WindowsLuisG.UribeC.S21S2013
022//..L13M2006L16O6VCC31G2011J17E2013(_kbhit)V08F2013

023//MSVisualStudio:Changeconfig.properties,general,toinclude:
024//..CommonLanguageRuntimeSupport(/clr)
025//..ProgramFileExtensionsMUSTbeCPP
026/**/
027//IncludeFiles
028#include"timers_h.h"

029/**/
030//GlobalVariables

031staticvolatilelongtimersMS[NTIMERS];

032/*===============================================================*/
033voidIniTimers(intntimers)/*()*/
034{//'ntimers'mustbe8inthisimplementation.ItisNOTused...

035if(NTIMERS&(NTIMERS1)){
036fprintf(stderr,
037"NTIMERS(%d)*MUST*beaPowerof2",NTIMERS);
038abort();
039}

96

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

040//LINKinitALLtimers(timersMS[NTIMERS])toZERO

041}/*IniTimers()*/

042/**/
043voidSetimerMS(inttimer,inttimeMS)/*()*/
044{
045longtc=(long)Environment::TickCount;//ticks(milliSeconds)

046timersMS[timer&(NTIMERS1)]=
047tc+(long)timeMS;//ticks(milliSeconds)

048}/*SetimerMS()*/

049/**/
050intTimeout(inttimer)/*()*/
051{
052longtc=(long)Environment::TickCount;//ticks(milliSeconds)

053_kbhit();//EnableCtrlCtesting!
054if(timersMS[timer&(NTIMERS1)]>=(tc))
055return(0);
056return(1);

057}/*Timeout()*/

058/**/
059voidWTimer(inttimer)/*()*/
060{
061longtc=(long)Environment::TickCount;//ticks(milliSeconds)

062if(timersMS[timer&(NTIMERS1)]tc>0)
063Thread::Sleep(timersMS[timer&(NTIMERS1)]tc);
064}/*WTimer()*/
065/**/
066voidWaitMS_on(inttimer,inttimeMS)/*()*/
067{
068SetimerMS(timer,timeMS);
069WTimer(timer);

070}/*WaitMS_on()*/

["Laboratorios\Lab2\_New\timtst2.cpp"]:
071char*_id=
072"timtst2.cpptestingroutines(Lite,WINDOWS).LuisG.UribeC.,"
073"C07S2011L31O2013\n";

074//char*_usage="timtest2\n";
075//cctimtst2.ctimers.c

076/**/
077/*IncludeFiles*/

97

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

078#include<stdio.h>
079#include<stdlib.h>

080#include"timers_h.h"

081/**/
082/*GlobalVariables*/

083chartext[]="1234567890";

084/*===============================================================*/
085voidmain(void)/*()*/
086{char*p=text;

087puts(_id);
088IniTimers(8);//only8timersallowedatthistime

089fputs("\n0)Press'ENTER'toprintw/odelays________",stdout);
090_getch();
091for(p=text;*p;p++){//ImpresinSINretardos
092_putch(*p);//putcharmaybebuffered;use_putch
093}

094/**/
095//RTCTest:Show3waysforcallingTimerRoutines.See://<<<

096fputs("\n1)Press'ENTER'tocontinueat300ms/char_",stdout);
097_getch();
098for(p=text;*p;p++){//ImpresinconWait_ona300mS.
099_putch(*p);
100WaitMS_on(0,300);//<<<BLOCKCPUfor300ms
101}
102fputs("\n2)Press'ENTER'tocontinueat750ms/char_",stdout);
103_getch();
104for(p=text;*p;p++){//Impresinconwhilea750mS.
105_putch(*p);
106SetimerMS(7,750);//<<<Setuptimer

107//<<<Dohereanyprocessyouneed

108WTimer(7);//<<<..waitforremainingtime
109}

110fputs("\n3)Press'ENTER'tocontinueat200ms/char_",stdout);
111_getch();

112p=text;//Impresinconwhilea200mS.
113ploop:
114while(*p){
115_putch(*p++);
116SetimerMS(5,200);//<<<Setuptimer

98

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

117//<<<Dohereanyprocessyouneed

118while(1){
119if(Timeout(5)){//<<<Testconditionlater...
120gotoploop;//<<<..finish?printnextchar
121}//<<<Youwon'tneedGOTOs!
122}
123}
124fputs("\n4)Press'ENTER'tocontinueat500ms/char_",stdout);
125_getch();
126for(p=text;*p;p++){//Impresinconwhilea500mS.
127_putch(*p);
128WaitMS_on(0,500);//<<<
129}
130fputs("\n5)Press'ENTER'tocontinueat1000ms/char",stdout);
131_getch();
132for(p=text;*p;p++){//Impresinconwhilea500mS.
133_putch(*p);
134WaitMS_on(0,1000);//<<<
135}
136fputs("\n6)Press'ENTER'toReturntofullspeed____",stdout);
137_getch();
138puts(text);

139puts("\nEnd...(Press'ENTER'tofinish)");
140getchar();
141exit(0);

142}/*main()*/

COMENTARIOS a ["Laboratorios\Lab2\_New\timers_.h"]:

El include file no tiene nada extrao; bsicamente define las funciones que se
implementarnacontinuacin.

011#defineNTIMERS8//ThisMUSTbeapowerof2:2,4,8,16...

El nmero de Timers se ha fijado a 8 en esta implementacin, pero puede cambiarse y


recompilarlalibrera.Losvalorestienenqueserpotenciasde2.

Las funcionalidades que se ofrecen son casi idnticas a las que mencionamos en la
introduccin,yalasqueimplementaremosenlenguajeensamblador:

015voidIniTimers(intntimers);
016voidSetimerMS(inttimer,inttimeMS);
017intTimeout(inttimer);
018voidWTimer(inttimer);
019voidWaitMS_on(inttimer,inttimeMS);

99

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Laboratorios\Lab2\_New\timers.cpp"]:

LavariabletimersMSesglobal,porconveniencia:

031staticvolatilelongtimersMS[NTIMERS];//GlobalVariable

IniTimers(8)(elparmetronointeresa;perosevalidaqueNTIMERSseapotenciade2)

033voidIniTimers(intntimers)/*()*/
034{//'ntimers'mustbe8inthisimplementation.ItisNOTused...
035if(NTIMERS&(NTIMERS1)){
036fprintf(stderr,
037"NTIMERS(%d)*MUST*beaPowerof2",NTIMERS);
038abort();
039}

No se inicializan los timers en esta implementacin, porque el LINKER realiza esta


funcinparaprogramasenC.

040//LINKinitALLtimers(timersMS[NTIMERS])toZERO
041}/*IniTimers()*/

Paraactivaruntimer:

043voidSetimerMS(inttimer,inttimeMS)/*()*/
044{longtc=(long)Environment::TickCount;//ticks(milliSeconds)
046timersMS[timer&(NTIMERS1)]=
047tc+(long)timeMS;//ticks(milliSeconds)
048}/*SetimerMS()*/

SetomaunadelasrepresentacionesdelahoradeWindows:TickCount(enMilisegundos);
selesumaeltiemporequerido,timeMS,enmilisegundostambin,yseloalmacenaenla
variablecorrespondientealtemporizadordeseado,timer.
La funcionalidad para establecer si ya venci el plazo seleccionado para algn
temporizador,timer,es'Timeout':

050intTimeout(inttimer){
052longtc=(long)Environment::TickCount;//ticks(milliSeconds)
053_kbhit();//EnableCtrlCtesting!
054if(timersMS[timer&(NTIMERS1)]>=(tc))
055return(0);
056return(1);
057}/*Timeout()*/

Timeout()leeen'tc'larepresentacindelahora,TickCountenMS,vigenteparael
momento en que se lo ejecuta; y compara si el valor almacenado para el temporizador
'timer' es mayor o igual a 'tc'. En caso de ser as significa que el tiempo actual,
'tc',nohasobrepasadoanalmemorizadoparaeltemporizador'timer'.Enesecaso,se
retornaun'0',queindiquequeannoestListoesetemporizador.

100

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Si,porelcontrario,eltiempoalmacenadoNOessuperioraltiempoactual,'tc',es
porque el tiempo ya ha sobrepasado el valor esperado por el temporizador deseado,
'timer',ysedevuelveun'1'indicandoqueeselapsoYAEXPIR.

WTimer consiste en detener el flujo del programa (bloquearlo) y esperar hasta que el
tiempo del temporizador 'timer', que ha sido previamente activado mediante un
SetimerMS, expire. Emplea una funcionalidad adhoc del Windows: Sleep(). Esta
implementacin tiene la ventaja de que al programa lo suspende el sistema operativo
hastaquesecumplalacondicin,yWindowspuedeadjudicarelCPUyotrosrecursos,
comolamemoria,eldisco,etc.,aalgnprocesoqueseencuentreendisponibilidadde
trabajar(estReady).
059voidWTimer(inttimer)/*()*/
060{longtc=(long)Environment::TickCount;//ticks(milliSeconds)
062if(timersMS[timer&(NTIMERS1)]tc>0)
063Thread::Sleep(timersMS[timer&(NTIMERS1)]tc);
064}/*WTimer()*/

Cuando hay que activar un temporizador, y el flujo del programa no puede continuar
hasta que transcurra el intervalo seleccionado, la funcionalidad BLOQUEANTE que se
empleaesWaitMS_on:

066voidWaitMS_on(inttimer,inttimeMS)/*()*/
067{SetimerMS(timer,timeMS);
069WTimer(timer);
070}/*WaitMS_on()*/

COMENTARIOS a ["Laboratorios\Lab2\_New\timtst2.cpp"]:
Elprogramadeprueba,timtst2.cpp,seexplicaporsmismo.

20) Librera de TIMERS para el HC9S08 (timers8HS.inc):

La librera 'timers8HS.inc' es FUNDAMENTAL para desarrollar sus proyectos. Entender


cmoesthechaesimprescindible,yustedtienequesercapazdecodificarsuspropias
funciones,comodemostracindequeentenditodoelproceso.

["Laboratorios\Lab2\Timers8HS\timers8HS.inc"]
001;Timers8HS.inc:LuisG.UribeC.,Basic8TimersSupportL30D2013
002;====================================================================
003;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
004;
005;Init8Timers:Init8Timerslibrary
006;
007;SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
008;..Settimerandcontinuetowork
009;
010;WaitMS_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
011;..SettimerandBLOCKuntiltimerexpires
012;
013;TimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
014;..gotoAddressIFtimerhasexpired

101

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

015;NTimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
016;..gotoAddressIFtimerhas*NOT*expired
018;TimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
019;..branchtoSubroutinecallAddressIFtimerhasexpired
020;NTimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
021;..branchtoSubroutinecallAddressIFtimerhasNOTexpired
022;
023;WaitISR_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
024;..SettimerandBLOCKuntiltimerexpires,INSIDEsomeISR
025;
026;TIMERS8ISR:ISRroutinestoupdate8timers(userneedtoINCLUDE
027;..thisMacroinMAINbutitisofnofurtherconcern)
028;====================================================================
029;DATADEFINITION.
030;Define8timersGlobalVariables
031;Note:Macrodirectives(DW,$IF...)cannnotgointomacros...GOK!
033;NOTE:REQUIRES'ORGram'**BEFORE**INCLUDE'timers8HS.inc'
034;..inmainprogram,tomakethisdatadefinitionswork!
035;***ALLfollowingvariables>>>MUST<<<resideonZEROpage!***
036;..(Timerflagsusebsetandbclr...)
037;
038;TimerDef:MACROandVariablesDEFINITION
039TimerDef:MACROtimer
040Timer\1:DS.W1;16bitcounters:65536mS:morethan
041Timer\1.RdyEQU\1;..oneminuteeachtimer(1mSTick)
042ENDM
043TimerDef0
044TimerDef1
045TimerDef2
046TimerDef3
047TimerDef4
048TimerDef5
049TimerDef6
050TimerDef7
051TimerFlags:DS.B1;8bitflags:Timer0,Timer1..
052;
053;DEFINES
054;ram:SETZ_RAMStart;<<<TIMERS8:PutTHISintoMainprogram<<<
055rom:SETROMStart;$2080
056initStack:EQURAMEnd+1;$1800=$17FF+1.Stackbeginson$17FF
057COP_Disable:EQU$42
058;
059;DefinesBitsforRTCProgramming
060;..RTCSC($1830)bits.02MC9S08QE128RM(ReferenceManual)U.pdf,p.246
061RTCPS_BY_ONEEQUmRTCSC_RTCPS3;..Bit#8Divideby1,gives1mSTick
062RTCIE:EQURTCSC_RTIE;..Bit#4RealTimeInterruptEnable
063RTCIE.bitEQUmRTCSC_RTIE;..Bit#4RealTimeClockInt.Enable
064NOT_RTCIE.bitEQU(~RTCIE.bit&$00FF)
065RTCIF:EQURTCSC_RTIF;..Bit#7RealTimeInterruptEnable
066RTCIF.bitEQUmRTCSC_RTIF;..Bit#7RealTimeClockInt.Enable
067ONE_KHZEQU0;Useinternaldefault1Khzclocksrc.
068RTC_FLAGSEQU(RTCIF.bit|ONE_KHZ|RTCIE.bit|RTCPS_BY_ONE)

102

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

069;====================================================================
070;MoreMACRODEFINITIONS
071TimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
072brset\1,TimerFlags,\2
073ENDM
074;
075NTimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
076brclr\1,TimerFlags,\2
077ENDM
078;
079TimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
080brclr\1,TimerFlags,\@cont
081bsr\2
082\@cont:
083ENDM
084;
085NTimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
086brset\1,TimerFlags,\@cont
087bsr\2
088\@cont:
089ENDM
090;
091SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
092bset\1,TimerFlags;MaketimerXReady...Mutex!!!
093pshh;saveH:X
094pshx;..
095ldhx\2;timeinmilliseconds(50)<<<
096sthxTimer\1;..<<<
097pulx;restoreH:X
098pulh;..
099bclr\1,TimerFlags;MaketimerXNotReady...
100ENDM
101;
102WaitMS_on:MACROtimer,time;timeisConstantorVariable
103SetimerMS\1,\2
104brclr\1,TimerFlags,*;Wait'time'msecondson'timer'
105ENDM
106;
107WaitISR_on:MACROtimer,time;timeisConstantorVariable
108psha;saveACC
109tpa;pushCCRSavesIMaskstatus
110psha;..
111sei;DISABLEINTERRUPTS(IMask=1):Let
112SetimerMS\1,\2;..SetimerusedinsideInt.Routines
113cli;REENABLEINTERRUPTS:LetRTCCount
114brclr\1,TimerFlags,*;Wait'time'msecondson'timer'
115pula;RestoreInterruptFlagMask
116tap;..toitsSavedvalue
117pula;RestoreACC
118ENDM
119;
120;AncillaryMACRODEFINITIONS

103

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

121UpdateTmr:MACROtimer
122brsetTimer\1.Rdy,TimerFlags,\@Next;Mutex!!!
123ldhxTimer\1;loadH:X
124aix#1;decrementTimerXX
125sthxTimer\1;..
126bne\@Next
127bsetTimer\1.Rdy,TimerFlags;0?:MarkTimerXXREADY
128\@Next:
129ENDM
130;====================================================================
131;RTCINIT.ThisisthebaseforTimerSupport
132Init8Timers:MACRO
133clrx
134clrh
135sthxTimer0;InitTimer0to0
136sthxTimer1;InitTimer1to0
137sthxTimer2;InitTimer2to0
138sthxTimer3;InitTimer3to0
139sthxTimer4;InitTimer4to0
140sthxTimer5;InitTimer5to0
141sthxTimer6;InitTimer6to0
142sthxTimer7;InitTimer7to0
143mov#$FF,TimerFlags;SetALL8bittimersflags:Done!
144lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
145staRTCSC;..ClearRTCIF;IntEnableRTC
146ENDM
147;====================================================================
148;RTCInterruptServiceRoutine(ISR).90cycles...
149TIMERS8ISR:MACRO
150pshh;HNotsavedbyInterruptprocess
151UpdateTmr0;ProtectedfromSetimersbyMutex
152UpdateTmr1;...
153UpdateTmr2
154UpdateTmr3
155UpdateTmr4
156UpdateTmr5
157UpdateTmr6
158UpdateTmr7
159;
160RTCISRexit:
161lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
162staRTCSC;..ClearRTCIF;IntEnableRTC
163pulh;HnotrestoredbyRTIprocess
164rti;..ReturnfromInterrupt
165ENDM

COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\timers8HS.inc"]:
Losaspectosmssobresalientesson:

003;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
005;Init8Timers:Init8Timerslibrary

104

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

007;SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
008;..Settimerandcontinuetowork

010;WaitMS_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
011;..SettimerandBLOCKuntiltimerexpires

013;TimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
014;..gotoAddressIFtimerhasexpired

015;NTimeOut:MACROtimer,gotoAddress;timerisalwaysaCONSTANT
016;..gotoAddressIFtimerhas*NOT*expired

018;TimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
019;..branchtoSubroutinecallAddressIFtimerhasexpired

020;NTimeOutS:MACROtimer,callAddress;timerisalwaysaCONSTANT
021;..branchtoSubroutinecallAddressIFtimerhasNOTexpired

023;WaitISR_on:MACROtimer,time;timeiseitherCONSTANTorVARIABLE
024;..SettimerandBLOCKuntiltimerexpires,INSIDEsomeISR

026;TIMERS8ISR:ISRroutinestoupdate8timers(userneedtoINCLUDE
027;..thisMacroinMAINbutitisofnofurtherconcern)

029;DATADEFINITION.
033;NOTE:REQUIRES'ORGram'**BEFORE**INCLUDE'timers8HS.inc'
034;..inmainprogram,tomakethisdatadefinitionswork!

Esta es el primer REQUISITO IMPORTANTE para emplear esta librera: en Main, ANTES de
INCLUIR 'timers8HS.inc', debe haberse hecho un: 'ORG ram' Esto se debe a que esta
libreradefinesuspropiasvariables,yrequiereencontrarseenelDATASEGMENTala
horadehacerlo.

039TimerDef:MACROtimer
040Timer\1:DS.W1;16bitcounters:65536mS:morethan
041Timer\1.RdyEQU\1;..oneminuteeachtimer(1mSTick)
043TimerDef0
...etc.,hasta7.

Observe algo con detenimiento. A veces algn usuario de la librera necesita emplear
nicamente un pequeo valor en sus temporizadores, y decide usar slo un byte para
representar sus retardos... Cuando van a cambiar el valor del WORD que representa el
contador,loalmacenansimplementeenlavariableTimerN(digamos,Timer0).YESTMAL.
TienenquerecordarqueestamquinaesBIGENDIAN,yqueelvalorTerminaldeunWORD
esten"Timer0+1"(enelsegundobytedelWORD).

UnaaproximacinmejorseracargarelvalorenelregistrondiceH:X(suvalorde8
bits quedara en la parte inferior de ndice) y mover sus 16 bits a Timer0; el
procesadorloalmacenacomocorresponde,dejandoelbytequerepresentasuinformacin,
enlaparteapropiadadelavariable.

059;DefinesBitsforRTCProgramming

105

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

LomejoresqueverifiqueTODOSlosbitsempleadosaqu,conelReferenceManualdel
MC9S08QE128, en donde estn claramente definidos todos y cada uno de los bits aqu
utilizados.

AlleerlasMacrosyfuncionesdefinidasenestalibrera,estpendientedecaeren
cuentadelaimplementacinDownUp,delomselementalhastalomssofisticado.

Las Macros TimeOut, NTimeOut, TimeOutS y NTimeOutS son de confeccin ms bien


elemental.

La Macro SetimerMS requiere alguna aclaracin explicativa; recibe dos parmetros, el


timerquehadeprogramarse,yelvalorde'time'enMilisegundos.

091SetimerMS:MACROtimer,time;timeiseitherCONSTANTorVARIABLE

Loprimeroquehace,antesdecomenzarajugarconlasvariablesasociadas,esmarcar
ese timer como READY (tiempo expirado). Lo hace colocando un uno (1) en el
correspondientebitdeTimerFlags:

092bset\1,TimerFlags;MaketimerXReady...Mutex!!!

Luego resguarda el registro ndice, que va a usar para cargar el valor del tiempo
(time)yalmacenarloenlavariableasociada(TimerX).Observelasangraeneltexto,
queresaltavariasinstruccionesparaunasolaoperacin.Finalmente,recuperaelvalor
delregistrondice:

093pshh;saveH:X
094pshx;..
095ldhx\2;timeinmilliseconds(50)<<<
096sthxTimer\1;..<<<
097pulx;restoreH:X
098pulh;..
099bclr\1,TimerFlags;MaketimerXNotReady...

ParalaMacroWaitMS_onresultatambininnecesarioalgnotrocomentario.

En cambio, se ha incluido una funcionalidad (WaitISR_on) que permite utilizar la


libreradetimers8,queestnbasadosenlasinterrupcionesdelreloj,DENTRODEOTRAS
rutinasdeinterrupcin.Estosehizoporcomodidad,ycomoejemplodequelosmanuales
de Motorola/Freescaleestn equivocados al decir que, habilitar interrupciones DENTRO
deinterrupciones,esmsconvenienteNOHACERLO,queporquedizqueescomplicado,yno
traeningnprovechonimejoraenelcomportamientodelosprogramas.

Complicado, y de cuidado, s es. Pero si le hicieran caso al manual, los


manufacturantesdesistemasoperativosnotendrantrabajo.

WaitISR_on, en trminos generales, equivale a Wait_ON, pero est especialmente


programada para funcionar DENTRO de las rutinas de interrupcin. NUNCA USE Wait_ON
dentrodeunarutinadeinterrupciones.

TAMPOCOUSEELMISMONMERODETIMERDENTRODELASRUTINASDEINTERRUPCIONESYENEL
PROGRAMAPRINCIPAL.

106

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

107WaitISR_on:MACROtimer,time;timeisConstantorVariable

Resguarda en el Stack el valor del acumulador; salva tambin el valor del CCR en el
Stack,paraguardarelestadoactualdelCPUyFUNDAMENTALMENTESIESTHABILITADOPARA
INTERRUPCIONES,ODESHABILITADO(IFlag)

Esto es importante porque, al momento de usar esta Macro WaitISR_on, la rutina debe
deshabilitar las interrupciones para poder trabajar toqueteando las variables del
timerinvolucrado.LuegodeesohabralatendenciaaREHABILITARlasinterrupciones...
pero lo que corresponde es DEJARLAS COMO ESTABAN cuando WaitISR_on comenz a
trabajar...Delocontrario,segenerarunDESASTRE.

108psha;saveACC
109tpa;pushCCRSavesIMaskstatus
110psha;..

Ahorasedeshabilitanlasinterrupciones(SEI)pues,comoacabodedecir,nosepuede
manipularlaestructuradedatosdeuntimer,sihaylaposibilidaddequeotrarutina,
fuera de sta interrupcin, tambin trate de hacerle cambios. Lo apropiado es
DESHABILITARLAS...

111sei;DISABLEINTERRUPTS(IMask=1):Let

Luego,semodificalaestructuradedatosdeltemporizador(SetimerMS)yseREHABILITAN
LAS INTERRUPCIONES (CLI), pues de lo contrario el timer no funcionara, ya que opera
porinterrupciones.Sehaceunbucledeespera(quenonecesariamenteesBLOQUEANTE,ya
quelasinterrupcionesestnACTIVAS!).

112SetimerMS\1,\2;..SetimerusedinsideInt.Routines
113cli;REENABLEINTERRUPTS:LetRTCCount
114brclr\1,TimerFlags,*;Wait'time'msecondson'timer'

Alterminarel'brclr',habrexpiradoeltimer;yeshoraderecomponertodo.

115pula;RestoreInterruptFlagMask
116tap;..toitsSavedvalue
117pula;RestoreACC

EsimportantenotarenUdateTmr,queNOTOCANADA(dadoqueentraporinterrupciones)
sielbitasociadoaltimerestenuno:

122brsetTimer\1.Rdy,TimerFlags,\@Next;Mutex!!!
(y,notequeSetimerloprimeroquehace,antesdemanipularnadams,escolocarese
bit en uno. As, si Setimer ha comenzado a actualizar la estructura de datos de un
temporizador dado, la rutina de interrupciones NO LO ACTUALIZAR, gracias a ese bit
que, adems de servir de indicador de READY, sirve como Semforopara la apropiacin
MutuamenteExclusivadeeserecurso:MUTEX)

120;AncillaryMACRODEFINITIONS
121UpdateTmr:MACROtimer
122brsetTimer\1.Rdy,TimerFlags,\@Next;Mutex!!!
123ldhxTimer\1;loadH:X
124aix#1;decrementTimerXX

107

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

125sthxTimer\1;..
126bne\@Next
127bsetTimer\1.Rdy,TimerFlags;0?:MarkTimerXXREADY
128\@Next:
La rutina de inicializacin de las variables, Init8Timers, no necesita mayores
aclaratorias.Soloqueenlaslneas144,145seescogeunrelojparaelRTC,queesde
1KHz(1milisegundoportick),muyconvenienteparanuestrospropsitos.Haytodauna
gama diferente para escoger; a usted le toca estudiarla, en caso de que sus
temporizadoresrequieransermuchomsrpidos,omslentos.

132Init8Timers:MACRO
...
144lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
145staRTCSC;..ClearRTCIF;IntEnableRTC

La rutina de interrupcin del RTC (Real Time Clock: TIMERS8ISR), que atiende las
actualizacionesdelosdiversostemporizadores,sebasaenlaMacroUpdateTmrque,como
yavimos,respetaauntemporizadorsifueradeestarutinadeinterrupciones,alguien
loestmanipulando,vaSetimer:

148;RTCInterruptServiceRoutine(ISR).90cycles...
149TIMERS8ISR:MACRO
150pshh;HNotsavedbyInterruptprocess
151UpdateTmr0;ProtectedfromSetimersbyMutex
152UpdateTmr1;...
153UpdateTmr2
154UpdateTmr3
155UpdateTmr4
156UpdateTmr5
157UpdateTmr6
158UpdateTmr7

160RTCISRexit:
161lda#RTC_FLAGS;Use1KHzinternalclock/1:1mStick
162staRTCSC;..ClearRTCIF;IntEnableRTC
163pulh;HnotrestoredbyRTIprocess
164rti;..ReturnfromInterrupt

21) Ejemplo del uso de la Librera de TIMERS (timer8HS.asm):

Lascosasquehayquerecordarparaemplearcorrectamentelalibreradetimers,estn
todasmarcadasenlosejemplosconelsmbolo:<<<

Nodejedemiraresasmarcasenlosejemplos,yatenderalasrecomendaciones...

["Laboratorios\Lab2\Timers8HS\timer8HS.asm"]
01;********************************************************************
02;ProgramaTimer8HS.asm:TSTTimerSupport
03;LuisG.UribeC.,L24N2003L08N4M27F7D08L7(timeOut)J16M2009
04;V31Y9V08J2012C04D2013L09D2013

108

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

05;
06;Includefiles
07;
08;CHECKLIST:ConserveelordenYlaposicinrelativade:
09;..derivative.inc,timers8HS.inceInit8Timers
10;
11;SiusaInit8Timers,*TIENE*queinicializarelvector:INT_RTC
12;..conDC.WRTC_INTERRUPT

13NOLIST
14INCLUDE'derivative.inc'
15LIST

16;
17;2)DEFINES
18ram:SETZ_RAMStart;<<<TIMERS8:<<<
19;====================================================================
20;3)GlobalVariables

21ORGram;<<<TIMERS8:*BEFORE*'timers8HS.inc'<<<
22NOLIST
23include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
24LIST

25var:DS.W1
26var2:DS.W1

27;********************************************************************
28;BeginofCodeSection
29ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
30ORGrom
31;
32;Alwaysincludethefollowing4instructions

33Main:lda#COP_Disable
34staSOPT1;SystemOptions1
35ldhx#initStack;InitSP
36txs

37Init8Timers

38;====================================================================
39;MainLoop(YourCode)

40ldhx#300;Beginwith300mSdelay,via'Var'
41sthxvar;..

42ldhx#2;2mSdelay,viaVar2
43sthxvar2;..
44;
45cli;Enableinterruptsnow
46;

109

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

47again:
48Setimer2,#200;Begin200mSecondsviaConstant
49Setimer5,var;300mSecondsviaVARIABLE
50loop:TimeOut2,Two_on;IfTimeOut2gotoTwo_on
51TimeOutS5,Five_on;elseifTimeOut5,brstoFive_on
52braloop;else'loop'
53;
54Five_on:;FromBRS(TimeOutS);returnviaRTS
55lda#5;ACC=5:identifyTHISroutine
56Setimer5,var;Reinstalltimer5w/300mS
57WaitMS_on7,var2;2mSecondsfromVariable(var2)
58ldhxvar
59bneFive_cont
60rts
61Five_cont:
62aix#1
63sthxvar
64rts
65;
66Two_on:;FromBRA(TimeOut);returnviaBRA
67lda#2;ACC=2:identifyTHISroutine
68Setimer2,#200;Reinstalltimerw/200mS
69WaitMS_on0,#150;TestWaitMS_onconstant
70braloop

71;====================================================================
72;PROGRAMTRAILER:
73;
74;1)TIM8INTMacro
75;2)InterruptVectors
76;
77;
78;RTCInterruptServiceRoutine,siusaInit8Timers...

79RTC_INTERRUPT:
80TIMERS8ISR

81;
82;InterruptVectors

83dummy_isr:;<<<MustbeplacedinROMSpace
84rti

85ORGVrtc;Increasingpriorityfrombottomup
86DC.WRTC_INTERRUPT;(SiusaInit8Timers...)

87ORGVirq;Virq,VswiandVreset
88DC.Wdummy_isr;IRQ
89DC.Wdummy_isr;SWI
90DC.WMain;RESET.Maximumpriority.Asynch.
91END

110

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\timer8HS.asm"]:
Aspectosnovedosos:

18ram:SETZ_RAMStart;<<<TIMERS8:<<<

20;3)GlobalVariables
21ORGram;<<<TIMERS8:*BEFORE*'timers8HS.inc'<<<
22NOLIST
23include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
24LIST

33Main:lda#COP_Disable
...
37Init8Timers

40ldhx#300;Beginwith300mSdelay,via'Var'
41sthxvar;..
42ldhx#2;2mSdelay,viaVar2
43sthxvar2;..

44;
45cli;Enableinterruptsnow

Sueleolvidarseesteltimopaso,ynadafunciona.Esttodoactivo,peroelprocesador
ignoratodaslasinterrupciones.

LomismosueleocurrirconlarutinadeinterrupcionesdelRTC.Hayqueincluirlade
acuerdoalsiguientecdigo:

79RTC_INTERRUPT:
80TIMERS8ISR

82;InterruptVectors

85ORGVrtc;Increasingpriorityfrombottomup
86DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
...

22) "WaitISR_on" Interactuando con la "IRQISR"

["Laboratorios\Lab2\Timers8HS\tim8_IRQHS.asm"]
001;********************************************************************
002;ProgramaTim8_IRQHS.asm:TimercallsinsideIRQISRJ01M2007D12A09
003;LuisG.UribeC.,J16A09V29Y09V08J2012C20F2013S21D2013
004;C20F2013:Use'WaitISR_on7,delay'onIRQISR,insteadofWaitMS_on
005;
006;ProgramshowSinteractionsbetweenRTC'timers8'interruptroutines
007;..and'IRQ'interrupts,whenitisneededtorequesttimerdelays
008;..fromIRQISR.Thisisatypicalcasewhenyouneedtorearmglobal
009;..interruptsDESPITETHEADVISEINCONTRARYFROMMOTOROLATECHNICAL

111

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

010;..DOCUMENTS...(cfr.01CPU08RM!ReferenceManualU.pdf,page30)
011;
012;
013;Includefiles

014NOLIST
015INCLUDE'derivative.inc'
016LIST

017;
018;Parameterdefinitions

019IRQACK:EQUIRQSC_IRQACK
020IRQIE:EQUIRQSC_IRQIE
021IRQPE:EQUIRQSC_IRQPE

022ram:SETZ_RAMStart;$80
023;====================================================================
024;GlobalVariables

025ORGram;Putthis*BEFORE*'timers8HS.inc'

026NOLIST
027include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
028LIST
029delay:DS.W1
030counter:DS.B1
031;********************************************************************
032;MAINPROGRAMHEADER:
033ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
034ORGrom

035Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
036staSOPT1;..SystemOptions1
037ldhx#initStack;InitSP
038txs
039;====================================================================
040;ExternalInterruptInitialization(>>>IRQ<<<)
041;1.MaskinterruptsbyclearingIRQIEinIRQSC.
042;(IRQIE=0onPoweronReset,byDefault)
043;2.SelectthepinpolaritybysettingtheappropriateIRQEDGbits
044;inIRQSC(IRQEDG=0isfallingedgetriggering)
045;(IRQEDG=0onPoweronReset,byDefault)
046;3.Ifusinginternalpullup/pulldowndevice,cleartheIRQPDDbit
047;inIRQSC(IRQPDD=0onPoweronReset,byDefault)
048;4.EnabletheIRQpinbysettingtheappropriateIRQPEbitinIRQSC
049;(IRQPE=0byDefaultonPoweronReset>>>WEMUSTsetIRQPE=1<<<)
050;NOTE:IRQSC:equ$000F?ZeroPageRegister.UseDirectaddressing!!
051;5.WritetoIRQACKinIRQSCtoclearanyfalseinterrupts.
052;6.SetIRQIEinIRQSCtoenableinterrupts

112

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

053bsetIRQPE,IRQSC;4.above
054bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
055bsetIRQIE,IRQSC;6.above
056;
057mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
058mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)
059ldhx#20;timeinmilliseconds(20)
060sthxdelay;..

061mov#$FF,counter;Decrement!!!insteadofincrement...
062mov#$FF,PTCD;Ledshavenegativelogic:0tolight
063mov#$FF,PTED;..
064Init8Timers
065;
066;MainLoop
067cli;GlobalEnableinterruptsNOW
068again:braagain
069;====================================================================
070;PROGRAMTRAILER:
071;
072;1)TIM8INTMacro
073;2)InterruptVectors
074;
075;
076;RTCInterruptServiceRoutine,siusaInit8Timers...

077RTC_INTERRUPT:
078TIMERS8ISR

079;
080;IRQINTERRUPTSERVICEROUTINE
081;IRQhasoneofthehighestprioritiesintheHCS08,andthehigher
082;..hardwarepriority,bellowResetandSWI.Thatisokfor
083;..responsiveness,butcaremustbetakentoassurethatno
084;..>>>PRIORITYINVERSION<<<ocurrsthroughlongISRtimes,for
085;...examplebyusingdebouncingdelays.Ifthisisthecase,you
086;..MUSTautodisabletheIRQinterruptsandreenableglobal
087;..interrupts,topermitotherlowerperipheralsaccess...

088IRQISR:
089bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**

090pshh;Notsavedbyinterruptproc
091;
092;20mSdelayprocessingforIRQISR:Helptoavoidmultiple
093;..interruptsduetocontactbouncingfromIRQpin...
094WaitISR_on7,delay;20MSecondsfordebouncing.Thisonly
095;..worksifRTCisenabledtointerrupt..
096;..YoucouldhaveincludedNOPloopsto
097;..delay:butyouCANNOTblockallother
098;..peripheralinterrupts!So,youmust
099;..followthissamestrategy...

113

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

100;
101;***NOTE***Timer7>>>MUSTNOT<<<BEUSEDANYWHEREELSE!
102;..ItbelongsEXCLUSIVELYtothis'IRQISR'
103;

104deccounter;DriveLEDsusingnegativelogic,is
105movcounter,PTCD;6bitstodriveLEDs
106movcounter,PTED;2bitsmoretodrivehigherLEDs

107IRQISRexit:
108bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
109bsetIRQIE,IRQSC;ReenableIRQinterrupts

110pulh;Notrestoredbyinterruptprocess
111rti;ReturnfromInterrupt

112;
113;InterruptVectors

114ORGVrtc;Increasingpriorityfrombottomup
115DC.WRTC_INTERRUPT;(SiusaInit8Timers...)

116ORGVirq
117DC.WIRQISR;IRQ

118ORGVreset
119DC.WMain;RESET.Maximumpriority.Asynch.

120END

COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\tim8_IRQ-HS.asm"]:

Aspectosnovedosos:

ProtocolocompletodeHabilitacindelIRQ:ExternalInterruptInitialization
(>>>IRQ<<<)

041;1.MaskinterruptsbyclearingIRQIEinIRQSC.
042;(IRQIE=0onPoweronReset,byDefault)
043;2.SelectthepinPOLARITYbysettingtheappropriateIRQEDGbits
044;inIRQSC(IRQEDG=0isfallingedgetriggering)
045;(IRQEDG=0onPoweronReset,byDefault)
046;3.Ifusinginternalpullup/pulldowndevice,cleartheIRQPDDbit
047;inIRQSC(IRQPDD=0onPoweronReset,byDefault)
048;4.EnabletheIRQpinbysettingtheappropriateIRQPEbitinIRQSC
049;(IRQPE=0byDefaultonPoweronReset>>>WEMUSTsetIRQPE=1<<<)
050;NOTE:IRQSC:equ$000F?ZeroPageRegister.UseDirectaddressing!!
051;5.WritetoIRQACKinIRQSCtoclearanyfalseinterrupts.
052;6.SetIRQIEinIRQSCtoenableinterrupts

114

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

053bsetIRQPE,IRQSC;4.above
054bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
055bsetIRQIE,IRQSC;6.above

ProgramacindelosLEDs:

057mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
058mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)
059ldhx#20;timeinmilliseconds(20)
060sthxdelay;..

LosLEDsestnalambradosparaENCENDERconunCERO:

061mov#$FF,counter;Decrement!!!insteadofincrement...
062mov#$FF,PTCD;Ledshavenegativelogic:0tolight
063mov#$FF,PTED;..

080;IRQINTERRUPTSERVICEROUTINE
081;IRQhasoneofthehighestprioritiesintheHCS08,andthehigher
082;..hardwarepriority,bellowResetandSWI.Thatisokfor
083;..responsiveness,butcaremustbetakentoassurethatno
084;..>>>PRIORITYINVERSION<<<ocurrsthroughlongISRtimes,for
085;...examplebyusingdebouncingdelays.Ifthisisthecase,you
086;..MUSTautodisabletheIRQinterruptsandreenableglobal
087;..interrupts,topermitotherlowerperipheralsaccess...

LaISRdelperifricoquevayaaemplearWaitISR_on,tieneparticularidadesnecesarias
para funcionar. En primer lugar, dado que va a rehabilitarse la atencin de
interrupciones, ANTES de terminar esa IRQ (en el ejemplo, ISRIRQ), es INDISPENSABLE
AUTODESHABILITARlasinterrupciones:

088IRQISR:
089bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**

Enesteejemplosencillo,sellamaacontinuacinaWaitISR_on(quesiyaleyeronsu
cdigo,hacevariascosas,entreellas,HABILITARLASINTERRUPCIONESDELCPU.(Deotra
forma,nooperaranlasinterrupcionesdeltimer,RTC)

094WaitISR_on7,delay;20MSecondsfordebouncing.
101;***NOTE***Timer7>>>MUSTNOT<<<BEUSEDANYWHEREELSE!
102;..ItbelongsEXCLUSIVELYtothis'IRQISR'
103;

Enelejemplo,cadavezqueseactivaelIRQ,seincrementallosLEDs.Comoencienden
alrevs,enlugardeincrementar,decrementamos...(truco)

104deccounter;DriveLEDsusingnegativelogic,is
105movcounter,PTCD;6bitstodriveLEDs
106movcounter,PTED;2bitsmoretodrivehigherLEDs

ParafinalizarIRQISR,sedaelAcknowledgecorrespondientealhardware,yseretorna
alprogramaprincipal:

115

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

107IRQISRexit:
108bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
109bsetIRQIE,IRQSC;ReenableIRQinterrupts
...
111rti;ReturnfromInterrupt

23) Enciende los 8 LEDs con Diferentes Intervalos

["Laboratorios\Lab2\Timers8HS\TimedFlash8.asm"]
001;********************************************************************
002;ProgramTimedFlash8.asm:LuisGUribeC.D10J2012C20F2013C04D2013
003;Flashesall8LEDsatdifferentintervalseachone.PushIRQto
004;..toggleprogramOFF/ON
005;C20F2013:DoNOTusetimer7insideIRQISRANDinMainprogram...
006;
007;Includefiles
008NOLIST
009INCLUDE'derivative.inc'
010LIST
011;
012;Parameterdefinitions

013IRQACK:EQUIRQSC_IRQACK
014IRQIE:EQUIRQSC_IRQIE
015IRQPE:EQUIRQSC_IRQPE

016ram:SETZ_RAMStart;$80
017;====================================================================
018;GlobalVariables

019ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<

020NOLIST
021include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
022LIST
023LEDsMask:DS.B1;Rambank#0(directaddressing)
024Toggle:DS.B1
025;********************************************************************
026;MAINPROGRAMHEADER:
027ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
028ORGrom

029Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
030staSOPT1;..SystemOptions1
031ldhx#initStack;InitSP
032txs
033;====================================================================
034;ExternalInterruptInitialization(>>>IRQ<<<)(seeTim8_IRQHS.asm)

116

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

035bsetIRQPE,IRQSC;4.above
036bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
037bsetIRQIE,IRQSC;6.above
038;
039;InitLEDsPORTsPTCD(bits05)andPTED(bits67)

040mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
041mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)

042Init8Timers
043;
044;MainLoop
045cli;GlobalEnableinterruptsNOW
046Setimer0,#673>>1
047Setimer1,#150>>1
048Setimer2,#2755>>1
049Setimer3,#1398>>1
050Setimer4,#511>>1
051Setimer5,#1002>>1
052Setimer6,#3000>>1
053Setimer7,#355>>1
054mov#$01,Toggle;BegininRUNstate
055loop:
056brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
057clrLEDsMask

058NTimeOut0,ET0
059bset0,LEDsMask
060Setimer0,#673>>1
061ET0:
062NTimeOut1,ET1
063bset1,LEDsMask
064Setimer1,#150>>1
065ET1:
066NTimeOut2,ET2
067bset2,LEDsMask
068Setimer2,#2755>>1
069ET2:
070NTimeOut3,ET3
071bset3,LEDsMask
072Setimer3,#1398>>1
073ET3:
074NTimeOut4,ET4
075bset4,LEDsMask
076Setimer4,#511>>1
077ET4:
078NTimeOut5,ET5
079bset5,LEDsMask
080Setimer5,#1002>>1
081ET5:
082NTimeOut6,ET6
083bset6,LEDsMask

117

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

084Setimer6,#3000>>1
085ET6:
086NTimeOut7,ET7
087bset7,LEDsMask
088Setimer7,#355>>1
089ET7:
090ldaPTCD
091eorLEDsMask
092staPTCD
093staPTED
094jmploop
095;====================================================================
096;PROGRAMTRAILER:
097;1)TIM8INTMacro
098;2)InterruptVectors
099;
100;RTCInterruptServiceRoutine,siusaInit8Timers...

101RTC_INTERRUPT:
102TIMERS8ISR
103;
104;IRQINTERRUPTSERVICEROUTINE

105IRQISR:
106bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**

107pshh;Notsavedbyinterruptproc
108ldaToggle
109eor#%00000001
110staToggle
111;
112IRQISRexit:
113sei
114bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
115bsetIRQIE,IRQSC;ReenableIRQinterrupts

116pulh;Notrestoredbyinterruptprocess
117rti;ReturnfromInterrupt
118;
119;InterruptVectors
120dummy_isr:;<<<<MustbeplacedinROMSpace
121rti

122ORGVrtc;Increasingpriorityfrombottomup
123DC.WRTC_INTERRUPT;(SiusaInit8Timers...)

124ORGVirq;Virq,VswiandVreset
125DC.WIRQISR;IRQ
126DC.Wdummy_isr;SWI
127DC.WMain;RESET.Maximumpriority.Asynch.

128END

118

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Laboratorios\Lab2\Timers8HS\TimedFlash8.asm"]:
EsteejercicioresultasimpticodeobservarenlatarjetaDEMOQE128:

044;MainLoop
045cli;GlobalEnableinterruptsNOW

Activalos8timers,cadaunoconunvalorqueobtuvedeunprogramaquegeneranmeros
al azar.El nmero es dividido por dos (>> 1) paraque dure la mitad encendido y la
mitadapagado(50%DuttyCycle)

046Setimer0,#673>>1
047Setimer1,#150>>1
048Setimer2,#2755>>1
049Setimer3,#1398>>1
050Setimer4,#511>>1
051Setimer5,#1002>>1
052Setimer6,#3000>>1
053Setimer7,#355>>1
054mov#$01,Toggle;BegininRUNstate

Toggleesunavariablequesirveparadetenerocontinuarelparpadeo,aloprimirel
botndeIRQ.

El proceso es muy sencillo. Se trata de un lazo infinito, en el que se pregunta por


cadatemporizadorparaversiyaexpir.Cuandoalgunoyacumpli,sedebecambiarel
estadodelcorrespondienteLED.

La rutina no afecta directamente los LEDs, sino que, a partir de una mscara
(LEDsMask), que comienza en ceros al principio del ciclo, se coloca en 1 el bit
correspondiente a cada LED que tenga que CAMBIAR. Al finalizar el ciclo, se hace un
EXORdelLEDsMaskconelvaloractualdelosLEDs(lnea091eor).As,secambiael
valor,deencendidoaapagado,oviceversa,paraaquellosaloscualesselesvenciel
tiempo. Desde luego, cada vez que para alguno expira el intervalo, se lo vuelve a
inicializar,conSetimer...

091eorLEDsMask
055loop:
056brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
057clrLEDsMask

058NTimeOut0,ET0
059bset0,LEDsMask
060Setimer0,#673>>1
061ET0:
062NTimeOut1,ET1
063bset1,LEDsMask
064Setimer1,#150>>1
...
089ET7:
090ldaPTCD
091eorLEDsMask

119

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

092staPTCD
093staPTED
094jmploop

La105IRQISRbsicamentealternalavariableToggle(subit#0),deestamanera,el
programaprincipalpuededetenertodoelproceso,oreanudarlo,deacuerdoalvalorde
lavariableToggle:

056brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
...
108ldaToggle
109eor#%00000001
110staToggle

24) Enciende ORDENADAMENTE los 8 LEDs con Diferentes Intervalos

LosLEDsmslentosestnaunladodelatarjeta;losmsrpidosalotroextremo.Es
unavariacinsencilladelejercicioanterior,ynonecesitamayorescomentarios:

["Laboratorios\Lab2\Timers8HS\TimedFlash8Ordered.asm"]
001;********************************************************************
002;TimedFlash8Ordered.asm:LuisG.UribeC.D10J2012C20F2013S22G13
003;C04D2013,J19D2013cosmetics
004;Flashesall8LEDsatdifferentintervalseachone.PushIRQto
005;..toggleprogramOFF/ON
006;C20F2013:DoNOTusetimer7insideIRQISRANDinMainprogram...
007;
008;Includefiles
009NOLIST
010INCLUDE'derivative.inc'
011LIST
012;
013;Parameterdefinitions

014IRQACK:EQUIRQSC_IRQACK
015IRQIE:EQUIRQSC_IRQIE
016IRQPE:EQUIRQSC_IRQPE

017ram:SETZ_RAMStart;$80
018;====================================================================
019;GlobalVariables

020ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<

021NOLIST
022include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
023LIST

024LEDsMask:DS.B1;Rambank#0(directaddressing)
025Toggle:DS.B1
026;********************************************************************

120

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

027;MAINPROGRAMHEADER:
028ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
029ORGrom

030Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
031staSOPT1;..SystemOptions1
032ldhx#initStack;InitSP
033txs
034;====================================================================
035;ExternalInterruptInitialization(>>>IRQ<<<)(seeTim8_IRQHS.asm)

036bsetIRQPE,IRQSC;4.above
037bsetIRQACK,IRQSC;5.above.IRQACK=1toclear(!)IRQF
038bsetIRQIE,IRQSC;6.above
039;
040;InitLEDsPORTsPTCD(bits05)andPTED(bits67)

041mov#$FF,PTCDD;SetPortsC&Dallbitsforoutput
042mov#$FF,PTEDD;..(theydrivetheLEDsonDEMOQE128)

043Init8Timers
044;
045;MainLoop
046cli;GlobalEnableinterruptsNOW
047SetimerMS0,#150>>1
048SetimerMS1,#355>>1
049SetimerMS2,#511>>1
050SetimerMS3,#673>>1
051SetimerMS4,#1002>>1
052SetimerMS5,#1398>>1
053SetimerMS6,#2755>>1
054SetimerMS7,#3000>>1
055mov#$01,Toggle;BegininRUNstate
056loop:
057brclr0,Toggle,*;WaitforBit0(RUN/~STOP)
058clrLEDsMask

059NTimeOut0,ET0
060bset0,LEDsMask
061SetimerMS0,#150>>1
062ET0:
063NTimeOut1,ET1
064bset1,LEDsMask
065SetimerMS1,#355>>1
066ET1:
067NTimeOut2,ET2
068bset2,LEDsMask
069SetimerMS2,#511>>1
070ET2:
071NTimeOut3,ET3
072bset3,LEDsMask
073SetimerMS3,#673>>1

121

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

074ET3:
075NTimeOut4,ET4
076bset4,LEDsMask
077SetimerMS4,#1002>>1
078ET4:
079NTimeOut5,ET5
080bset5,LEDsMask
081SetimerMS5,#1398>>1
082ET5:
083NTimeOut6,ET6
084bset6,LEDsMask
085SetimerMS6,#2755>>1
086ET6:
087NTimeOut7,ET7
088bset7,LEDsMask
089SetimerMS7,#3000>>1
090ET7:
091ldaPTCD
092eorLEDsMask
093staPTCD
094staPTED
095jmploop

096;====================================================================
097;PROGRAMTRAILER:
098;1)TIM8INTMacro
099;2)InterruptVectors
100;
101;RTCInterruptServiceRoutine,siusaInit8Timers...
102RTC_INTERRUPT:
103TIMERS8ISR
104;
105;IRQINTERRUPTSERVICEROUTINE
106IRQISR:
107bclrIRQIE,IRQSC;**SELFDISABLEIRQInterrupts**
108pshh;Notsavedbyinterruptproc
109ldaToggle
110eor#%00000001
111staToggle
112;
113IRQISRexit:
114sei
115bsetIRQACK,IRQSC;IRQACK=1toclear(!)IRQF
116bsetIRQIE,IRQSC;ReenableIRQinterrupts

117pulh;Notrestoredbyinterruptprocess
118rti;ReturnfromInterrupt
119;
120;InterruptVectors
121dummy_isr:;<<<MustbeplacedinROMSpace
122rti
123ORGVrtc;Increasingpriorityfrombottomup

122

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

124DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
125ORGVirq;Virq,VswiandVreset
126DC.WIRQISR;IRQ
127DC.Wdummy_isr;SWI
128DC.WMain;RESET.Maximumpriority.Asynch.
129END

Finalizacin Tema TIMERS


Antes de finalizar el tema de los Timers, y despus de haber ledo la documentacin
hasta aqu, haberla estudiado y entenderla... haga un examen de conciencia que le
permitadecirconcerteza,sinohayunoomsdetallesqueustedhubierapasadopor
alto,oquenisiquieraentendi.
Esteeselniveldedetallealquehayqueacostumbrarsecuandotrabajaenstareade
lossistemasEmbebidos,dondetododependedetodo,ycuandonopensarenunbitque
nos sirva como Mutex (tal como lo manejan la rutina de interrupciones del timer, y
otrascomoelSetimer...)puededaraltrastecontodounproyecto.
METICULOSIDAD, MUCHO ANLISIS Y REFLEXIN EN CADA PASO, MUCHAS PRUEBAS (TestDriven
Development,TDD)sonmenesterenunproyecto.
No crea que esta dificultad es inherente slo a nuestro campo. La parte electrnica
sloesmsfcilporquehayunagrancantidaddefuncionalidadesdemuyaltonively
grancomplejidadincluidaencircuitosintegrados,tantoanalgicoscomodigitales;de
frecuenciabajasymuyaltas.
Poresosostengoquehayqueaceptarquenuestraformadediseohacambiado:ahorahay
quesaberINTEGRARcomponentes,quepuedensertarjetascompletas,comolaDEMOQE128,o
losCreditCardComputers,quepor$100noscolocanenlasmanostodoelpoderdeunPC
IBM/ATcompatible,comolosquecomproenCompuLabhttp://compulab.co.il/
The486COREyousenttoushasarrivedatthisverymomenttoouroffice.Imust
congratulateyouandCompuLab:Thisistrulyabeautifulpieceofhardware.
LuisG.Uribe,Vessing2000

PROGRAMAS AVANZADOS EN ASSEMBLY


LANGUAGE, PARTE III
Hemos cubierto hasta ahora una seccin introductoria, donde aprendimos a usar el
conjunto de instrucciones del HCS08, sus modos de direccionamiento, y all hicimos
nuestrasprimerasaproximacionesalaprogramacindeperifricos,encendiendoalgunos
LEDsyleyendolosinterruptoresdelatarjetaDEMOQE128.
AprendimosausarelambientededesarrolloCodeWarriorysudebbuger,quenospermite
seguirpasoapasoelprogramadirectamenteDENTROdelMCU,locualsefundamentaenla

123

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

nueva versin de esta familia de microcontroladores, que incluye un acceso directo a


los registros internos del MCU, y una infraestructura de Debugging que permite a un
programa externo (CodeWarrior) interactuar con los recursos internos del micro, SIN
detenersufuncionamientonicasiinterferirconl.Parahaceruntrabajosimilaren
otrasfamiliasdemicrocontroladores,senecesitaadquirirunainterfazconocidacomo
ICE (In Circuit Emulator) que, por un lado reemplaza al micro en la tarjeta del
cliente,medianteunenchufequetienelamismaformadelMCUyqueporelotroextremo
se conectaal PC; all, un programa SIMULA el comportamiento del micro, genera todos
losvaloresdevoltajeenlospinesqueproduciraelMCUoriginal,leelasvariables
externas,digitalesoanalgicascomosifueraelMCUy,desdeluegoqueinteractacon
el usuario, puesto que no hay tal MCU, sino una versin simulada del mismo. Un
dispositivocomoste,dependiendodelmanufacturante,puedecostarentre$600y$2000
que,comosever,nonecesariamenteresultabarato.
Pues sta familia del HCS08 incluye dentro del mismo chip todos los recursos que
permitenhacerexactamentelomismoqueconelICE,yauncostonulo.
En los ejercicios un poco ms avanzados aprendimos a crear variables dinmicas en el
stack,alestilodelC;probamosadescomponerlosprogramasensubrutinas,yconocimos
elprotocolodellamadodelasmismas:
CREARELSTACKFRAMEPARASUBRUTINAS:
GuardarlosparmetrosenelStack;
Reservarelespacioparalasvariableslocalesdelasubrutina;
Hacerlallamada;
Inicializarlasvariableslocales,sieselcaso;
Ejecutarelcdigo;
Almacenarelvalorresultante(casisiempreunByte)enelAcumulador,oenuna
variable:externa,oGlobal,odefinidamedianteunapuntador.
REMOVERELSTACKFRAMEACTUALYRECUPERARELANTERIOR
Eliminartantovariableslocalescomoparmetros
RETORNAR.
Empleando variables en el stack pudimos hacer con facilidad programas recursivos, al
estilodelastorresdeHanoi,clculodefactorialysimilares.

Y...comenzamoslaparteavanzada,dondeaprendimosaprogramarunabateradeTimers,
queademsderesultarnosmuybeneficiososennuestroslaboratoriosyenelproyecto,
nossirviparavercondetenimientolaformacomosediseayconstruyeSOFTWARE:Una
definicindelproblema,descomponindoloenfuncionesdesdeelnivelmsalto,bajando
hasta llegar a definir las operaciones ms elementales (Top Down Design); y la
codificacin,quehicimosdesdestasfuncioneselementaleshaciaarriba,hastallegar
aimplementarelcdigodemsaltonivel(ButtomUpCoding).Hicimosmuchoesfuerzoen
mostrareldesarrollodeesalibrera,descomponindolaenPolticasyMecanismos,para
definireimplementarporunalado,cdigoqueslotienequeverconLOQUESEVAA

124

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

HACER, sin tener en cuenta cmo se lo va a hacer (si van a hacerse los timers con
retrasos, con temporizadores, empleando o no interrupciones...). Y por ltimo, la
codificacindelosMecanismos,quesdependendecmosevaahacercadaoperacin.
Pero an all, puede obligarse al programador a establecer una separacin entre las
rutinasqueTOCANelhardware,yaquellasqueno.Windows,porejemplo,tieneunacapa
de software que separa el hardware de otro software, y se la denomina HAL: Hardware
AbstractionLayer.Esmuyimportantelograralmximoesaseparacin,demaneraquesi
secambiaelhardwarenohayaquetiraralabasuratodoelsoftware.Recuerdanhaber
odocadaratoqueelmicroeraun486,unPentium,unPRO,unMMX,unQuadracore?Y
esoocurreconunavelocidadpasmosa.Ytambin,quesusdiscoserande560Mb,de1Gb,
de100Gb,de1Terabyte,deestadoslido...
As que: NO separar el hardware especfico, del resto del cdigo, es GARANTA DE
SUICIDIOENUNAEMPRESA.
Llegamosahoraalltimoaspectoquepuedecubrirseenlashorasreservadasparaeste
cursodeArquitecturadelComputador,quehahechonfasisprimordialenlaUTILIZACIN
delosmicrocontroladores,msqueensudiseo.
Elperifricodecomunicacinserial(SCIenelMC9S08QE128)tienevariasventajaspara
elaprendizaje,porlascualeslohemosincluidoaqu.
En PRIMER lugar, una de las principales funciones que realizan los MCUs en sistemas
embebidos consiste en intercambiar informacin con unos con otros, y con sistemas de
mayorjerarqua,comoservidores,etc.Estudiaresteperifricoseenmarcadentrodela
importanciadelafuncin.
SEGUNDO,cubrelagranmayoradeaspectosbsicosquesedebenconsiderarsiempreal
utilizar una funcin de stas: manejo de los perifricos propiamente dichos
(encenderlos, apagarlos), control de sus lneas de habilitacin para interrupcin, y
protocolodeintercambiodeinformacin:DataReady,Done,dondeelperifricoproduce
una seal de que hay datos listos para leerse, y el MCU le da un reconocimiento
(Acknowledge)alperifricoparaquelpuedaprocedercorrectamenteconotrodato.Lo
mismoocurreconlasinterrupciones:suhabilitacin,procesamiento,reconocimiento.Se
tocan otros aspectos como la habilitacin de interrupciones DENTRO de rutinas de
interrupciones, a pesar de todolo que los manuales de Freescale hablan en contra...
Hayqueaprendertodoelprotocolodeinterrupcin:quguardaelmicroenelStack,
quno(yqueporlotantotienequeguardarelprogramadoramano),enquordense
guardanyserecuperanlosvaloresalmacenados,cmosedesactivanautomticamentelas
interrupcionesanivelgeneraldelCPU,etc.

TERCERO: Como parte del protocolo de atencin se aprende a manejar el vector de


interrupciones,ysehacemuchonfasisenNOhacerlamayorpartedelprocesodentro
delarutinadeinterrupciones,sinoenporejemplorecibirundato,almacenarloen
algnlugarreservadoeidneoparaello,informaralprogramaprincipaldeeseEVENTO,
quizs activando una bandera (flag), y retornar rpidamente al cdigo al que se
interrumpi.
En este sentido es conveniente incluir el manejo de Colas de Datos, lo cual se hace
precisamenteaquyahora,parasincronizarlosdoseventos,deporsasncronosentre

125

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

ellos,quesonlosdatosentrantesdeunequipoousuarioexterno,independiente,yel
MCU.Seindicanvariantesdelmtodo,medianteTABLAS,quepuedenfuncionarcomoDouble
Buffers cuando se procesan datos que llegan en rfagas, como es el caso de la
manipulacindediscos,etc.
Todoloanteriorseintegra,pues,enlasiguienteseccin.

COLAS DE DATOS
Cuando dos sistemas de diferentes velocidades se comunican entre s, de manera
asncrona,esdecir,cuandonoexisterelacintemporaldefinida,clarayprecisaentre
ellos,esindispensablesincronizarlosodelocontrarioseperderndatosdurantela
transferenciadeinformacin.Unejemplocotidianoesunapersonaempleandoelteclado
paraenviarinformacinasuPC;nopodransermsdiferentessusvelocidades,yno
existesincronaniporasomoentreelusuarioyelPC.
La forma de sincronizarlos vara de acuerdo a la naturaleza de la informacin
transmitida.Sielsistemamsrpidopuededarseellujodeemplearbuenapartedesu
tiempoesperandoqueelusuarioletransmitaunaletra,quizsbastaconunelementode
memoriaenelquereposarlaletramientrasselaprocesa,antesdeveniraleerel
siguiente smbolo. El dispositivo elemental, unitario, de memoria, suele ser un
registro (Data Buffer) interpuesto entre el dispositivo Productor de la informacin
(canaldecomunicacinconelusuario),yelConsumidordelamisma,enestecaso,el
CPUdelPC(EstaunidaddeacoplerecibeelnombredeINTERFAZ;eninglsInterface.NO
SETRADUCEALCASTELLANOCOMOINTERFACE!
Para facilitar la vida del PC, se agrega a la Interfaz una bandera, el bit de Data
Ready,queseactivacuandohallegadounaletraporelcanaldeinformacin,producida
desdeafueradelPCporelusuarioaloprimirunatecla.Alleerlatecla,sereponea
ceroelvalordelabandera,detalmaneraquelaunidaddecomunicacinsepaqueya
leyeroneldatoqueellaaport.
Aesteprotocolo,realizadomanipulandoordenadamentelabanderadeDataReady,selo
conocecomoHandShaking(eningls:apretndemanos).
ElsaludooHandShakingverbalizadoseraalgoascomo:
"Hola,tengoundato"."Ah,unmomento,yalorecibo"."Listo,graciasyciao"."Ciao".
Las dificultades comienzan cuando el CPU no puede bloquearse esperando a que llegue
cada smbolo, porque eso lo pondra a trabajar ms o menos a la velocidad del
subsistemalento,enestecaso,elusuario.Unaalternativaeslograrqueelprograma
queelCPUvaaestarcorriendoentreletrayletra,secomportecomounaespeciede
CICLOdelongitudindefinidaque,entrelascosasquetienequerealizar,estlade
pasararevisarsillegonounaletra.
CuntotiempotieneelCPUparadarlavueltaypreguntarporunaletraalaentrada,
antesdequecomienceallegarOTRALETRA,porquesobrescribiraparcialototalmente
la letra anterior? Pues si el registro de entrada es un "Shift Register" que va
recibiendounoaunolosNbitsdecadaletra,elCPUtienequeatenderalperifrico
ANTESdequetranscurraUNTIEMPODEBITdecomunicaciones.As,llegaelltimobitde

126

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

unsmboloproducidoporelusuarioeneltecladoyseactivaelbitdeSTATUS,Data
Ready.ElCPUtienequeleerloyactuarANTESdequecomienceallegarelprimerbit
delsegundosmbolo.Siseestenunatransferenciacontinuadedatos,secalculael
tiemponecesariodereaccindelCPU,comoseloconoce,infiriendo,delavelocidadde
comunicacin, el tiempo de cada bit. Ese es la cota superior o lmite en tiempo que
puedepasarentreatencinyatencinalperifrico,paragarantizarquenosepierden
ningnsmbolorecibido.
Unamodificacinquehacemsllevaderalavidadelossistemasconsisteenagregarle
un Registro Adicional al Serializador de Entrada (el serializador que es el que va
recibiendounoaunolosbitsdelaletra,ycuandotieneNnormalmente8bitspara
nuestrosejemplos,siendo8elnmeromsempleadoenlaactualidadelcontroladorde
lainterfazlotransfiereaeseDataBuffer.AhoraelCPUtieneTODOUNTIEMPODEBYTE
TRANSMITIDO, entre atencin y atencin al perifrico. Como cada byte (8 bits) puede
durar 10 tiempos de bit en transmitirse, se ha disminuido en un orden de magnitud
(dividido por 10) el tiempo permitido al CPU para atender los smbolos. A esta
combinacin de serializador alimentando a otro registro, que es el registro que en
definitiva OPERA el CPU, se lo conoce como Double Buffer (porque hay 2 registros
involucrados,obuffers).
CuandolavelocidadconlaquelaunidaddecomunicacionesleentregalosdatosalCPU
enalgunasoportunidades,esmayordeltiempolibre,odeholgura,delprocesador,ste
seveenlanecesidaddeatenderlosdatosconmayoragilidad.Yparafacilitareste
intercambio, se invent el mecanismo conocido como INTERRUPCIONES, que consiste en
lograrqueelCPUrespondarpidamenteacadaletrapero,siporalgnmotivonotiene
tiempoparaprocesarlainformacindeentrada,tienequemoverladeldoublebuffera
lamemoria.
Cuandolamemoriadetrabajotieneunprincipioyunfin,comounatabla,selaconoce
comoBUFFERdeEntrada.DesdeluegopuedehaberBUFFERSdeSalidatambin(tablas).Si
lavelocidaddetransferenciadeinformacinesmuyelevada,porejemploenlaentrada,
seempleanDOSBUFFERS,yselosconmutadetalmaneradeestaradquiriendoinformacin
sobre un BUFFER, mientras se est procesando el otro. A esta tcnica se la conoce
tambin como DOUBLE BUFFERING, y se distingue de la anterior por la cantidad de
elementos de informacin que conforma cada buffer. En el caso mencionado antes, eran
solo dos elementos o registros: el serializador, y el registro buffer, propiamente
dicho. En este segundo caso (que desafortunadamente recibe el mismo nombre, Double
Buffer,oBuffering)eltamaodelbuffersuelesergrande,entre64bytesparacanales
decomunicacinmuyrpidos,hasta512bytesparaunidadesadaptadorasdediscos,que
cuandodicentransferirinformacinlohacendemaneramuyveloz.
Pero hay otra alternativa, frente al Double Buffering, que consiste en el empleo de
COLASoQUEUEs;algunasdeellasrealizadasaniveldecircuitosintegrados(FIFOs).
Unacolapuedeversecomounatabladetamaofijo,peroCIRCULAR,locualquieredecir
quesisevancolocandodatosenellaysellegaalfinal,elprximodatoSECOLOCAR
ALPRINCIPIOdelatablaotravez.Estoproducelailusindequeesareadememoria
es CIRCULAR, pues el final de la tabla est contiguo al principio, como si fuera un
anillo(ocrculo)quenotienefin.
El mayor uso de las Colas se consigue cuando el proceso Productor de datos puede
generar a veces, rfagas de informacin, como picos de transmisin, pero que
normalmenteestpordebajodeloquepodramosllamarComunicacinIninterrumpida,o

127

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

continua.Esasquelacomunicacinvaaunpasodado,perodeprontoseaceleraen
unarfagadeunaduracinacotada,inferioraXcaracteres.SiademselConsumidorva
extrayendoconciertaperiodicidadlosdatosdelacola,ycuandolohacelohacemuy
rpidamente(delamismacola),laColapresentalaimagenvirtualdequeesdemayor
capacidadoperativadesurealcapacidadfsica.
UnodelosaspectososcurosdelempleodeColaseselestablecimientodeltamaodelas
mismas,yaquesucapacidaddependedeladiferenciadevelocidadesentreProductory
Consumidor. Una alternativa consiste en simular la cola en el PC, alimentndola y
extrayendo informacin de ella al azar, e ir incrementando un contador que determine
cundo, al tratar de agregarse un elemento a la cola, sta estaba llena, lo cual
conformaunerror,ytambin,dependiendodelcaso,sisequisoretirarunelementode
informacindelacola,ynosepudodebidoaquestaseencontrabavaca.
UnaCola,pues,esunaEstructuradeDatosqueestmaterializadaenlamemoriacomo
unatabla,yempleavarioselementosaccesoriosparasucorrectaoperacin.
Se requiere una variable que determine el tamao definido para la cola, 'SIZE'(1) en
nuestradescripcin.(Nota:losnmerosentreparntesiscorrespondenacadaelemento
identificadodelamismamaneraenelprximodibujo)
Es cmodo tener un pointer que seale siempre a dnde comienza la tabla: BASE, que
apuntaa"BUF"(2).
Se necesita un apuntador que indique en cul posicin de la tabla se colocar la
prximaletraquellegueensecuencia,yhayaquealmacenarla.EsteeselPUTpointer,
osimplemente"PUT"(3).
Se necesita otro apuntador, al que le corresponde sealar cul es la letra que debe
salir en secuencia de la cola, cuando se haga una lectura de all. Este es el GET
pointer,osencillamente"GET"(4).
Es cmodo tener otro pointer que identifique el final de la tabla: LIMIT, y una
variable"N"(5),queindiquelacantidaddebytesquealmacenalaColaenuninstante
dado.Parallevarlapistadecuntosbytesestnalmacenadosenlacola,cadavezque
seincluyaunodebeincrementarseelcontador,yalmomentodeextraerundato,debe
decrementarse dicho valor. As, siempre "N"(5) contiene la cantidad de Smbolos
almacenadosenunmomentodeterminado.
En'C',unelementodeinformacincomoelqueacabamosdedescribirserepresentade
maneranaturalcomounaSTRUCT;lanuestrasera(tomadademisrutinasdeColaspara
elPC):
typedefstruct{
byte*put;/*n(5)*/
byte*get;/*(2)buf>++*/
wordn;/*|(1)|>(4)get*/
wordc;/*(3)put>|s|*/
byte*base;/*|i|*/
byte*limit;/*|z|*/
wordsize;/*|e|*/
}QUE;/*++*/

128

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

EnestadefinicindeQUEestnlosdosapuntadoresabyte:*puty*get;elcontadorde
elementosque,paraestaimplementacinesunwordn(16bits,conloquelacapacidad
mximadelascolasesde64Kbytes);losapuntadoresabyte,queindicanelcomienzoy
alfinaldelatabla:byte*baseybyte*limit;unaconstanteparacadacola,queessu
tamao:wordsize;yfinalmenteunavariableauxiliarparaalmacenarunsmbolodela
tablatemporalmente,wordc(esword,nobyte,porqueigualqueelsmboloEOFenla
libreraestndardeC,senecesitaunwordparaalmacenarlo).
Unailustracindelosrangosdevaloresquepuedenalcanzarlasdiferentesvariables,
yladefinicindecolallenayvacaeslasiguiente:
Sea 'size'(1) de 'buf'(2) igual a 5, como ejemplo. Los pointers 'put'(3) y 'get'(4)
slopuedentenerlosvalores:
buf,buf+1,buf+2,buf+3,buf+4;
esdecir,lospointersdebenpermanecerenelrango:
buf<=pointer<(buf+size),o,loqueeslomismo:
buf<=pointer<limit

'n'(5)puedevaler:
0(vaco),1,2,3,4and5(lleno).
Noteque'n'esUNSEMFOROqueimponelassiguientesreglasdetrfico:
NO'deQue'cuandonsea<=0
NO'enQue'cuandonsea>=size

Con estos antecedentes en mente, analicemos mi librera de colas para el HC9S08,


escritasenAssemblyLanguage:
25) BIBLIOTECA de COLAS: Que.inc

["Laboratorios\Lab3\SciComm\Que.inc"]
001;********************************************************************
002;Que.inc:QueueSupport(forSCI)
003;LuisG.UribeC.,C14M2007C15A09L08J09J14J2012(HCS08)M05M2013
004;S30N2013(defineQue&initQuenowbeginwithLowerCase)C18D2013
005;====================================================================
006;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
007;
008;defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG*
009;initQue:MACROname1,size2;==>>Use'initQue'in*ROMstartORG*
010;enQue:MACROname1;enQAccumulatorintoQue:'name1'
011;deQue:MACROname1;deQAccumulatorfromQue:'name1'
012;====================================================================
013;EXAMPLESOFUSE
014;...
015;GlobalVariables
016;ORGram

129

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

017;inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
018;outQ:defineQue5
019;...
020;
021;ORGrom
022;...
023;initQueinpQ,6;Usemacro'initQue'in'ORGrom'
024;initQueoutQ,5
025;
026;enQueinpQ
027;bcsfull_inpQ
028;...
029;deQueinpQ
030;bcsempty_inpQ
031;enQueoutQ
032;bcsfull_outQ
033;...
034;====================================================================
035;DATADEFINITION.
036;
037;NOTE:ThisisONEwaytoworkwith>>>STRUCTURES<<<inAssembler...
038;ReferencestointernalRAMstructpositionsaredoneviasymbols:
039;ThefollowingEQUsaredefinedtohelpusinlocatingthedifferent
040;..variablesusedinQueue'sstruct;i.e:
041;_QN:BYTE:unsignnumberofcharsstoredanytimeinoneQueue
042;_QPUT:WORD:pointerusedtostorethenextchar,vaenQue;
043;_QGET:WORD:pointertodeQueonechar.
044;_QSIZE:BYTE:staticspacereservedforQueue;
045;_QBASE:WORD:addressofthefirstchartobestoredinthe
046;..reservedmemoryofeachQueue;
047;_QLIMIT:WORD:lastelement'saddressinaQueue;usedinwrap
048;..aroundprocess,whenapointercrossestheborder
049;_QBUF:BYTES:herebeginsRAMspaceforcharacterstobestored
050_QN:EQU0;BYTE:databytescounterN
051_QPUT:EQU1;WORD:pointerforstoringdataintoQueue
052_QGET:EQU3;WORD:pointerforgettingdatafromQueue
053_QSIZE:EQU5;BYTE:sizeof
054_QBASE:EQU6;WORD:baseaddressofQueuestruc
055_QLIMIT:EQU8;WORD:lastaddressofbuffer
056_QBUF:EQU10;BYTES:reserve'size'databytes

057;====================================================================
058;"defineQue"isusedwith1parameter:SIZEoftheQueue.
059;..defineQueRESERVESRAMspace,and*MUST*beusedinRAMspaceORG.
060;===>>^^^^<<<===
061;Touse"defineQue",you*MUST*beginitwithaLABEL:This*IS*
062;..theNAMEofyourQUEUE;i.e:
063;
064;**********************
065;inpQ:defineQue6*
066;**********************
067;NOTE:Itisclevertodefinedatabytesramspace,thelast...

130

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

068defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG**
069;===>>===>===>===>===>===>>^^^^^^^^<<<===
070DS_QPUT_QN;n:databytescounterN
071DS_QGET_QPUT;put:ptrforSTOREdataintoQueue
072DS_QSIZE_QGET;get:ptrforGETdatafromQueue
073DS_QBASE_QSIZE;size:sizeof
074DS_QLIMIT_QBASE;base:baseaddressofQueuestruc
075DS_QBUF_QLIMIT;limit:lastaddressofbuffer
076DS\1;buf:reserve'size'databytes
077ENDM

078;
079;"initQue"isusedwith2parameters:NAMEoftheQueue,ANDSIZE.
080;initQueSTORESinformationintheQueue'sRAMspace,and
081;..*MUST*beusedin**ROMspaceORG**
082;==>>^^^^<<<===
083;ForinitQueyoumustwriteSAMEparametersusedondefineQue;i.e:
084;
085;******************
086;initQueinpQ,6*'inpQ'wasQueue'sNAMEindefineQue;sizewas6
087;******************
088;
089;ALLreferencestointernalRAMpositionsaredoneviathesymbols
090;.._QN,_QPUT,_QGET,_QSIZE,_QBASE,_QLIMITand_QBUF
091;..NotethatthisisONEwaytoworkwithSTRUCTURESinassembler...

092initQue:MACROname1,size2;==>>Use'initQue'in*ROMstartORG*
093;==>>====>====>======>>^^^^^^^^<<==
094clra;markQueueasempty(n=0)
095sta(\1+_QN);'sta',not'clrOP'causeOPcould
096;..residein16bitaddressspace
097ldhx#(\1+_QBUF)
098sthx(\1+_QBASE)
099sthx(\1+_QPUT)
100sthx(\1+_QGET)
101lda#\2
102sta(\1+_QSIZE)
103aix#\2
104sthx(\1+_QLIMIT)
105ENDM
106;
107;"enQue"storesthecontentofACCumulatorinthedesignatedQUEUE
108;
109;********************************************************************
110;*Youmayprogramotherusefullmacrossuchas:enQueKfordealing*
111;*..withconstants,enQueVtoenQuevariables,etcIt'suptoyou*
112;********************************************************************
113;
114;IfthereisNOspaceforstoringsomecharacter,themacrosignals
115;..itbysettingtheCbitonCCR,sotheinvokingprogrammay
116;..knowthattheQueueisfull,andtakeactions...
117;

131

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

118;NOTE:enQueisNOTablockingaction...
119;
120;******************
121;enQueoutQ;*enQAccumulatorintoQueuenamedoutQ
122;******************
123enQue:MACROname1;enQAccumulatorINTOQueue:'name1'
124psha
125lda(\1+_QN);Verifythatthereisroom(n<SIZE)
126cmp(\1+_QSIZE)
127pula
128blo\@ok
129sec;c=1signalerror:Queuefull
130bra\@exitQ
131\@ok:ldhx(\1+_QPUT);*put++=accumulator
132sta,x;..
133aix#1;..
134sthx(\1+_QPUT);..
135cphx(\1+_QLIMIT);..
136blo\@incn;putpointerinsideque?ok
137ldhx(\1+_QBASE);else:rollover:reasignputtoBASE
138sthx(\1+_QPUT);..
139\@incn:
140clc;c=0:enQuewassuccesfull
141ldhx#(\1+_QN);n++.ThisistheLASTthingtobe
142inc,x;<<<<<<..done:'n'ISthesemaphore
143\@exitQ:
144ENDM
145;
146;"deQue"retreivesdatafromthedesignatedQueueandstoresitin
147;..theACCumulator.
148;
149;********************************************************************
150;*Youmayprogramothermacros,suchas:deQueVforretreive*
151;*..dataandstoreitonvariables,etc.Itisuptoyou*
152;********************************************************************
153;
154;IfthereisNOdataforretrieving,themacrosignalsitbySETting
155;..theCbitonCCR,sotheinvokingprogrammayknowthattheQueue
156;..isempty,andtakeactions...
157;
158;NOTE:deQueisNOTablockingaction...
159;
160;******************
161;deQueinpQ;*deQuefromQueuenamedinpQintoAccumulator
162;******************

163deQue:MACROname1;deQ:AccumulatorFROMQueue:'name1'
164lda(\1+_QN);Verifythatqueisnotempty(n>0)
165bne\@ok
166sec;c=1signalerror:Queuefull
167bra\@exitQ
168\@ok:ldhx(\1+_QGET);accumulator=*get++

132

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

169lda,x;..
170aix#1;..
171sthx(\1+_QGET);..
172cphx(\1+_QLIMIT);..
173blo\@decn;getpointerinsideque?ok
174ldhx(\1+_QBASE);else:rollover:reasigngettoBASE
175sthx(\1+_QGET);..
176\@decn:
177clc;c=0:enQuewassuccesfull
178ldhx#(\1+_QN);n.ThisistheLASTthingtobe
179dec,x;<<<<<<..done:'n'ISthesemaphore
180\@exitQ:
181ENDM

COMENTARIOS a ["Laboratorios\Lab3\SciComm\Que.inc"]:

Seleofrecenalusuario4funcionesprincipales:

ParacadaColaseprecisahacerunadefinicinANTESdeinvocarcualquierotrafuncin
relacionada:

008;defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG*

Ejemplo:

inpQ:defineQue6

SedefineunaColade6elementos(enestaimplementacintodosloselementossonBYTES
pero, desde luego, usted puede emplear otros valores, como enteros, Longs, y otros
TiposdeDatos.Peroestoespreferible(comocasitodo)programarloenC.

NOTAIMPORTANTE:

'defineQue'debeusarsehabiendopreviamenteabiertounDATASECTION:'ORGram',porque
'defineQue'reservaespacioenRAMparalosapuntadoresydemsvariablesrelacionadas,
ascomotambinparalatablacircularpropiamentedicha.

Para cada cola se precisa, adems, inicializar apropiadamente sus apuntadoras y


variablesrelacionadas;estosehacecon:

Ejemplo:

initQueinpQ,6

NOTAIMPORTANTE:

'InitQue' slo debe emplearse estando en CODE SECTION, es decir, habiendo hecho
previamenteun'ORGrom',yaqueeslapartequegeneracdigoajustadoacadacolaen
particular.

133

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Finalmenteestnlasfuncionesdeusorutinario,paraalmacenaryextraerdatosdeuna
cola,lasMacrosenQueydeQue:

010;enQue:MACROname1;enQAccumulatorintoQue:'name1'
011;deQue:MACROname1;deQAccumulatorfromQue:'name1'

Cada Macro hace uso del dato que est previamente guardado en el Acumulador. A
continuacin,unejemploquecubretodoloanterior:

ParadefinirlasColas,hayqueabrirunDATASECTION(orgRAM)yluegollamarlaMacro
defineQue,tantasvecescomoColasquierandefinirse:

015;GlobalVariables
016;ORGram
017;inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
018;outQ:defineQue5

NotequeelNOMBREdelascolas,inpQyoutQ,sonETIQUETASdelaMacrodefineQue.

Cuandovanainicializarselascolas,hayquedefinirunCODESECTION(orgROM):

019;...
021;ORGrom
022;...
023;initQueinpQ,6;Usemacro'initQue'in'ORGrom'
024;initQueoutQ,5

NotequeelnombredelasColasNOesunnuevo"Label",sinoquelasetiquetasquese
emplearonenlaDefinicindelasColas,seusanahoracomoPARMETROSdelasmacrosde
Inicializacin:inpQyoutQ.

Elejemploencolaunchar,almacenadoenelAcumulador,enlacoladeentrada,inpQ;
msadelante,otraseccindelcdigo(seguramenteunarutinaquetransmitelosdatos
que se han encolado), saca elementos almacenados, posiblemente los preprocesa y,
finalmente,losencolaenoutQparaque,probablemente,larutinadeinterrupcionesque
seencargadetransmitirinformacin,laenvealPC,porejemplo.

025;
026;enQueinpQ
027;bcsfull_inpQ
028;...
029;deQueinpQ
030;bcsempty_inpQ
031;enQueoutQ
032;bcsfull_outQ
033;...

"STRUCT" in ASSEMBLY LANGUAGE


Primerohayquevolveramirarloselementosquecomponenesteelementodeinformacin,
porquenotodossuscomponentessonexactamentecomoenelejemploenC.Lostamaosen
nuestraimplementacinactualson:

134

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

041;_QN:BYTE:unsignnumberofcharsstoredanytimeinoneQueue

Fjensequeenestaimplementacin,unaColapuedeidentificarmximo256caracteres,
pues'N'midesolounbyte.

042 ; _QPUT: WORD: pointer used to store the next char, via enQue; 043 ; _QGET:
WORD:pointertodeQueonechar.

044;_QSIZE:BYTE:staticspacereservedforQueue;

Aqu,denuevo,eltamaonocorrespondealquepuededefinirseenunentero,sinoen
unbyte.

045 ; _QBASE: WORD: address of the first char to be stored in the 046 ;
..reserved memory of each Queue; 047 ; _QLIMIT: WORD: last element's address in a
Queue;usedinwrap048;..aroundprocess,whenapointercrossesthe
border049;_QBUF:BYTES:herebeginsRAMspaceforcharacterstobestored

Conestasdefinicionesconcretas,definimosahoraelvalordecadasmbolo,utilizando
lapseudoinstruccinEQU:

050_QN:EQU0;BYTE:databytescounterN

_QNrepresentaunOffset,odesplazamientode0,ennuestra'STRUCT'.

Como_QNmideunBYTE(es'N',elcontadordebytesquehayenunmomentodeterminado
enlaCola),ytodosemideenBytes,elsiguienteelementoestUN(1)BYTEdespusde
_QN;poresoelEQU1:

051_QPUT:EQU1;WORD:pointerforstoringdataintoQueue
_QPUT,comoesunapuntador,tienequemedir16bits(DOS[2]bytes),puesenelHC9S08
todas las direcciones deben ser capaces de discriminar entre 65536 posiciones de
memoria. Por eso, elsiguiente elemento est separadode _QPUT por DOS (2)unidades.
ComoyallevbamosUNO(1),elsiguientees1+2=3:

052_QGET:EQU3;WORD:pointerforgettingdatafromQueue

Igualocurreconelsiguiente,queseseparaporDOS(2)delanterior,y3+2=5:

053_QSIZE:EQU5;BYTE:sizeof

_QSIZE mide UN (1) byte, as que el prximo, _QBASE, se separa de ste por UNA (1)
posicin,loqueda:5+1=6:

054_QBASE:EQU6;WORD:baseaddressofQueuestruc

ElprximoseseparaporDOS(2),queesloquemide_QBASE,dando6+2=8:

055_QLIMIT:EQU8;WORD:lastaddressofbuffer

135

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

y, finalmente, el buffer COMIENZA separado por DOS (2), que es lo que mide _QLIMIT,
dando8+2=10:

056_QBUF:EQU10;BYTES:reserve'size'databytes

OBSERVACINNOTABLE:

Laposicinenquecoloquelcomienzodelatabla,_QBUF,ESLAMEJORPOSICINPARA
ALOJAR LA TABLA en esta definicin. Qu pasara si la hubiramos incluido entre los
smbolos_QGETy_QSIZE,oentreotroscualesquiera?PINSELO!"Itisclevertodefine
databytesramspace,thelast..."

HechastodasestasparametrizacionesselasempleaparafinalmenteDEFINIRLACOLAEN
RAM,mediantela:

MACRODEFINEQUE:

068defineQue:MACROsize1;===>>Use'defineQue'in**RAMstartORG**
069;===>>===>===>===>===>===>>^^^^^^^^<<<===
070DS_QPUT_QN;n:databytescounterN
071DS_QGET_QPUT;put:ptrforSTOREdataintoQueue
072DS_QSIZE_QGET;get:ptrforGETdatafromQueue
073DS_QBASE_QSIZE;size:sizeof
074DS_QLIMIT_QBASE;base:baseaddressofQueuestruc
075DS_QBUF_QLIMIT;limit:lastaddressofbuffer
076DS\1;buf:reserve'size'databytes

Fjense cmo cada variable usa el nmero de bytes apropiado, empleando DS (Data
Storage)ylacantidadqueresultadecalcularelnmerodebytesqueresultahaciendo:
siguientesmbolomenosactual,comoen:

070DS_QPUT_QN;n:databytescounterN
Sehabranpodidocolocarestascantidadesamano,perometomlamolestiadehacerlo
medianteparmetrosquemepermiten,siquierocambiaralgocomoeltamaodelacola
(peroNOqueremos)paraquefueradehasta64Kbytes,conslomodificarunsmbolo(o
dos...)elrestosereacomodaautomticamente.

Es EVIDENTE que en una mquina tan pequea, NO vamos a usar colas de tamao mayor a
256,queademssonsuficientesenMUCHOScasos,inclusoparamquinasmsgrandes.As
queesteejemplosloestcodificadoas,paraqueustedesveanlamaneraprofesional
dehacerlo:PARAMETRIZADO.

As,esperoquehayanaprendidoLAMANERAdetrabajarestructurasenAssemblyLanguage.

MACROINITQUE:

092initQue:MACROname1,size2;==>>Use'initQue'in*ROMstartORG*
094clra;markQueueasempty(n=0)
095sta(\1+_QN);'sta',not'clrOP'causeOPcould
096;..residein16bitaddressspace

136

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

CuandosecomienzaatrabajarconunaCola,losapuntadoresalaBASEytambinlosde
PUTyGETdebensealartodosalPRINCIPIODELATABLACircular.Notequelaexpresin
#(\1 + _QBUF) representa: una CONSTANTE (#), igual a la base de la Estructura de la
Cola ("\1", el primer parmetro) MS el desplazamiento a dondese comienza la tabla:
_QBUF)

097ldhx#(\1+_QBUF)
098sthx(\1+_QBASE)
099sthx(\1+_QPUT)
100sthx(\1+_QGET)

La inicializacin de los otros dos parmetros es trivial (o no? Si no est claro,


escriba TODAS las definiciones, y ver lo que hace el AIX #\2; verifique lo que se
cargantesenelregistrondiceH:X):

101lda#\2
102sta(\1+_QSIZE)
.........
103aix#\2
104sthx(\1+_QLIMIT)

Finalmente,revisemoscmosecodificaronlasMacrosparaelmanejonormaldelaColas:
enQueydeQue(encolarydecolar...).

"enQue":AlmacenaelcontenidodelAcumuladorenlaColarequerida:
Elproblemacuandosevaaencolaralgo,esqueNOhayaespaciopararecibirunnuevo
valor.Sifueraas,laMacroloSEALAcolocandoenUNOelbitdecarry,C,enelCCR;
as, el programa que invoca la Macro puede saber si la cola estaba llena, y tomar
acciones. Ntese que la manera como codifiqu la Macro enQue NO ES DE MANERA
BLOQUEADORA,locualresultamuyconveniente...Ustedsimplementeencolaalgoyluego
preguntasisehizobien,mirandoelbitdeCarry,C.Ahustedtomaladecisinque
corresponda.

123enQue:MACROname1;enQAccumulatorINTOQueue:'name1'

GuardaelvalordelAcumulador,enelStack:

124psha

Verificaquehayaespacio(quensea<SIZE):

125lda(\1+_QN);Verifythatthereisroom(n<SIZE)
126cmp(\1+_QSIZE)
127pula
128blo\@ok

SiShayespacioenlaCola,continuaenlaetiquetamarcadacomo:\@ok;deNOhaber
espacio,seactivalabanderaC(Carry),ytermina:

129sec;c=1signalerror:Queuefull
130bra\@exitQ

137

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Habiendo verificado que S hay espacio, carga la direccin para ENCOLAR (segn el
pointerPUT),enelregistrondiceH:X,yusandoeldireccionamientoindexadoalmacena
elnuevodato,tomndolodelAcumulador:

131\@ok:ldhx(\1+_QPUT);*put++=accumulator
132sta,x;..

Una vez guardado el dato, se incrementa el apuntador (aix #1), para que seale a la
prximaposicinquerecibirundato,yseguardaesenuevovalor,incrementado,enla
posicindememoriaquereservadaparaalmacenareseapuntador:

133aix#1;..
134sthx(\1+_QPUT);..

ComparaeseNUEVOvalor,paraversiseapuntafueradelreaasignada:

135cphx(\1+_QLIMIT);..
136blo\@incn;putpointerinsideque?OK

Si el apuntador contiene una direccin que queda FUERA del rea asignada, hay que
reiniciarlo,paraqueapuntealaBASE(ROLLOVER;estemecanismoeselquelacolasea
CIRCULAR):

137ldhx(\1+_QBASE);else:rollover:reasignputtoBASE
138sthx(\1+_QPUT);..

Sielapuntadorsealacorrectamentedentrodelreaasignada,seborralabanderaC,
Carry,paraindicarasqueTODOESTBIEN:

139\@incn:
140clc;c=0:enQuewassuccesfull

LuegovienelapartequizsMSDIFCILDECOMPRENDER,CONCEPTUALMENTE:

Como"N"eselMUTEX(semforobinario),

===lo>>>LTIMO<<<quehayquehaceralalmacenaralgoenlaColaes>>>INCREMENTAR
"N"<<<;

hacerlo ANTES puede deshacer la magia del semforo, que probablemente ya no nos
resguardecontrainconsistencias.

Supongamos,porejemplo,quelaColaestVACAy"Main"estuvieraenelprocesodel
"enQue",tratandodeENCOLARunsmbolo.SialgunarutinairrumpetratandodeDECOLAR
algopara,porejemplo,transmitirlo,y"N"leindicaqueShayinformacinenlaCola
(porque se increment "N", por ejemplo, al principio de la Macro, ANTES de que en
realidadsehubieraalmacenadonada),puesel"deQue"delaISRLEERAesainformacin,
QUENOEXISTE!

138

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

CAOSgarantizado...

Esto es slo un DETALLE, pero es... FUNDAMENTAL! No es SENCILLO de analizar, y es


MUCHOMSDIFCILDE...CODIFICAR.

141ldhx#(\1+_QN);n++.ThisistheLASTthingtobe
142inc,x;<<<<<<..done:'n'ISthesemaphore

La explicacin sobre "deQue" resulta algo as como el DUAL de la que acabo de hacer
sobre "enQue", y por eso no voy a presentar aqu ms comentarios. Se sigue la misma
normaconrelacinalbitC:Carry,quesiestEN0representaquetodofueBIEN,yEN
1,indicaquehubounERROR(fueaextraersealgodelacola,ystaestabaVACA...).

Elproblemaenestaparteessimilaralanterior:Supongamos,porejemplo,quelaCola
est LLENA y "Main" estuviera en el proceso del "deQue", tratando de DECOLAR un
smbolo.SialgunarutinairrumpetratandodeENCOLARalgo,porejemploloqueacabade
leer del receptor, y "N" le indica que S hay espacio en la Cola (porque Main
increment "N", por ejemplo, al principio de la Macro deQue, ANTES de en realidad
haberloledo(cambielordenqueenrealidadhayqueseguir),puesel"enQue"dela
ISRPERMITIRAALMACENARSUinformacin,ENUNAPOSICINQUEANNOHASIDOLEDAPOR
MAIN!

CAOSgarantizadodenuevo...

Este es otro DETALLE pequeo pero igualmente... FUNDAMENTAL! Complicado de analizar


y...MUCHOMSDIFCILDECODIFICAR.

Verifique con MUCHO detenimiento en el cdigo, que tampoco aqu existe JAMS un
comportamiento indebido, como que la rutina de interrupciones almacene algo sin que
hayaespaciodndecolocarlo...
NOTA:LacodificacindelbitdeCarry,C,seusaenellenguaje"C"desdeelcomienzo
de los tiempos, para retornar CERO si una funcin S oper bien, y UNO si N oper
normalmente.Assecomportan,porejemplo,lasfuncionesdebajoniveldelaseccin
correspondientea<io.h>.

EsascosasustedhadebidoaprenderlasensuscursosdeProgramacin.Sinofueas,lo
estafaron.

Cuandoterminedeponderarlanitidezdelcdigo,tratedehacernuevamenteunExamen
deConciencia,ydigasiustedhubierapodidopensarentodalacomplejidadsubyacente
en las interacciones que pueden ocurrir asincrnicamente, entre un Main tratando de
Encolar,yunarutinadeinterrupcionestratandodeDecolar...oviceversa,SINQUESE
PUEDAJAMSEXTRAERDELACOLAALGOQUENOHAY,OENCOLARALGOENUNAPOSICINDELA
QUEANNOSEHADESOCUPADO!

26) Programa Elemental para Probar la Librera de COLAS


Programamuysencillo,queencolaen"inpQ"unasecuenciadecaracteresconsecutivos,
comenzandoconlaletra'A',yfinalizacuando"inpQ"sellena.Acontinuacinprocede
a extraerlos de "inpQ" y los va trasladando a "outQ", hasta que "inpQ" se vace o

139

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

"outQ" se llene, lo primero que ocurra. El comportamiento debe verificarse con el


Debugger,siguiendopasoapasoelprograma.

["Laboratorios\Lab3\SciComm\4quetst.asm"]
01;********************************************************************
02;Programa4QueTst.asm:TestQueSupport(forSCI)
03;LuisG.UribeC.,M13M2007C15A09L08J09S16J2012(HCS08)
04;
05;Seeinthisprogram:TheuseofQue.inc,defineQue,initQue,enQue
06;..anddeQue.TrayandcodetheprogramusingRCVinterrupts,using
07;..a'Queue'fortemporallystoringtheincomingdata.
08;YoumustbecarefullyandnotexceedthefreeRAMonthechip...
09;
10;
11;Includefilesthatdonotdefineram
12;
13;CHECKLIST:Conservethisorder,andtherelativepositionof:
14;..'derivative.inc'and'Que.inc'
15;
16;Includefilesthatdoesnotdefineram
17NOLIST
18INCLUDE'derivative.inc'
19INCLUDE'Que.inc';<<<===Que.incfiledoesNOTuseRAM
20LIST;..storage,andTHISisit'splace
21;
22;2)DEFINES

23rom:SETROMStart;$2080
24ram:SETZ_RAMStart;$80
25initStack:EQURAMEnd+1;$1800=$17FF+1.Stackbeginson$17FF
26COP_Disable:EQU$42
27;====================================================================
28;3)GlobalVariables
29ORGram

30inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
31outQ:defineQue5
32;********************************************************************
33;4)MAINPROGRAMHEADER:
34ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
35ORGrom

36Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
37staSOPT1;..SystemOptions1
38ldhx#initStack;SetupSP
39txs;...
40;====================================================================
41initQueinpQ,6;Usemacro'InitQue'in'ORGrom'
42initQueoutQ,5

43lda#'A'
44cont:enQueinpQ

140

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

45bcsfull
46inca
47bracont

48full:
49cont2:deQueinpQ
50bcsempty
51enQueoutQ
52bcsfull2
53bracont2
54empty:
55full2:bra*
56;
57nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
58;This'nop'MAYberemovedforCW6.3...
59;
60;InterruptVectors

61ORGVreset
62DC.WMain;RESET.Maximumpriority.Asynch.
63END

COMENTARIOS a ["Laboratorios\Lab3\SciComm\4quetst.asm"]
Elqueestudiaestetextoharbienenlarecomendacindecodificarelprogramausando
interrupcionesRCVyuna'Queue'paraalmacenartemporalmentelainformacinquellega.

Comosiempre,vienen:

11;Includefilesthatdonotdefineram
EstoesIMPORTANTE:

13;CHECKLIST:ConservethisORDER,andtherelativepositionof:
14;..'derivative.inc'and'Que.inc'

Esteejercicioslotienelassiguientes(Global)VariablesenRAM(defineQue).Usted
DEBE jugar y cambiar los tamaos de cada cola para ver cmo se modifica el
comportamientodelprograma.

29ORGram
30inpQ:defineQue6;Usemacro'defineQue'in'ORGram'
31outQ:defineQue5

DespusdelaDEFINICIN,alcomienzosehacelainicializacin:

41initQueinpQ,6;Usemacro'InitQue'in'ORGrom'
42initQueoutQ,5

Elprogramaenviarletrasconsecutivas,comenzandoenla'A',hastaquelacola"inpQ"
sellene.

Inicializaelacumulador:

141

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

43lda#'A'

ElcicloqueencolahastaqueinpQsellene:
44cont:enQueinpQ
45bcsfull

Incrementarunaletraproducelasiguiente:La'A'+1,produce'B':
46inca
47bracont

Cuando la cola "inpQ"se llenese extraenotra vez de"inpQ" yse los traslada a la
cola "outQ", hasta que "inpQ" se vace o hasta que "outQ" se llene. Verificar el
comportamientodelprogramaconelDebugger,siguindolopasoapaso.

48full:
49cont2:deQueinpQ
50bcsempty
51enQueoutQ
52bcsfull2
53bracont2

SefinalizaconlaconsabidaimitacindelHALT:

55full2:bra*

La modificacin que se sugiere hacer al programa consiste en colocar una Cola para
recibirporinterrupcionesloquellegadelPC.Larutinadeinterrupciones(alacual
se llega luego de las habilitaciones respectivas, y porque un smbolo lleg por la
lnea de comunicaciones, y as gener una interrupcin de RCV), toma la letra, la
ENCOLAysedevuelve(RTI).

Elprogramaprincipal,Main,selapasaleyendodelacolamientrasstaseencuentra
vaca; y, cuando llega a encontrarla NO vaca, DECOLA una letra y la devuelve al PC
(INCREMENTADAcomoyavimos),usandolaMacroPUTCHAR;luegoregresaalcicloinfinito.

AGREGO:Cuandoesofuncione,tratedecolocardos(2)colas,unapararecibirloque
llegadelPC,comoacabamosdever,yotraparaalmacenarloquesevaatransmitir;es
decir, la parte de cdigo que antes haca PUTCHAR, ahora hace "enQ outQ" y, LUEGO,
HABILITALASINTERRUPCIONESdesalida.

Larutinadeinterrupcionesdesalida,alacualsellegacuandosepueda,siesqueel
perifricotransmisorestdisponible(previasTODASlashabilitacionesnecesarias)...
DESENCOLA ("deQ outQ") si ve que NO ESTABA VACA transmite va PUTCHAR. Si la cola
estabavaca,larutinadetransmisinseAUTODESHABILITAparainterrupciones.ESTOES
IMPORTANTE!

Yenesasselapasan.

Laideaesqueustedaprendaausarlosmecanismosderecepcinytransmisin,tantode
manera programada como por interrupciones, usando como vehculo para aprender, las
comunicacionesserialesconelPC.As,estarpreparadoparasusproyectos...hoy,y
luegocomograduado.

142

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMUNICACIONES SERIALES

ESTEESELCULMENDELAPRESENTACIN;AQUCONFLUYENTODASLASTCNICASAPRENDIDAS;el
perifricodecomunicacionesnoesTANsimpledeestudiarpero,desdeluego,esmucho
ms sencillo que los stacks TCP/IP y Bluethoot, o algunos otros perifricos de
comunicacionessincrnicas,oelI2CyelSPI(SerialPeripheralInterface,withfull
duplex or singlewire bidirectional; doublebuffered transmit and receive; master or
slavemode;MSBfirstorLSBfirstshifting...)

EsteNOESUNTRATADODECOMUNICACIONESSERIALES.Ellectorestavisadodequedebe
revisar documentos publicados en relacin al tema. Yo mismo inclu el PDF:
"SerialComm16F84A(UribeChap14RS232)"enlaPginademicursoenAsignaturasdelaUSB.
YenelInternethaymultituddedocumentosrelacionados.

Usted tiene que aprender por su cuenta, en otra parte, cules son los voltajes
empleadosenlastransaccionesRS232F;lasvelocidades;ladistanciadeloscablesy
el tipo, los conectores; el nombre y significado de las seales como DTR, DSR, RTS,
CLS, Carrier Detect, TX, RX, Modem, Null Modem, dnde van los conectores hembra, y
donde los conectores macho; Gender Exchanger; lo que es comunicacin Full y Half
Duplex; Simplex. Start bit, Stop bit, tcnicas de lectura sobre la seal de entrada
paragarantizar5%deholguraenelosciladorlocalderecepcin,etc.

Tienequeleeralgntextoparaesto,comoyadije.

27) LIBRERA de COMUNICACIONES SERIALES: SciComm.inc


Repitomiobjetivoprimordial:PresentarlaMetodologadeProgramacinquedefinelo
quevaacodificarse,deforma"TopDownDesign",ylamaterializacindelsoftwarede
manera "ButtomUp". Observen y evalen primordialmente, en esta biblioteca que les
obsequio,elusodeesastcnicasdediseoyprogramacin.

["Laboratorios\Lab3\SciComm\SciComm.inc"]
001;********************************************************************
002;SciComm.inc:SCIComm.SupportM28E2014
003;LuisG.UribeC.,D11M2007L12M07J16A09L08J09
004;..S16J2012(HCS08)D24J2012M26F2013J12D2013(putcX)C18D2013
005;J12D2013:Modified'putcX'toenableanypossiblefollowing'BEQ'
006;M10D2013:Changed'XmtRcvEnable'to'XmtRcvActivate'
007;M26F2013:Fixed:IncludeCommasinListofALLMacros(comments!)
008;J03E2013:ListALLMacros,forreference,inthisheader...AddresS
009;
010;**REFERto>>>>>02MC9S08QE128RM(ReferenceManual)U.pdf<<<<<**
012;====================================================================
013;THEFOLLOWINGMACROSAREDEFINEDINTHISLIBRARY
014;
015;SCI9600N8:MACRO;ProgramSCI@9600,8,N,1
016;
017;getchar:MACRO;MAYrearmRcvinterrupts,insideISR
018;getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++
019;

143

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

020;putchar:MACRO;MAYrearmXmtinterrupts,insideISR
021;putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
022;putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
023;
024;RcvChar:MACRO
025;XmtChar:MACRO
026;
027;XmtRcvActivate:MACRO
028;
029;AncillaryMacros
030;
031;IfRcvRdy:MACRObrAddressIfReady1
032;IfXmtRdy:MACRObrAddressIfReady1
033;
034;XmtIntEn:MACRO
035;XmtIntDsb:MACRO
036;
037;RcvIntEn:MACRO
038;RcvIntDsb:MACRO
039;
040;ComIntEn:MACRO;InterruptEnableforCommunications
041;
042;
043;*TODO*:DefineIfNotRcvRdy,IfNotXmtRdy,IfNotRcvRdyS,IfNotXmtRdyS
044;..(cfr.timers8)ifyoueverneedthem.
045;CREATEkbhit,Nkbhit&equivalentsforoutput.getcvar
046;====================================================================
047;DEFINEREGISTERS:(in'MC9S08QE128.inc'),ANDREQUIREDBITS
048;..(here),forSCISerialCommunicationsInterface

049;********************************************************************
050;SCI1BD:EQU$0020;BaudeRateregister
051;LOOPMODE!!!

052Bauds9600Value:EQU$001A;16bit:4000000/(16*9600)=26.04=0x1A
053;
054;SCI1D:EQU$27
055;>>>>>>ALIAS<<<<<<(Othernamesforsameaddress.BECAREFULL!)

056XMTBUF:EQUSCI1D;TransmiterBuffer
057RCVBUF:EQUSCI1D;ReceiverBuffer
058;
059;SCI1C2:EQU$23
060;>>>>>>ALIAS<<<<<<(Othernamesforsameaddress.BECAREFULL!)

061XMTCTRLREG:EQUSCI1C2
062RCVCTRLREG:EQUSCI1C2

063XMTEN:EQUmSCI1C2_TE;TE:TransmiterEnable%00001000
064XMTIEN:EQUmSCI1C2_TIE;TIE:XmtINTEnable%10000000
065XMTIEN.bit:EQUSCI1C2_TIE;7

144

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

066RCVEN:EQUmSCI1C2_RE;RE:ReceiverEnable%00000100
067RCVIEN:EQUmSCI1C2_RIE;RIE:RcvINTEnable%00100000
068RCVIEN.bit:EQUSCI1C2_RIE;5

069XmtRcvEnab:EQU(XMTEN|RCVEN);EnableBOTHdevices%00001100
070;====================================================================
071;SCI1S1:EQU$24
072;>>>>>>ALIAS<<<<<<(OthernamesfortheSAMEADDRESS.BECAREFULL!)

073XMTSTATREG:EQUSCI1S1
074RCVSTATREG:EQUSCI1S1
075;Relevantbits:

076XMTRDY:EQUmSCI1S1_TDRE;TransmiterDataRegisterEmpty
077XMTRDY.bit:EQUSCI1S1_TDRE;7(mSCI1S1_TDRE:%10000000)

078RCVRDY:EQUmSCI1S1_RDRF;ReceiveDataRegisterFull
079RCVRDY.bit:EQUSCI1S1_RDRF;5(mSCI1S1_RDRF:%00100000)

080XMTEMPTY:EQUmSCI1S1_TC;TransmissionCompleteFlag
081XMTEMPTY.bit:EQUSCI1S1_TC;6(mSCI1S1_TC:%01000000):last!
082;
083;Receiver:
084OVERRUNERR:EQUmSCI1S1_OR;OR:Overrun%00001000
085NOISERR:EQUmSCI1S1_NF;NF:NoiseFlag%00000100
086FRAMERR:EQUmSCI1S1_FE;FE:FramingError%00000010
087PARERR:EQUmSCI1S1_PF;PE:ParityError%00000001

088RCVErrs:EQU(OVERRUNERR|NOISERR|FRAMERR|PARERR)
089;********************************************************************
090;MACRODEFINITIONS
091;NOTE:Accumulator,H:X,CCRareNOTpreservedthroughComm.Macros

092;
093;NoneedforpreviousenabledSCIperipherals
094SCI9600N8:MACRO;ProgramSCI@9600,8,N
095ldhx#Bauds9600Value;program9600bpsvalue
096sthxSCI1BD;..
097ENDM
098;
099XmtRcvActivate:MACRO
100mov#XmtRcvEnab,SCI1C2;ACTIVATEBOTHunits:xmt&rcv
101ENDM
102;====================================================================
103IfRcvRdy:MACRObrAddressIfReady1
104brsetRCVRDY.bit,RCVSTATREG,\1
105ENDM
106;
107getchar:MACRO;MAYrearmRcvinterrupts,insideISR
108brclrRCVRDY.bit,RCVSTATREG,*;rearm..
109ldaRCVBUF;..rearm
110ENDM

145

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

111;
112getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++
113ldhx\1
114brclrRCVRDY.bit,RCVSTATREG,*;rearm..
115movRCVBUF,x+;..rearm
116tpa;saveCCRtoenableanyfollowingBEQ
117sthx\1
118tap;..restoreCCR:enablefollowingBEQ
119ENDM
120;
121RcvChar:MACRO
122ldaRCVBUF
123ENDM
124;====================================================================
125IfXmtRdy:MACRObrAddressIfReady1
126brsetXMTRDY.bit,XMTSTATREG,\1
127ENDM
128;
129putchar:MACRO;MAYrearmXmtinterrupts,insideISR
130brclrXMTRDY.bit,XMTSTATREG,*;rearm..
131staXMTBUF;..rearm
132ENDM
133;
134putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
135lda\1
136brclrXMTRDY.bit,XMTSTATREG,*;rearm..
137staXMTBUF;..rearm
138ENDM
139;
140putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
141ldhx\1
142brclrXMTRDY.bit,XMTSTATREG,*;rearm..
143movx+,XMTBUF;..rearm
144tpa;saveCCRtoenableanyfollowingBEQ
145sthx\1
146tap;..restoreCCR:enablefollowingBEQ
147ENDM
148;
149XmtChar:MACRO
150staXMTBUF
151ENDM
152;====================================================================
153XmtIntEn:MACRO
154bsetXMTIEN.bit,XMTCTRLREG
155ENDM
156;
157XmtIntDsb:MACRO
158bclrXMTIEN.bit,XMTCTRLREG
159ENDM
160;
161RcvIntEn:MACRO
162bsetRCVIEN.bit,RCVCTRLREG

146

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

163ENDM
164;
165RcvIntDsb:MACRO
166bclrRCVIEN.bit,RCVCTRLREG
167ENDM
168;
169ComIntEn:MACRO;InterruptEnableforCommunications
170bsetRCVIEN.bit,RCVCTRLREG;JustonlyRCV...
171;MustEnableXMT*ONLY*whenneeded
172ldaRCVSTATREG;Clearanypossiblypending
173ldaRCVBUF;..RCVReadyFlag
174ENDM

COMENTARIOS a ["Laboratorios\Lab3\SciComm\SciComm.inc"]:
Comencemos, pues, identificando las funcionalidades que requiere el usuario cuando
necesitamanipularunperifricodecomunicacionesseriales,RS232.Noolvidenrevisar
elManualdeReferenciaquepubliqu:02MC9S08QE128RM(ReferenceManual)U.pdf.

Primero se presenta la funcionalidad que empleamos para definir los parmetros de


comunicacin.Enprincipio,enuncanaldecomunicacinserial,deltipodefinidocomo
RS232,hayvariablesquesedefinenFUERAdelprotocolo.Esoquieredecirquesiusted
tienequecomunicarseporejemploconCANTV,empleandoestemtodo,tienequeLLAMARLOS
portelfono,preguntarlesquvalorestienenpara:Nmerodebitsdecadasmbolo(8
es el ms comn, pero NO el nico); la velocidad en bits por segundo (9600 bps, en
nuestralibrera,perohayMUCHOSotrosvaloresqueseemplean,llegandohasta115,200
bps, y ms, sobre todo en comunicacin LOCAL, la que no se transmite va Modem o
Radio...Luego,estunbitllamado"Parity",oparidad,queserva,alprincipioms
queahora,paraayudaraidentificarerroresderecepcin.Hayunoms:elnmerode
STOPbits,quehacemuchotiemposeusacomoUN(1)Stopbit.

NuestraMacroparainicializarelcanaldecomunicacionesserialeses:

015;SCI9600N8:MACRO;ProgramSCI@9600,8,N,1

Esdecir:9600bps,NOparity,8bitsperchar,ONE(1)stopbit.

Para leer y transmitir caracteres, el usuario AMARA poder tener funcionalidades


equivalentes a las de "getchar" y "putchar" del C... Por eso aqu estn, a
continuacin:

017;getchar:MACRO;MAYrearmRcvinterrupts,insideISR
018;getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++

"getchar"funcionaigualqueenC:tomaunsmbolodeentrada(EnCvienendelteclado;
aqu, del puerto serial) y nos lo retorna en el Acumulador. "getcX" lee datos y los
almacena, no en el Acumulador, sino empleando el registro ndice H:X; muy til para
almacenarenunatablaloscaracteresrecibidos.

020;putchar:MACRO;MAYrearmXmtinterrupts,insideISR
021;putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
022;putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++

147

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

"putchar",transmiteloqueestenelAcumulador,empleandolalneadecomunicaciones
seriales. "putc" se usa cuando desean transmitirse CONSTANTES o VARIABLES; y "putcX"
para enviar informacin que est almacenada en TABLAS, "apuntadas" empleando el
registrondiceH:X.

Lasprximas2Macrossondemsbajonivel:

024;RcvChar:MACRO
025;XmtChar:MACRO

DijeconanterioridadquelosperifricosdelMC9S08QE128tienen,enprimerlugar,que
ENERGIZARSE:muchosdeesosperifricosNOestnconectadospermanentementealafuente
dealimentacin,paradisminuirelconsumodeenerga.Losdosperifricosquetienen
queverconlacomunicacinserial,RS232(SCI),quesoneldeTransmisin(XMT)yel
deRecepcin(RCV),seenergizacadaunoporaparte.Yoactivolosdosdeunasolavez,
porqueenmisejemplosestamosempleandoAMBOS:XMTandRCV"Activate":

027;XmtRcvActivate:MACRO

Lasfuncionalidadesdemsbajonivelan,son:

029;AncillaryMacros
031;IfRcvRdy:MACRObrAddressIfReady1
032;IfXmtRdy:MACRObrAddressIfReady1
que sirven para ver si el dispositivo de recepcin (RCV) o el de transmisin (XMT)
estndisponibles(READY),afindesabersiselospuedeemplear.

Para habilitar o deshabilitar cada dispositivo, independientemente, para que


interrumpan:

ParaelTransmisor(XMT),activarydesactivarlasinterrupciones:

034;XmtIntEn:MACRO
035;XmtIntDsb:MACRO

ParaelReceptor(RCV),activarydesactivarlasinterrupciones:

037;RcvIntEn:MACRO
038;RcvIntDsb:MACRO

Y,finalmente,unaformaconvenientedeactivarAMBOSperifricossimultneamentepara
trabajarconellos:

040;ComIntEn:MACRO;InterruptEnableforCommunications

La definicin de registros usted tiene que analizarla JUNTO a los manuales de


referenciaparaelSCI,SerialCommunicationsInterface:

050;SCI1BD:EQU$0020;BaudeRateregister
052Bauds9600Value:EQU$001A;16bit:4000000/(16*9600)=26.04=0x1A

148

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

NOTA: Para aumentar la compresin del cdigo, he utilizado varios ALIAS, que son
NOMBRES ALTERNATIVOS para unas mismas direcciones o variables. Hay que ser MUY
CUIDADOSOScuandoseempleanALIAS,paranocaerenolvidosquenosllevenacreerque
losAliasSONDIFERENTESVARIABLES,OREGISTROS,OPOSICIONESDEMEMORIA!(Recuerde:
Son DISTINTOS nombres para LAS MISMAS COSAS ENTIDADES: registros, posiciones de
memoria,ETC.)

056XMTBUF:EQUSCI1D;TransmiterBuffer
057RCVBUF:EQUSCI1D;ReceiverBuffer

INTERESANTEnotarqueAMBOSderegistros,elbufferdetransmisinyelderecepcin,
corresponden a la MISMA ENTIDAD FSICA: SCI1D. Esto es as porque el campo de
direcciones es un recurso MUY LIMITADO; y para optimizar, se definen AMBOS registros
conlamismadireccin.

CmosabeelCPUculdelosdosperifricos,eldeentradaoeldesalida,estamos
direccionando? Pues, si estamos LEYENDO de esa nica direccin, seguro estamos
intentando RECIBIR desde el perifrico RECEPTOR. Y si estamos ESCRIBIENDO sobre ese
MISMO recurso, con seguridad estamos tratando de TRANSMITIR por el perifrico
TRANSMISOR.

ConseguridadcoincidirconmigoenqueesMUCHOmsinteligibleunsmbolocomoRCVBUF
(ReceiverBuffer,oregistrodedatosdelreceptor),queSCI1D.Enelcdigohayotros
ejemplos en los que la inteligibilidad de los smbolos por m definidos resulta con
muchosuperioraladelasdefinicionesdeFreescale!
RegistrosdeControldelTransmisor:
061XMTCTRLREG:EQUSCI1C2
062RCVCTRLREG:EQUSCI1C2

RECUERDE: hay que HABILITAR el transmisor (ENABLE: XMTEN), para trabajar con l;
adems,sidebeinterrumpir,hayquehabilitarlotambinparainterrupcin(XMTIEN):

Bitsdeusofrecuente:
063XMTEN:EQUmSCI1C2_TE;TE:TransmiterEnable%00001000
064XMTIEN:EQUmSCI1C2_TIE;TIE:XmtINTEnable%10000000
065XMTIEN.bit:EQUSCI1C2_TIE;7

Vuelvoarecalcar:UnacosaeselXMTEN(TransmiterENABLE),queACTIVAalperifrico
transmisor(loENERGIZA),

..yotramuydistintaXMTIEN,queeselInterruptENableparaelXMT(Transmiter).Yel
XMTIENqueyointroduzco,esmuchomejornombrequemSCI1C2_TIE.

Elnmerobinarioaladerechademisdefiniciones,identificaCULbiteselreferido:

TIE:XmtINTEnable%10000000(bit7)delregistrodecontrolasociado,XMTCTRLREG.
Esimportantesaberculessonlosbits,parapoderlosverconelDebugger.

Estenmero(7)identificaendecimal,elcorrespondientebit:

065XMTIEN.bit:EQUSCI1C2_TIE;7

149

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

DefinicionesequivalentesparaelReceptor:

066RCVEN:EQUmSCI1C2_RE;RE:ReceiverEnable%00000100
067RCVIEN:EQUmSCI1C2_RIE;RIE:RcvINTEnable%00100000

Elbitparahabilitarlasinterrupcionesdetransmisinsedefineporaparte:

068RCVIEN.bit:EQUSCI1C2_RIE;5

Finalmente, tenemos una forma de activar AMBOS dispositivos (para que reciban
alimentacinelctrica);unsmboloquecubrelosdosperifricos:

069XmtRcvEnab:EQU(XMTEN|RCVEN);EnableBOTHdevices%00001100

Antes se definieron los bits de los registros de Control; ahora les corresponde el
turnoalosStatusRegisters:

073XMTSTATREG:EQUSCI1S1
074RCVSTATREG:EQUSCI1S1

Losbitsmsusadosenellos,queelusuarionuncaversiestempleandomisMacros:

076XMTRDY:EQUmSCI1S1_TDRE;TransmiterDataRegisterEmpty
077XMTRDY.bit:EQUSCI1S1_TDRE;7(mSCI1S1_TDRE:%10000000)

078RCVRDY:EQUmSCI1S1_RDRF;ReceiveDataRegisterFull
079RCVRDY.bit:EQUSCI1S1_RDRF;5(mSCI1S1_RDRF:%00100000)

080XMTEMPTY:EQUmSCI1S1_TC;TransmissionCompleteFlag
081XMTEMPTY.bit:EQUSCI1S1_TC;6(mSCI1S1_TC:%01000000):last!

PorqupararecepcinhayunsolobitdeREADY,yparatransmisinhaydos?Bueno,
losdosperifricossonCASIDUALESelunodelotro,peronoexactamente.

Alcomienzo,cuandohablamosdeColas,indicamosunamodificacinparaeldispositivo
de entrada, que TAMBIN se le hizo al perifrico DE SALIDA: Se le agreg un segundo
Registro Adicional al Serializador de Salida (el serializador que es el que va
transmitiendounoaunolosbitsdelaletra)ycuandostehatransmitido8bits,el
controlador de la interfaz toma otro smbolo del Data Buffer y lo lleva al
serializador, si es que hay algn dato ya en el Data Buffer. A esta combinacin de
Serializadoralimentadoporotroregistro,queesaqueldedondeendefinitivaelCPU
ESCRIBE los datos, se lo conoce, al igual que en el caso del receptor, como Double
Buffer(porquehay2registrosinvolucrados,obuffers).

Elprotocoloessimilaraldelcasodeentrada:cadavezquehayunBitdeReadyactivo
enlatransmisin,elCPUpuedemoverelsiguientedatoalTransmiterBuffer.Enalgn
momento ese dato pasa al serializador, y como el Buffer de Transmisin ha quedado
libre,sevuelveaactivarelBitdeReadydeTransmisin,loquepermitealprograma
principal colocar un nuevo valor en el Transmiter Buffer, mientras se est
transmitiendoeldatoanterior.

150

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Ahora, cuando ya no hay nada ms que transmitir, la ltima vez que el subsistema de
salidaactivaunTransmiterReady,elprogramaprincipalpodraCORTARlacomunicacin
enesemomento,peroPERDERAlatransmisindelltimobyteporque,aunqueelbuffer
de salida est disponible, el perifrico de salida NO ha terminado de serializar el
ltimodatoquetienequetransmitirporelcanaldecomunicaciones.Estasituacinse
trat en los primeros UARTS, mediante un retardo que el programa principal activaba
cuando transfera el ltimo dato al Transmiter Buffer. Y NO cerraba el canal de
comunicaciones (Modem? Radio?) hasta que no hubiera transcurrido ese tiempo,
calculadocomomayoralnecesarioparaenviarunbyte.

EnlosUARTsmodernossecolocunSEGUNDObitdeReadyparaeltransmisor;queslo
usamosantesdecerrarelcanaldecomunicacionesdespusdehabertransmitidonuestro
ltimobyte.Ennuestrosejercicios,stenoeselcaso,peroenlavidareal,s.

Un ltimo grupo de bits dentro del SCI, que tambin pueden INTERRUMPIR y tienen su
propio vector de interrupciones, es el de los ERRORES. Note que NO hay errores de
TRANSMISIN, porque no tenemos control ni conocimiento de lo que pasa, una vez que
hemosenviadounsmboloalcanaldecomunicaciones.SlohayerroresdeRECEPCIN:

084OVERRUNERR:EQUmSCI1S1_OR;OR:Overrun%00001000

El OVERRUNERR lo detecta la interfaz de entrada, cuando va a almacenar en el Data


Bufferunvalorqueacabadeserializar,yeseregistrodeentradaNOHASIDOLEDOpor
el procesador. La unidad controladora de entrada lo sabe, porque el protocolo de
recepcin ordena que cuando el CPU lee un dato, debe borrar la bandera de Ready de
entrada.Siestabanderaestenuno,paraelmomentoenquesedebecolocarunnuevo
dato en el registro de entrada, se sabe que el nuevo dato BORRAR el valor viejo, y
comoelCPUnohaindicadoqueloley,seESTNPERDIENDODATOSenlarecepcin.El
canaldecomunicacionesestalimentandoinformacinaunavelocidadsuperioralaque
elCPUlaestprocesando...

085NOISERR:EQUmSCI1S1_NF;NF:NoiseFlag%00000100

El Error de Ruido lo infiere el receptor si, cuando est realizando el proceso de


muestreodelosbitsdeentrada,encuentraquehaycambiosenlainformacin,msall
delosprevisiblesenlosbordesdelasealdemuestreo.Elmanualdereferenciatiene
ladescripcinexacta.

086FRAMERR:EQUmSCI1S1_FE;FE:FramingError%00000010

UnFramingErrorseproducecuandoelreceptorcomienzaamuestrearnuevosbits,porque
hadetectadounbitdeARRANQUE(START)y,alllegaralfinNOENCUENTRAUNSTOPBIT.
Estopuededeberseaexcesivoruidoenlalnea,quehizocreeralainterfazquehaba
unSTARTbit,oaunaprdidadesincronismoporalgunaotracausa,yqueentodocaso
producequelainformacindeentradanotengaelMarcooFRAMEcorrecto.Notequesi,
habindosesalidodesincronismo,pormalasuerteelltimobit,queselee,errneo,
esunUNO,lainterfazNOpuededetectarningnFramingError...

087PARERR:EQUmSCI1S1_PF;PE:ParityError%00000001

El bit de paridad (PAR o IMPAR) se invent al comienzo cuando los dispositivos de


comunicaciones seriales eran electromecnicos (TLEX), y haba MUCHOS errores en la

151

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

transmisin. La ideaera aadirun bit ala informacin, codificndola de tal manera


quehubieraunamitaddesmbolosPOSIBLES,yunamitaddevaloresIMPOSIBLES.As,si
alreceptorlellegaunsmbolodelgrupoequivocado,sabequehahabidoUNerrorde
comunicaciones.Sieldatoesdelgrupovlido,sesuponequehallegadobien(aunque
si hay DOS errores, o un nmero PAR de ellos, el receptor no es capaz de
identificarlo). Una manera fcil de aadir el bit extra, consiste en hacerlo de tal
maneraqueTODOSlosbitsdelavariablequeseesttransmitiendo,seanPARES(EVEN
PARITY)oIMPARES(ODDPARITY).Undispositivomuysencillosumaelnmerodebitsde
la informacin (sumador; cadena de EXORs), y si el nmero unos ya coincide con la
paridad,noagreganada,perosielnmerodeunosnocoincide,seagregaununo,afin
deobligaralsmboloparaquesiempresucantidadcoincidaconlaparidad,nmeropar
oimpardeunos.

Finalmente,sehaceunacombinacinparaidentificarCUALQUIERcondicindetectablede
error:

088RCVErrs:EQU(OVERRUNERR|NOISERR|FRAMERR|PARERR)

Unidadesdecomunicacinserialmsavanzadas,comolasqueseempleanenelPCIBM/AT
compatible,tienenunCUARTOelementoquepuedetambingenerarinterrupciones,enun
vectorindependiente.SetratadelmanejadordeLnea(LINECONTROLER)encargadodever
sielModemseactivosedesactiv,siseperdilaportadoraoregres,sihayun
inconvenienteconelModem(DSRinvlido),osienalgnmomentonopuedeaceptarun
smbolonuevo(CTSinvlido).

Escribir un paquete completo de comunicaciones, que considere los cuatro elementos


disponiblesenlasinterfacesindustrialesdecomunicaciones,noresultanadasencillo.
Perosecompranpormenosde$60,congaranta,soporte,ydocumentacinimpecablepara
suuso.

El resto de la biblioteca casi no necesita mayor comentario, si se analizan con


detenimientolasinstruccionesdecadaMacro.

Bueno; la primera Macro le coloca al dispositivo SCI (tanto al transmisor como al


receptor)losvaloresapropiadosdeBPS(bitsporsegundo:9600paranuestrosejemplos
[SIEMPREFUNCIONAN!]),8bitsparacadaelementotransferido,NOparityyun(1)Stop
bit.ElregistroenelqueseprogramanesosparmetroseselSCI1BD:BaudRate.Vase
elReferenceManual.

094SCI9600N8:MACRO;ProgramSCI@9600,8,N
095ldhx#Bauds9600Value;program9600bpsvalue
096sthxSCI1BD;..

LaACTIVACINdeambosdispositivos,transmisoryreceptor(energizarlos):

099XmtRcvActivate:MACRO
100mov#XmtRcvEnab,SCI1C2;ACTIVATEBOTHunits:xmt&rcv

Macroauxiliarparadeterminarsielreceptorestlisto:

103IfRcvRdy:MACRObrAddressIfReady1
104brsetRCVRDY.bit,RCVSTATREG,\1

152

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Sillegaanecesitarlamacroopuesta(IfRcvNotRdy),esas:

If_NOT_RcvRdy:MACRObrAddressIfNotReady1
brclrRCVRDY.bit,RCVSTATREG,\1

>>>LA<<<Macroprincipal,queleecomosiseestuvierahaciendoenC:

107getchar:MACRO;MAYrearmRcvinterrupts,insideISR
108brclrRCVRDY.bit,RCVSTATREG,*;rearm..
109ldaRCVBUF;..rearm

Sencillo,no?ObservequeestaMacroesBLOQUEANTE,igualqueenelC...Adems,si
est leyendo Strings,que son elementos de informacinterminadosen un byte ZERO, a
continuacin de un "getchar" usted puede simplemente hacer un BEQ, o BNE, y estas
instrucciones hacen referencia al LTIMO byte transferido por getchar (LDA hace una
comparacintcitadelvalorquetransfiere,contraCero).

Ojo que ambas Macros de RECEPCIN, Y LAS SIMILARES PARA TRANSMISIN (putchar, putc,
putcX), HAN SIDO PROGRAMADAS de tal manera que adems, "REARMEN" las
interrupcionesdecadaperifricoy,as,PUEDENUSARSETAMBINdentrodelasrutinas
deinterrupcin!

EsomequedMUUUYBIEN.

Eso es as porque el protocolo de Acknowledge de Interrupcin, que le dice al


perifricodeRecepcin,oaldeTransmisin,queyafueronatendidos,eslamismacosa
que llevarles la bandera de Ready a Cero a dichos dispositivos, y consiste en lo
siguiente(tomadodirectamentedelManualdeReferencia):

"ToclearRCVRDY,readRCVSTATREGwithRCVRDY=1andTHENreadtheSCIdataregister
(RCVBUF)".Estoesexactamenteloquehacegetchar:

107getchar:MACRO;MAYrearmRcvinterrupts,insideISR
108brclrRCVRDY.bit,RCVSTATREG,*;EsperaaqueRCVRDY=1
109ldaRCVBUF;LuegoLEEdelRCVBUF

Unaobservacinparaellectoravispado:Enlasrutinasdeinterrupcinpuedesuponerse
queNOHABRAnecesidaddeincluir:

108brclrRCVRDY.bit,RCVSTATREG,*;EsperaaqueRCVRDY=1

puesnicamentesellegaalarutinadeinterrupcinporqueelperifricoESTREADY!
Parecerasuperfluo.Pero,esosdospasossonlosqueserequieren,segneltextoen
inglsqueacabodecopiardirectamentedelReferenceManual.

NOTA:ElmanualesINEXACTOeIMPRECISO,porquecuandodice:"readRCVSTATREGwith
RCVRDY=1andTHENreadRCVBUF",NODICESIENTREESASDOSINSTRUCCIONESPUEDEN,O
NO,HABEROTRASINSTRUCCIONES(queseraelcasoenqueunainterrupcinsecolara
en medio de ellas, y la cosa quedara como: a) "read RCVSTATREG with RCVRDY=1",
b)a continuacin un nmero indeterminado de instrucciones (las de la rutina de
interrupcin)yfinalmente,c)el"readRCVBUF".

153

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Lanicamaneradeesclarecerestoesmedianteinvestigacin,incluyendoinstrucciones
amanoyviendoque,enrealidad,sfuncionaconinstruccionesextrasincluidasentre
lasotrasdos..Peroespocoprofesionalqueparasaberloquehaceundispositivo,no
seasuficienteconleerladocumentacin.

"To clear XMTRDY, read XMTSTATREG with XMTRDY = 1 and then write to the SCI data
register(XMTBUF)".Estoesexactamenteloquehaceputchar:

129putchar:MACRO;MAYrearmXmtinterrupts,insideISR
130brclrXMTRDY.bit,XMTSTATREG,*;EsperaaqueXMTRDY=1
131staXMTBUF;LuegoESCRIBEenelXMTBUF

NOTA:Endispositivosmsavanzados,comolafamiliaIntelqueseusaenlosPCIBM/AT
compatibles,elprotocolodeAcnowledgedeentradaysalidalorealizaelhardware:la
mismainstruccinqueLEEeldatodelbufferdeentrada,BORRALABANDERAdeReady;la
mismainstruccinqueescribesobreelperifricodesalidaBORRALABANDERAdeReady.

Noeraalgotancomplicado,comoparaobligaralprogramadorahacerestaoperacinpor
software.

Maisc'estlavie...

Note que al igual de su equivalente en C, getchar es BLOQUEANTE: una vez invocada,


esperaraquellegueunaletra,ANTESdecontinuaradelanteconelprograma.

Sienalgnmomentodecidequeustednodebebloquearse(unprogramaCASINUNCAdebe
bloquearse, porque se pierde casi todo el control sobre el sistema), usted puede
preguntarsihayletrasenelreceptorANTESdellamaragetcharparaleerlas.Estees
elequivalenteausarkbhit()enCpero,muyprobablementeustedesjamsoyeronhablar
dekbhit()antes.

NotKbhit(mstilaququekbhit)puedecodificarseas(esigualaIf_NOT_RcvRdy):

NotKbhitEQUIf_NOT_RcvRdy

Elcdigoquedaraas:

NotKbhitcont;Sinohaydatos,noloslee
getchar;..getcharnosebloquea,porqueshaydatos
cont:

Unaltimafuncionalidadmuytilenelreceptorconsisteennoleerlosdatossobreel
acumulador,sinosobreunatabla,quesesuponequevamosallenarconlosdiferentes
smbolosquelleguen.TambinesBLOQUEANTE:

112getcX:MACROPtr1;..MAYrearminterrupts,insideISR.*Ptr1++

SecargaelregistrondiceconelApuntadorhaciaelprximoelementodisponibleenla
tabla:

113ldhx\1

154

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Seesperaaquellegueunaletra,aligualqueengetchar:

114brclrRCVRDY.bit,RCVSTATREG,*;rearm..

AlllegarunnuevodatoselollevaalatablaconelMOV,SEINCREMENTAelapuntador
en un solo golpe, gracias al lujo de instrucciones y modos de direccionamiento que
tieneesteexcepcionalmicrocontrolador:

115movRCVBUF,x+;..rearm

Ahora, una funcionalidad prometida en estas macros es que, una vez transferido el
elemento de informacin principal (el DATO que lleg), el programador pueda hacer un
saltocondicional,aprovechandoelvalordelabanderaZ,activadoporelconjuntode
instruccionesENRIQUECIDOdelMCU.

Pero,apesardequeYAtransferimoseldatoasusitio,yqueelMOVyacolocelbit
Z en su estado apropiado, todava no hemos llevado el nuevo valor del pointer
incrementadoasusitio.Alhacerlatransferenciadelapuntador,sevanaalterarlas
banderasdelCCR,enparticularlaZ.AsquehayquepreservarelvaloractualdelCCR
(tpa)ANTESdeguardarelapuntador(sthx),yrecobrarlodespus(tap):

116tpa;saveCCRtoenableanyfollowingBEQ
117sthx\1
118tap;..restoreCCR:enablefollowingBEQ

Observeque"tpa"y"tap"fueronpensadasdetalmaneraqueNOmodificanlasbanderas
delCCR!

NOTE:INCREBLEMENTE,esteeselcomentarioquefiguraenelManualdeReferencia,en
relacinalainstruccinTAP:

*NOTE:TheTAPinstructionwasaddedtoimprovetestabilityof*theCPU08,andsofew
practicalapplicationsofthe*instructionexist.

The author of this infamous paragraph HAS NO IDEA OF WHAT HE IS TALKING ABOUT. This
instructionwasNOTaddedtoimprovetestability;itisoneofthemostimportantOp
CodesintheentireHC08instructionset,andonethatdeservesafullexampleonusing
it!

Forexample,towritesomegenericroutine,onethatcouldbeusedinsideanISR,if
youneedtodisableinterrupts,lateryoucannotsimplyenablethem:Youmustrestore
interruptstothestatetheywhereatthebeginning,somethinglikethis:
...
;
TPA
;TransferCCRtoAcc(TPAisTAPstwinopcode)
PSHA
;..SaveAcc(CCR)intostack
;...Lateryoumayrecovertheinterruptstate,asfollows:
PULA
;Pop(er...Pull)Acc
TAP
;..TransferAcctoCCR

;..(savedflags,includingIFlag)
;...

155

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Bytheway,TAPstandsfor:TransferAccumulatortoPROCESSORSTATUSWORD.Youknow,
theybeguncallingtheflags:PSWand,then,changetheirmindandrenamedthePSWlike
Condition Code Register (CCR) but, the instruction codes remain using the old
nomenclature(TAP,TPA).

Usted tiene que pensar en todo; la programacin es una actividad MUY MINUCIOSA. Por
eso,hayquedividirenproblemaenzonasmuymuypequeas,quenospermitanVERtodas
lasinteracciones.Siustedhaceuncdigodemillneas,yluegocomienzaaverpor
qunofunciona,estperdido.

Las Macros para el transmisor son las DUALES del receptor; por eso los comentarios
sernmnimos:

129putchar:MACRO;MAYrearmXmtinterrupts,insideISR
130brclrXMTRDY.bit,XMTSTATREG,*;rearm..
131staXMTBUF;..rearm

"putchar"esbloqueante.
putc no tiene equivalente en el dispositivo receptor: Se usa putc cuando se van a
transmitirCONSTANTESOVARIABLES;nospermitenotenerquecargarexplcitamenteesas
constantesovariablesenelacumulador:

134putc:MACRO#KorV;MAYrearmXmtinterrupts,insideISR
135lda\1
136brclrXMTRDY.bit,XMTSTATREG,*;rearm..
137staXMTBUF;..rearm

putcXesmuysimilaragetcX.Parapoderhacerusodelasinstruccionesenriquecidas,
tal como en getcX, antes de almacenar el apuntador incrementado, hay que guardar el
valordeZ(CCR),cargadoporeldatoquesehatransmitido,yrecuperarlodespusde
moverelapuntador:

140putcX:MACROPtr1;..MAYrearminterrupts,insideISR;*Ptr1++
141ldhx\1
142brclrXMTRDY.bit,XMTSTATREG,*;rearm..
143movx+,XMTBUF;..rearm
144tpa;saveCCRtoenableanyfollowingBEQ
145sthx\1
146tap;..restoreCCR:enablefollowingBEQ

LasmacrosXmtIntEn,XmtIntDsb,RcvIntEn,RcvIntDsbsonsimplementeencenderoapagar
elbitcorrespondiente.

ComIntEn hace "Interrupt Enable for Communications". Es decir, una vez colocados los
valores:SCI9600N8,yenergizadoslosdosperifricos:XmtRcvActivate,sedeseaActivar
elSubsistemaCompletoparatrabajarporinterrupciones:

169ComIntEn:MACRO;InterruptEnableforCommunications
170bsetRCVIEN.bit,RCVCTRLREG;JustonlyRCV...
171;MustEnableXMT*ONLY*whenneeded
172ldaRCVSTATREG;Clearanypossiblypending
173ldaRCVBUF;..RCVReadyFlag

156

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Ntese que SLO SE ACTIVA LA RECEPCIN para que interrumpa. Esto es as porque el
comportamientodelosperifricosdeentradaestalqueNUNCAellosestnREADY(nunca
interrumpen) hasta que llega una letra o algn otro elemento por la correspondiente
entrada.

Losperifricosdesalida(impresoras,transmisorRSR232,ycualquierotro),cuandose
los Activa es ms que seguro que no estn haciendo nada (nadie los ha mandado A
transmitirnada,onoleshandadonadaparaimprimir).

Asque,paracomenzar,ESTNREADY.

Si se los activa para que interrumpan, como estn Ready, van a interrumpir
INMEDIATAMENTE. Por eso hay que posponer la habilitacin para interrupciones de los
perifricos de salida, hasta cuando haya salidas disponibles, como una tabla para
transmitir por interrupciones, o una cola, o incluso una letra, si es que no se la
deseaenviardemaneraprogramada,sinoporinterrupciones.

NTESEque,ademsdelaactivacindelbitdeRCVIEN.bit,leyendoelRCVSTATREGyel
RCVBUF:

172ldaRCVSTATREG;Clearanypossiblypending
173ldaRCVBUF;..RCVReadyFlag

..se BORRA cualquier posible "RCV Ready Flag" pendiente, si es que hubiera llegado
algnsmboloANTESdequeactivramoselComIntEn.

(Y, esto... puede NO ser suficiente para activar confiablemente un dispositivo de


Recepcin, cuando los equipos externos NOS ESTN ENVIANDO INFORMACIN, de manera
Asincrnica...SobrelosperifricosexternossolemosNOtenercontrol!).

Piense bien sobre las implicaciones que existen si queremos habilitar nuestra
recepcin, y no lo podemos hacer sin estar seguros de que NO NOS HAN COMENZADO A
TRANSMITIRTODAVA!

Elcomportamientodelosperifricosdesalidaesas:larutina,probablementeMain,
llenaunatablaousauna,pregrabadaenROM(Flash),yhabilitalasinterrupcionesde
salida. La ISR de transmisin: XMTISR, se activa cuando est disponible, si se
encuentrahabilitadaparainterrumpir.As,sacaunelementodelatabla,lotransmite
yretornaconRTI(ReturnfromInterrupt).CuandovuelvaaquedarenestadodeReady,
vuelveainterrumpir.

Dosmecanismossuelenemplearseparaidentificarqueyanohaynadaqueprocesar:ose
acaba de enviar EL sealizador de final, que suele ser un byte NULL, lleno de ceros
(ste esel mismo mtodo que usa el C para terminar sus Strings), o llegaa cero un
contador que identifica cuntos caracteres faltan para terminar, y que se lo ha ido
decrementandocadavezquesetransmiteunaletra.

Cualquiera que sea el mtodo, cuando XMTISR determina que ya no hay nada ms que
enviar,SEAUTODESHABILITAPARAINTERRUMPIR,yretornaconRTI.

157

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

NOTA: Si ha "encolado" una tabla para su transmisin, y quiere enviar otra, o


reutilizar la misma rea para enviar otros datos, tiene que estar seguro de
MANTENERLACOHERENCIA.

Mucho cuidado con comenzar una accin antesde terminar la otra.Puede hacerse, pero
garantizando que jams se trancar el juego. Por ejemplo, supongamos que se est
empleandounaCOLA:SiMainhace"enQue"dealgoyhabilitalasinterrupciones,yla
XMTISR hace "deQue" y lo transmite, y si en un momento Main est "enQueing" algo y
quiere volver a habilitar las interrupciones, tiene que asegurarse que no ocurra una
situacindeDEADLOCK,enlaqueMainacabadehabilitarlasinterrupcionesyXMTISR
las desactiva y se llegue a un estado en que a Main le aparece la cola llena, y no
puedehacerunulteriorenvo,yXMTISRNOinterrumpe,porqueestdesactivada,ypor
tantonosacacaracteresdelacola.Esoes:SUPROGRAMAESTMUERTO:DEADLOCK.Nada
haceningnproceso;cadaentidadesperaporlaotra,yningunadelasdostrabaja...

Yolesdijequelasinterrupcionessonunagranadicinalmodelodelcomputador,sin
lascualesseranimpensableslascomputadorasmodernas,yqueapesardeello,sonel
PEORDOLORDECABEZAdeunprogramadordesistemasEmbebidos...

Elanlisissecomplicamuchsimo,porquesetiendeacreerque2instruccionesquese
escribieronunaacontinuacindelaotra,seejecutarnunainmediatamentedespusde
la otra. Cuando hay interrupciones activas, esto no necesariamente es as. Por eso,
cuando est haciendo un anlisis de coherencia, que le permita garantizar que su
programajamsquedarenDEADLOCK,paracadainstruccintienequesuponerquetodas
las ISR lo interrumpen, hacen su trabajo, y que todo sigue bien cuando su programa
contineaejecutarlasiguienteinstruccindesulalistado.Esmuylaborioso.

NOTAFINAL:

Usted debe haber observado que se ha empleado la instruccin MOV en varias partes;
incluso aprovechando su modo auto incrementado para el registro ndice H:X. Pero la
instruccinMOVrequierequealmenosunadesusdireccionesseencuentrenenlapgina
0 (ZPage),es decir, dentro de las 256 primeras posiciones. Por tanto, estasrutinas
PRECISAN la definicin de sus tablas EN ZRam. Si eseno va a ser su caso, tiene que
reescribirlasparausarparejasdeLDAySTAquereemplacenlosMOV.

Espero que les haya gustado mi implementacin de la librera de comunicaciones


seriales,RS232,empleandoeldispositivoSCIdelMC9S08QU128.Llevoalmenos30aos
implementandolasmismasrutinasparaelPC,paramispropiosequiposdeSupervisiny
Control,aniveldeMaestras,ydeRTUs(RemoteTerminalUnits),trabajandoensistemas
tandiversoscomoQNXyDOS.Noesquemesentestasemanayselascodifiqu....

28) Transmisin.
SeenvanpermanentementealPClasletrasdela'A'maysculaala'z'minscula.En
el PC se ejecuta un programa de comunicaciones tal como "Hyperterminal" (antigua
utilidad nativa en Windows, y ya periclitada...), el "TeraTerm" (que es el que yo
siempreuso),el"Putty"("poty",comosepronunciaenInternet),el"RealTerm",quees
el programa instalado en los PCs del Laboratorio C, y cualquier otro que ustedes
conozcanpararealizarestaactividaddeinteractuarenWindowsconundispositivova
canaldecomunicacionesRS232,enloqueseconoceunaCONSOLAREMOTA.

158

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

["Laboratorios\Lab3\SciComm\1tstXmt.asm"]
01;********************************************************************
02;Programa1TstXmt.asm:TestSCIComm.Support
03;LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)M10D2013
04;
05;..Send'A'to'z'lettersforever,toHyperterminal
06;
07;
08;Includefilesthatnodefineram
09NOLIST
10INCLUDE'derivative.inc'
11INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
12LIST;..storageandTHISisit'splace
13;
14;2)DEFINES

15ram:SETZ_RAMStart;$80
16rom:SETROMStart;$2080
17initStack:EQURAMEnd+1;$1800=$17FF+1.Stackbeginson$17FF
18COP_Disable:EQU$42
19;====================================================================
20;MAINPROGRAMHEADER:
21ABSENTRYMain
22ORGrom

23Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
24staSOPT1;..SystemOptions1
25ldhx#initStack;SetupSP
26txs;...
27;
28SCI9600N8;SetupSerialCommunicationsInter
29XmtRcvActivate;..face:9600bps,Noparity,8bits
30;
31Forever:
32lda#'A';Ascii'A'
33XmitLoop:
34putchar
35inca;'A'+1is'B';'Z'+1is'a'
36cmp#'z'
37blsXmitLoop

38putc#$0D;CarriageReturn(CR:'\r'inC)
39putc#$0A;LineFeed(LF:'\n')

40braForever;Tocometothisendyou'lneed
41;..217,191cycles@4,194,304Hz
42;
43nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
44;This'nop'MAYberemovedforCW6.3...
45;
46;InterruptVectors

159

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

47ORGVreset
48DC.WMain;RESET.Maximumpriority.Asynch.
49END

COMENTARIOS a ["Laboratorios\Lab3\SciComm\1tstXmt.asm"]
As,nuestroprimerprograma"1TstXmt.asm"incluyelalibrera'SciComm.inc'enunrea
queNOempleaRAM,acontinuacinde'derivative.inc':

10INCLUDE'derivative.inc'
11INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM

NoolvidequestaeslaposicindondeDEBEincluirmilibreradecomunicaciones.
Luego, se definen los parmetros de comunicacin (SCI9600N8) y se activan AMBOS
perifricos:XmtRcvActivate(ActivateXmt&Rcv):

28SCI9600N8;SetupSerialCommunicationsInter
29XmtRcvActivate;..face:9600bps,Noparity,8bits

Elprogramaensesmuysencillo;consistedeuncicloindefinidoquetransmitetodas
lasletrasentrela'A'maysculayla'z'minscula:

31Forever:
32lda#'A';Ascii'A'
33XmitLoop:
34putchar
35inca;'A'+1is'B';'Z'+1is'a'
36cmp#'z'
37blsXmitLoop

Cada vez que se termina una serie, se imprime el smbolo que representa, para la
pantalla,eldevolversehaciaelladoizquierdodelamisma:CarriageReturn('\r'in
C),yluegoelqueobligaalcursordelapantallaabajarunalnea:LineFeed(LF:
'\n'):

38putc#$0D;CarriageReturn(CR:'\r'inC)
39putc#$0A;LineFeed(LF:'\n')

29) ECHO.
Este programa implementa una funcionalidad muy empleada entre los profesionales que
tienenqueinteractuarconcomunicacionesseriales,deltipoRS232.Consisteenhacer
unECO(ECHO)aloscaracteresquelellegananuestroequipo,probablementedesdeuna
estacinMaestra,remota.

Ustedes simularn la estacin remota con el PC; su dispositivo local ser nuestra
tarjetaDEMOQE128.Ahora,resultaqueenocasiones,losprogramasdecomunicacinque
se ejecutan en la estacin maestra (o en el PC), tienen una funcin que a veces el
operadorolvida,yquesellamaLOCALECHO.Estosignificaquetodoloqueseenva,
porejemplodesdeeltecladodelPC,seveenlapantalladelmismo.Esclaroque,si

160

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

est activa esa caracterstica, es difcil saber si nos estamos comunicando con el
perifricoremoto,ono.

Poresoelsiguienteprogramacontestaconlaletraquerecibe,INCREMENTADAenuno.Se
sabeque,enlacodificacindeloscaracteres(clsicamente,ASCII:AmericanStandard
CodeforInformationInterchange),unaletradelalfabetoesigualalaanterior,MAS
UNO.Esdecir,quelaletra'B'esigualalaletra'A'MS1.Asquenuestroprograma
de ECHO, toma cada smbolo que recibe, y devuelve el siguiente: Smbolo Recibido MS
UNO. Ahora s es fcil en el PC verificar que la comunicacin se ha establecido. Si
escriboun'A',recibouna'B',yasparatodaslasletras.

SiustedescribeHAL,comosellamabalasupercomputadoradelapelcula"2001Odisea
delEspacio",apareceenlapantalla...IBM.Qutal?

["Laboratorios\Lab3\SciComm\2echo1.asm"]
01;********************************************************************
02;Programa2Echo1.asm:TestSCIComm.Support
03;LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04;M10D2013cosmetics(XmtRcvActivate)
05;Tobesurethatthereis"ECHO",returnback'letter+1',
06;..i.e:ifHyperterminalsends'A',HC908willreturn'B'...
07;..fortherange'A'<=c<'z'.
08;Anyothercharsarereturnedbackwithoutmodification.

09;
10;Includefilesthatnodefineram
11NOLIST
12INCLUDE'derivative.inc'
13INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
14LIST;..storageandTHISisit'splace
15;
16;2)DEFINES

17ram:SETZ_RAMStart;$80
18rom:SETROMStart;$2080
19initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
20COP_Disable:EQU$42
21;====================================================================
22;MAINPROGRAMHEADER:
23ABSENTRYMain
24ORGrom

25Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
26staSOPT1;..SystemOptions1
27ldhx#initStack;SetupSP
28txs;...
29;
30;SCI9600N8:NoneedforpreviousenabledSCIperipherals
31SCI9600N8;SetupSerialCommunicationsInter
32XmtRcvActivate;..face:9600bps,Noparity,8bits
33;
34Prompt:

161

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

35lda#'A';Ascii'A'
36XmitLoop:
37putchar
38inca
39cmp#'z'
40blsXmitLoop

41putc#$0D;CarriageReturn(CR:'\r'inC)
42putc#$0A;LineFeed(LF:'\n')
43;BEPATIENT!Tocomehereyou'lneed
44;..217,191cycles@4,194,304Hz
45;************NOTE:***************
46;ToSIMULATESCI*inputs*usePEMicroSCI1debuggercommand.
48;ItwillbeinstructivetodisplaySCI1S1(statusregister),andsee
49;..mostimportantflags,bits7,6&5:XMTRDY,XMTEMPTY&RCVRDY
50;Whiledebugging,seehowreadingStatusandwritingBUF,clears
51;..theRCVReadyflag;seealsohowXMTStatuswork(RDY&EMPTY)

52inpLoop:
53getchar;Lettersinrange'A'..'z'will
54cmp#'A';..beincrementedbeforereturning,
55bhsinRange;..tobesurethatwhatweseein
56;..thePCisn'taLOCALECHO!
57Xmit:putchar
58brainpLoop;Stayinthisloop,forever

59inRange:
60cmp#'z'
61bhsXmit;Don'tincrement'z'either
62incLetter:
63inca;Incrementthisreceivedchar
64braXmit;..andreturnbackittoPC
65;
66nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
67;This'nop'MAYberemovedforCW6.3...
68;
69;InterruptVectors
70ORGVreset
71DC.WMain;RESET.Maximumpriority.Asynch.
72END

COMENTARIOS a ["Laboratorios\Lab3\SciComm\2echo1.asm"]:
NoolvidelaposicindondeDEBEincluirmilibreradecomunicaciones:

12INCLUDE'derivative.inc'
13INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM

Acontinuacin,comoenelejemploanterior,lasMacros:

31SCI9600N8;SetupSerialCommunicationsInter
32XmtRcvActivate;..face:9600bps,Noparity,8bits

162

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

PrimeroelprogramaenvaLAMISMATRAMAdelejercicioanterior.Sellama"PROMPT"aun
textodeadvertenciaqueelcomputadorleenvaalusuariopararecordarlequeesten
posicin de recibir los datos que se le enven. Por eso esta trama la llamamos aqu
Prompt:

34Prompt:
35lda#'A';Ascii'A'
36XmitLoop:
37putchar
38inca
39cmp#'z'
40blsXmitLoop
41putc#$0D;CarriageReturn(CR:'\r'inC)
42putc#$0A;LineFeed(LF:'\n')

LuegorecibeloqueleenvandesdeelPC,verificaquelossmbolosseencuentrenen
elrango'A'..'z';sino,retransmitelomismoquerecibi...

52inpLoop:
53getchar;Lettersinrange'A'..'z'will
54cmp#'A';..beincrementedbeforereturning,
55bhsinRange;..tobesurethatwhatweseein
56;..thePCisn'taLOCALECHO!
57Xmit:putchar
58brainpLoop;Stayinthisloop,forever

59inRange:
60cmp#'z'
61bhsXmit;Don'tincrement'z'either

Y en caso afirmativo, de que el rango sea el apropiado, retransmite el smbolo


recibido,INCREMENTADO:
62incLetter:
63inca;Incrementthisreceivedchar
64braXmit;..andreturnbackittoPC

30) Transmisin por INTERRUPCIONES.


Este programa es igual al anterior, pero usa las interrupciones de transmisin para
enviarel'Message':

["Laboratorios\Lab3\SciComm\3echoInt1.asm"]
01;********************************************************************
02;Programa3EchoInt1.asm:TestSCIComm.Support
03;LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)D24J2012
04;M10D2013cosmetics(XmtRcvActivate)
05;..Same2Echo1.asmprogrambutusingINTERRUPTSforXMT'Message'
06;
07;Includefilesthatnodefineram
08NOLIST
09INCLUDE'derivative.inc'
10INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM

163

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

11LIST;..storageandTHISisit'splace
12;
13;2)DEFINES
14ram:SETZ_RAMStart;$80
15rom:SETROMStart;$2080
16initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
17COP_Disable:EQU$42
18;====================================================================
19;GLOBALVARIABLES
20ORGram
21XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
22XmtPtr:DS2;charpointerofnextdatatoXmt
23;********************************************************************
24;MAINPROGRAMHEADER:
25ABSENTRYMain
26ORGrom
27Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
28staSOPT1;..SystemOptions1
29ldhx#initStack;SetupSP
30txs;...
31;
32;SCI9600N8:NoneedforpreviousenabledSCIperipherals

33SCI9600N8;SetupSerialCommunicationsInter
34XmtRcvActivate;..face:9600bps,Noparity,8bits
35;====================================================================
36;Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
37Prompt:
38ldhx#Message;InitXmtPtrwithMessageaddress;
39sthxXmtPtr;..initcounterwith#ofchars
40mov#LOW(MessageSize),XmtNchars;...
41XmtIntEn;XmtISRwillsendthemessageand
42;..clear'XmtNchars'whenfinished
43cli;<<<DON'TFORGETTOGLOBALENABLEINTs
44;
45XmtLoop:
46tstXmtNchars;Waituntildone(tst:cmpwith0)
47bneXmtLoop;(Notneededhere.Just:GotoBRA*)
48bra*
49;
50Message:DC'12345',$0D,$0A;Shortmessage.DC?DefineConstant

51;;Message:DC"Esteeselmensajedeprueba,"
52;;DC"primeroentransmitirsealPCporinterrupciones"
53;;DC$0D,$0A;CarriageReturn,LineFeed(Newline)
55MessageSize:EQU*Message

56;====================================================================
57XmtISR:
58pshh;Notsavedbyinterruptproc
59tstXmtNchars;Seeifdone
60beqXmtDone;0chars?GotoDsbXmtInt

164

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

61Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
62decXmtNchars;Adjustcharcounter
63braXmtIsrExit

64XmtDone:
65XmtIntDsb
66XmtIsrExit:
67pulh;Notrestoredbyinterruptproc
68rti
69;
73;InterruptVectors(ELIMINADASLNEAS70,71,72porespacio.VerSRCORG)
74ORGVsci1tx
75DC.WXmtISR;SCITransmit
76ORGVreset
77DC.WMain;RESET.Maximumpriority.Asynch.
78END

COMENTARIOS a ["Laboratorios\Lab3\SciComm\3echoInt-1.asm"]:
Comodecostumbre,aquvanlosIncludeFilesquenodefinenram:

09INCLUDE'derivative.inc'
10INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM

Se incluyen dos variables GLOBALES: un contador de los caracteres que faltan por
enviar,XmtNchars,yelapuntadoralaprximaletradelmensajequesetransmitir:

20ORGram
21XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
22XmtPtr:DS2;charpointerofnextdatatoXmt

La consabida definicin de los parmetros de comunicacin, y la Activacin de ambos


dispositivos,eldetransmisinyelderecepcin:

33SCI9600N8;SetupSerialCommunicationsInter
34XmtRcvActivate;..face:9600bps,Noparity,8bits

El mensaje se encuentra completo en la tabla 'Message'. Se origina cargando la


direccindelmensajeenlavariablequeusamoscomoapuntador:

38ldhx#Message;InitXmtPtrwithMessageaddress;
39sthxXmtPtr;..initcounterwith#ofchars

Obsrvese que la direccin de la tabla 'Message' es: #Message. Si usted mueve


simplemente'Message',estarcopiandolaPRIMERALETRAdelmismo,nosudireccin.

A continuacin se inicializa la variable XmtNchars con el nmero que representa el


tamao del mensaje: #LOW(MessageSize). Ntense aqu dos cosas; en PRIMER lugar, el
tamaoeselsmboloMessageSize,quecuandoanalicemosenseguidalaconstitucinde
la tabla veremos en detalle cmo logramos que el Assembler calcule ese valor por
nosotros,paraquenoseamosnosotroslosquetengamosquehacerJAMSeltrabajodela
computadora.Luego,esevalorMessageSizepuedeengaaralAssembler,detalmaneraque

165

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

ste no sepa con seguridad si ese smbolo representa 8 bits o 16. Para evitar toda
ambigedad se usa el operador LOW, que escoge los 8 bits inferiores del smbolo en
cuestin. Y el numeral (#) se le agrega porque estamos usando la parte baja de
(MessageSize)comounaconstante(elvalordeltamaoreservadoparaesatabla):

40mov#LOW(MessageSize),XmtNchars;...

De los dos procedimientos que suelen emplearse para verificar que la transmisin se
termin(ZStrings,terminadosenNULL,ounContadorindicandolacantidaddesmbolos
quefaltaportransmitir),hemosescogidoesteltimo,uncontadordeletras.
Despus de esto estamos listos para transmitir; para esto habilitamos las
interrupcionesdeltransmisory,PORLTIMO,TAMBINhabilitamoslabanderaGLOBALdel
CPU,paraquesteacepteyproceseinterrupts:

41XmtIntEn;XmtISRwillsendthemessageand
42;..clear'XmtNchars'whenfinished
43cli;<<<DON'TFORGETTOGLOBALENABLEINTs

El ciclo final consiste en esperar a que se termine la transmisin, analizando la


variablecompartida(global)XmtNcharshastaquesehagacero,encuyocasollegamosal
bra*quesimulaunHALT:

45XmtLoop:
46tstXmtNchars;Waituntildone(tst:cmpwith0)
47bneXmtLoop;(Notneededhere.Just:GotoBRA*)
48bra*

Seveconclaridadquebastarareemplazaresas3instruccionesconel"bra*",porque
despus de transmitir los datos, no hay ningn proceso ulterior en este ejercicio.
Tambinsevequenosenecesitanlasinterrupciones,porqueelCPUnoesthaciendo
nada mientras la ISR transmite el texto... porque ste es un ejemplo muy sencillo.
Cuando usted haga su proyecto tendr oportunidad de introducir en Main, cdigo que
trabajeCONCOMITANTEMENTEconlaISR.

VieneladefinicindelaTabla:

50Message:DC'12345',$0D,$0A;Shortmessage.DC?DefineConstant
55MessageSize:EQU*Message

El texto, muy corto en este ejercicio, corresponde a los nmeros 12345 y luego, el
Carriage Return (\r: 0x0D: $0D) y el New Line (\n: 0x0A: $0A). El DC es por "Define
Constant";debeutilizarseenelCODESECTION,puesdefineespacioenRAM(Flash).

Y para que sea el Assembler el que calcule el tamao del texto, a fin de que si lo
cambiamosNOTENGAMOSQUEVOLVERACONTARLO,eltrucoesgenerarunsmbolo,definido
ahoraporlapseudoinstruccinEQU,as:

55MessageSize:EQU*Message

Recuerde que el LOCATION COUNTER (que usted debi aprender al hacer una de las
monografas de la parte terica del curso) se identifica en el CodeWarrior con el
smbolo '*'. Y deesa manera es claro que el nmero de byteses iguala la posicin

166

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

siguientealtexto,identificadaporel'*',menoslaetiquetaquesealaelcomienzo
delatabla,Message:

Siquiereensayarcontextosmslargos,aquhayunejemplo:

51Message:DC"Esteeselmensajedeprueba,"
52DC"primeroentransmitirsealPCporinterrupciones"
53DC$0D,$0A;CarriageReturn,LineFeed(Newline)
55MessageSize:EQU*Message

Larutinadeinterrupcionesparaeltransmisor,XmtISR,comienzaguardandoenelStack
elvalordelaparteHdelregistrondice:H:X,porqueelhardwareNOsalvaesebyte
automticamente. Y como putcX emplea el registro ndice, pues hay que resguardar su
valoraliniciodelaISR,yrestaurarloparafinalizar.

57XmtISR:
58pshh;Notsavedbyinterruptproc

Loprimeroquesehaceesverificarsianhayalgoportransmitir.Sino,terminamos
saltandoalaetiquetaXmtDone:

59tstXmtNchars;Seeifdone
60beqXmtDone;0chars?GotoDsbXmtInt

Si an nose ha terminado la transmisin, ENVIAMOS laprxima letra empleando 'putcX


XmtPtr'que,comoyadijimos,depasoBORRAelXMTRDY.bit.

61Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit

Selerestaunoalcontadordeletras,XmtNchars,yseretornadelainterrupcin.

62decXmtNchars;Adjustcharcounter
63braXmtIsrExit

Cuandoelcontadordeterminaqueyasetermintodalatransmisin,seAUTODESHABILITA
larutinadeinterrupcin:

64XmtDone:
65XmtIntDsb

y se ejecuta la parte final, recuperando el valor de H que se haba guardado al


principio,yretornandodeinterrupcin:

66XmtIsrExit:
67pulh;Notrestoredbyinterruptproc
68rti

LosInterruptVectorssonsloelVsci1txyelVreset:

74ORGVsci1tx
75DC.WXmtISR;SCITransmit
76ORGVreset

167

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

77DC.WMain;RESET.Maximumpriority.Asynch.

31) Cuarto Programa de COMUNICACIONES: Flash LEDs.


Este programa es similar al anterior, pero hace parpadear los LEDs con cada byte
enviado.Ademsdelalibrera'SciComm.inc',enesteejercicioseincluyelalibrera
'timers8HS.inc':

["Laboratorios\Lab3\SciComm\3echoInt1Leds.asm"]
001;********************************************************************
002;Programa3EchoInt1Leds.asm:TestSCIComm.Support
003;LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)C27J2012
004;..J03E2013M10D2013cosmetics(XmtRcvActivate)
005;..Same3echoInt1.asm,butFlashLEDswitheachbytesent.
006;InDEMOQUE128,DO***NOT***USEPTC5'sASSOCIATEDLED,asitis
007;..alsothepinusedtoDISABLECOMM1!!!,viaJumperJ8,THANKS!
008;
009;Includefilesthatnodefineram
010NOLIST
011INCLUDE'derivative.inc'
012INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM
013LIST;..storageandTHISisit'splace
014;
015;2)DEFINES

016ram:SETZ_RAMStart;$80
017rom:SETROMStart;$2080
018;;;initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
019;;;COP_Disable:EQU$42
020;====================================================================
021;GLOBALVARIABLES
022ORGram

023NOLIST
024include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
025LIST

026XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
027XmtPtr:DS2;charpointerofnextdatatoXmt
028;********************************************************************
029;MAINPROGRAMHEADER:
030ABSENTRYMain
031ORGrom

032Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
033staSOPT1;..SystemOptions1
034ldhx#initStack;SetupSP
035txs;...
036;
037;SCI9600N8:NoneedforpreviousenabledSCIperipherals

168

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

038SCI9600N8;SetupSerialCommunicationsInter
039XmtRcvActivate;..face:9600bps,Noparity,8bits
040;====================================================================
041;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
042mov#%11110000,PTCD;Turnon4leds,toshowprogram
043mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
044mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
045mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
046;NOTE:PTC5isprogrammedforINPUTsowrittingtoPTC5doesNOTHING
047;********************************************************************
048;NOTE:GeniusworkingatPEMicrousesamePTC5pintoboth,drivea
049;LED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,THANKS!
050;So,ifyouuseBOTHCOMM1andLeds,doNOTusePTC5associatedLED.
051;********************************************************************

052Init8Timers
053cli;<<<DON'TFORGETTOGLOBALENABLEINTs
054Loop:WaitMS_on7,#750;Showthelights...
055;
056;Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
057Prompt:
058ldhx#Message;InitXmtPtrwithMessageaddress;
059sthxXmtPtr;..initcounterwith#ofchars
060mov#LOW(MessageSize),XmtNchars;...
061XmtIntEn;XmtISRwillsendthemessageand
062;..clear'XmtNchars'whenfinished
063XmtLoop:
064tstXmtNchars;Waituntildone(tst:cmpwith0)
065bneXmtLoop;..

066WaitMS_on7,#750;Showthelights...
067ldhx#Message2;InitXmtPtrwithMessageaddress;
068sthxXmtPtr;..initcounterwith#ofchars
069mov#LOW(MessageSize),XmtNchars;...
070XmtIntEn;XmtISRwillsendthemessageand

071XmtLoop2:
072tstXmtNchars;Waituntildone(tst:cmpwith0)
073bneXmtLoop2;..
074braLoop
075;
076Message:DC'1234567890',$0D;Shortmessage.DC?DefineConstant
077MessageSize:EQU*Message
078Message2:DC'6789012345',$0D;Shortmessage.DC?DefineConstant

079;;Message:DC"Esteeselmensajedeprueba,"
080;;DC"primeroentransmitirsealPCporinterrupciones"
081;;DC$0D,$0A;CarriageReturn,LineFeed(Newline)
082;;MessageEnd:

083;====================================================================

169

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

084XmtISR:
085pshh;Notsavedbyinterruptproc
086tstXmtNchars;Seeifdone
087beqXmtDone;0chars?GotoDsbXmtInt

088lda#$FF;FlashLedstoshowprogramprogress
089eorPTCD;..
090eorPTED;..
091staPTCD;..
092staPTED;..
093Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
094decXmtNchars;Adjustcharcounter
095braXmtIsrExit

096XmtDone:
097XmtIntDsb
098XmtIsrExit:
099pulh;Notrestoredbyinterruptproc
100rti
101;
102nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
103;This'nop'MAYberemovedforCW6.3...
104;====================================================================
105;RTCInterruptServiceRoutine,siusaInit8Timers...

106RTC_INTERRUPT:
107TIMERS8ISR
108;
109;InterruptVectors
110ORGVrtc;Increasingpriorityfrombottomup
111DC.WRTC_INTERRUPT;(SiusaInit8Timers...)
112ORGVsci1tx
113DC.WXmtISR;SCITransmit
114ORGVreset
115DC.WMain;RESET.Maximumpriority.Asynch.
116END

COMENTARIOS a ["Laboratorios\Lab3\SciComm\3echoInt-1Leds.asm"]:

LoprimeroescomentarqueenlatarjetaDEMOQUE128,NOsepuedeusarelLEDasociado
con PTC5's ASSOCIATED LED, porque ese mismo pin se emplea en esa tarjeta para
DESHABILITARLASCOMUNICACIONES!!!,vaJumperJ8.Eso...eraINNECESARIO.Graciasa
PEMICRO!

009;Includefilesthatnodefineram
012INCLUDE'SciComm.inc';SciCommINCfiledoesNOTuseRAM

Incluirlalibreratimers8HS.inc,queSdefinevariablesenRAM:

022ORGram
024include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros

170

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Elcontadordecaracteresyelapuntadoralaprximaletraquesertransmitida:

026XmtNchars:DS1;SoftFlagforMain:0NothingtoXmt
027XmtPtr:DS2;charpointerofnextdatatoXmt

Parmetrosdecomunicacin,yActivacin(Activate)deXMTyRCV:

038SCI9600N8;SetupSerialCommunicationsInter
039XmtRcvActivate;..face:9600bps,Noparity,8bits
INICIALIZACINDELOSLEDs.LosLEDsenlatarjetaDEMOQE128son8,peroNOprovienen
de un MISMO registro de 8 bits (lo que no le hubiera costado nada a la gente de
PEMicro),sinoquevienen6ydos,as:dePTCD:bits05,ydePTED;bits67.Eso...
eraINNECESARIO.Gracias,PEMICRO!

LoprimeroquesehacecuandosevanaprogramarunoomsbitsparaSALIDAcomoes
elcasodelosLEDsenesteejercicio,esinicializarlosconelvalorqueparael
ejercicioseaelmsconveniente,ANTESDEDEFINIRLOSCOMOSALIDA(Recuerdeque,al
encenderelMCU,TODOSlospuertossondeENTRADA).

Los puertos de entrada y salida digital tienen varios registros asociados. El ms


importante es el de datos: PTCD para el puerto "C", PTED para el puerto "E", y as
sucesivamente(cfr.elrespectivoReferenceManual)

041;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
042mov#%11110000,PTCD;Turnon4leds,toshowprogram
043mov#%11110000,PTED;..start(0?LedON.1?LedOFF)

Despusdequeyatienenunvalordesalidaasignado,puedenahorasprogramarsepara
SALIDA:

044mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
045mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
046;NOTE:PTC5is^programmedforINPUT:WrittingtoitdoesNOTHING

ADVERTENCIA:

A algunos GENIOS que trabajan en PEMicro, se les ocurri usar el MISMO pin PTC5
paramanejarsimultneamenteunLEDYTAMBINPARADESHABILITARLASCOMUNICACIONES,
vaelJumperJ8,Gracias,PEMicro!

AsquesisuproyectousasimultneamenteelpuertodecomunicacionesSCI1yLEDs,
NOuseelLED5,asociadoconPTC5.

Ahora,inicializalostimers,comosiempresehahecho,yhabilitalasinterrupciones
globalesdelCPU:

052Init8Timers
053cli;<<<DON'TFORGETTOGLOBALENABLEINTs

171

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

PrimeroesperaunpocomenosdeunsegundoparaqueseveanlosLEDs:

054Loop:WaitMS_on7,#750;Showthelights...

Transmitaelmensaje;estaparteesidnticaaladelejercicioanterior:

057Prompt:
058ldhx#Message;InitXmtPtrwithMessageaddress;
059sthxXmtPtr;..initcounterwith#ofchars
060mov#LOW(MessageSize),XmtNchars;...
Despusdecargartodoslosparmetrosparaelmensaje#1,habilitalasinterrupciones
detransmisin:

061XmtIntEn;XmtISRwillsendthemessageand

Yluegovieneelciclodeesperahastaqueseterminedetransmitir:

063XmtLoop:
064tstXmtNchars;Waituntildone(tst:cmpwith0)
065bneXmtLoop;..

Cuandohayaterminado(XmtNcharsvalecero),vuelvaaesperar,afindequeseveanlos
LEDs:

066WaitMS_on7,#750;Showthelights...

Ahora carga la direccin del nuevo mensaje, Message2. Note que como ambos mensajes
tienenlamismalongitud,solosehaempleadoUNAlongitudparaellosdos.Esonotiene
porquseras.Sisusmensajestienendiferentelongitud,repitaelmismoclculoque
seesthaciendoparaelmensajeuno,enelmensaje2,yelrestosigueigual:

067ldhx#Message2;InitXmtPtrwithMessageaddress;
068sthxXmtPtr;..initcounterwith#ofchars
069mov#LOW(MessageSize),XmtNchars;...

Vueltaahabilitarlasinterrupcionesdesalida,queseAUTODESHABILITARONalterminar
detransmitirelmensajeanterior:

070XmtIntEn;XmtISRwillsendthemessageand

071XmtLoop2:
072tstXmtNchars;Waituntildone(tst:cmpwith0)
073bneXmtLoop2;..
074braLoop

Yrepite...

Losmensajes:

076Message:DC'1234567890',$0D;Shortmessage.DC?DefineConstant
077MessageSize:EQU*Message
078Message2:DC'6789012345',$0D;Shortmessage.DC?DefineConstant

172

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

La rutina de interrupciones para el transmisor. La primera parte es idntica al


ejercicioanterior:

084XmtISR:
085pshh;Notsavedbyinterruptproc
086tstXmtNchars;Seeifdone
087beqXmtDone;0chars?GotoDsbXmtInt

LasprximaslneasnieganlosbitsdelosregistrosCyE,quealimentanalosLEDs:

088lda#$FF;FlashLedstoshowprogramprogress
089eorPTCD;..
090eorPTED;..
091staPTCD;..
092staPTED;..

Luegosetransmitelasiguienteletra;sedecrementaelcontadoryseterminalaISR:

093Xmt:putcXXmtPtr;NOTE:putcXclearsXMTRDY.bit
094decXmtNchars;Adjustcharcounter
095braXmtIsrExit

Cuando se transmitido todo el mensaje, se AUTODESHABILITA la rutina para


interrupciones,ytermina:

096XmtDone:
097XmtIntDsb
098XmtIsrExit:
099pulh;Notrestoredbyinterruptproc
100rti

LaRTCInterruptServiceRoutine:

106RTC_INTERRUPT:
107TIMERS8ISR

YlosInterruptVectors,unoparamilibreradeTimers,Vrtc,otroparaeltransmisor
deinformacinserial,Vsci1tx,yelsiemprenecesario,Vreset.

32) Programas de COMUNICACIONES que USTED Debe Hacer:


Haga un programa que reciba informacin por interrupciones, que la RCVISR la encole,
habilitelasinterrupcionesdesalida,quelaXMTISRlasaquedelacolayretransmita
lo que 'recibe + 1', tal como hizo el programa de ECHO que ya describimos SIN
interrupciones.

DebepoderhacerunprogramaquesimuleunCHAT:EnusuarioescribedesdeelPC,elMCU
le hace ECHO normal (si recibe una A retransmite una A), y para simular que el otro
usuario escribe desde el MCU, donde no hay muchos recursos... podemos pegar varios
mensajes,unoacadapushbuttondeentrada;elMCUleeelbotnqueseoprimi,encola
elcorrespondientemensaje,yrealizalatransmisinporinterrupciones.

173

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Tienequetomarprevisionesparaquenohayaconflictoentreelmensajequeustedest
transmitiendodesdeelMCU,conelECOqueseleesthaciendoacadaletraquereciba
del PC. (Por ejemplo, si est transmitiendo su mensaje, puede ignorar por completo
hacerle Eco a la informacin que de pronto le puedan enviar simultneamente desde el
PC).

De los dems perifricos, el PWM se usar en los proyectos en los que haya sonidos
(tipoWalkman,opiano).ElADC(AnalogtoDigitalConverter)seemplearenproyectos
donde,porejemplo,quieracambiarseelvolumendelsonido,olafrecuenciadelpiano,
osisedeseahacerunVoltmetroDigital(elpotencimetroalimentadirectamenteuno
deloscanalesdelADCenlatarjetaDEMOQE128)

UnaaplicacindelPWMesladehacerquelatarjetaHABLE:Segrabalavozysela
reproducevaPWM,detalmaneraquelacorneticadelatarjetasuene,locualharcon
muy mala calidad, porque la respuesta del piezoelctrico, que hace de transductor de
sonido,esmuypobre.Perosiustedpuedereproducirunapalabra,serunbuenlogro.

YlosotrosdispositivosnopuedenusarseenelDEMOQE128sintocarlosconectores,lo
queestprohibidoenloscursosdeArquitecturaIennuestroslaboratorios.Yatendrn
oportunidaddeemplearlosafondoenloscursosmsavanzadosdeArquitectura,yenlos
deLaboratoriosdeProyectos.

PROGRAMAS VARIOS EN ASSEMBLY LANGUAGE

33) BITCOPY, MACRO y Ejemplo.


EnIngenieraDigital,Cap.3,sehaceunaintroduccinaunodelosmsapasionantes
y antiguos mtodos de deteccin y correccin de error: El Cdigo Hamming. No voy a
repetirloqueallescribparasureferencia;bstenosconexplorarunejemplo.

Sisetieneunatramadeinformacinde4bits,llamadosI7I6I5I3,ysequieredetectar
la presencia o ausencia de UN error, se le agrega UN BIT DE PARIDAD, del cual ya
hablamos con antelacin al explicar los aspectos ms relevantes de la LIBRERA DE
COMUNICACIONESSERIALES:SciComm.inc.

RichardWesleyHamminghizoen1950unacodificacinsimple,pura,clara,eficientey
eficaz,quepermiteDETECTARlaaparicindeUNERRORyCORREGIRLO,ydetectar(peroNO
corregir)laexistenciadeDOSerrores.

Para nuestro caso de ejemplo, Hamming dispuso los bits en la siguiente TRAMA (Trama
Hamming):I7I6I5P4I3P2P1,endonde,ademsdelosbitsdeInformacin,I7I6I5I3,sehan
entrelazado 3 bits adicionales, de paridad: P4P2P1 (note que su identificacin
correspondeapotenciasde2)

Enesatrama,Hamminghizoelsiguienteplanteamiento:Los3bitsextras,deparidad,
puedenestablecer8combinacionesentreellos.Lacombinacin000indicarqueNOhay
error.Ylasrestantes7combinaciones,del001al111,indicarnlaposicinendonde
apareceelerror,delaposicin1ala7,endecimal.

Su codificacin para cumplir con esta tan extraordinaria aproximacin consisti en


establecer,paralatransmisin,elsiguienteclculobinario:

174

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

P1 = I3 XOR I5 XOR I7, el XOR entre los bits situados en las posiciones
correspondientesalosnmerosimparesdelatabladeabajo:

P2=I3XORI6XORI7(observeelporquenlatabla)

P4=I5XORI6XORI7(observeelporquenlatabla)

TABLAHAMMING:

Error_Column#
PPP|IIII
421|7653
+
0000(NOERROR)
0011....
0102....
0113...1P1=I3XORI5XORI7
1004....P2=I3XORI6XORI7
1015..1.P4=I5XORI6XORI7
1106.1..
11171...

Donde haya un 1, para cada Pn, se toma la Im que tenga 1 (si es que hay) y se la
incluyeenlaecuacin.

VerlaexplicacinparauncasodeNbitsdeinformacinestenIngenieraDigital.

SupongamosquetenemoslaInformacinde4bitsdelejemployqueremoscalcularlas3
Paridades.Cmoharaustedlos6XORsdelas3ecuacionesbooleanas?

Una forma inmediata de hacer los XORs sera colocando los bits en dos variables del
CPU,H1yH2,enlassiguientesposiciones,yemplearlainstruccinEOR(XORparael
S08):

H1|I5I3I3
H2|I6I6I5XOR
+
H2|p4p2p1(RespuestaParcial)
H1|I7I7I7XOR
+
H2|P4P2P1(RESPUESTADEFINITIVA)

A partir de los bits dispuestos en Trama Hamming, I7I6I5P4I3P2P1, resulta un tanto


laboriosoreasignarlosbitshastalasposicionesrequeridasenlatablaparahacerlos
XORs,ydelresultadodevueltaalavariablequealojalaTramaHamming:

b7b6b5b4b3b2b1b0
..I7I6I5P4I3P2P1(Variablede7bits;alojalaTramaHamming)

b7b6b5b4b3b2b1b0
H1|I5I3I3
H2|I6I6I5

175

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

H1|I7I7I7
ydeaquotravezalatrama:
H2|P4P2P1(RESPUESTA)

YsilosbitsdeInformacincomienzanjuntos:I7I6I5I3,hayquemoverlos,alcomienzo,
paraformarlaTramaHamming.

Setransmitelatramaaselaboradayeneldestinoseaplicaunclculosimilar,que
ustedtienequerevisarenIngenieraDigital.Altransmitir,secomienzacon4bitsde
informacinyseformaunatramade7bits;alreceptorlelleganlos7bits,selos
procesayseproducenlos4bitsdeinformacin,libresdeerror,mientrasnoocurra
msdeunerrorencadatramade7.

Finalmente, se pueden detectar y corregir cualquier cantidad necesaria de errores,


calculando las tramas como acabo de indicar, y transmitindolas VERTICALMENTE. El
receptorlasreacomodaHORIZONTALMENTE,ycorrigetodosloserroresanticipados,segn
explicoenlareferenciamencionada.

El objetivo de este ejercicio es mostrar un procedimiento, la MACRO BITCOPY, y un


ejemplo.AustedlevendrabienaplicarlaalclculodeHamming,tantoparaGeneracin
delCdigoHammingcomoparalaDeteccinyCorreccindelerror.

Paraunexamenoevaluacin,losejerciciossuelentenermsde3bitsdeinformacin,
loqueproducetramasquenocabenenunBYTE.Sinembargoelprocedimientoessimilar
alanterior.

En Ingeniera Digital se encuentra la generalizacin a N bits de Informacin, y el


agregado de un bit de paridad extra, que permite DETECTAR dos errores, aunque el
algoritmonopermitacorregirlos.

["Laboratorios\Proy\Buzzer\BitCopy.asm"]
01;********************************************************************
02;BitCopy.asm;LuisG.UribeC.,D01L2012
03;MACROBITCOPYandtestprogram.
04;Toimplement"C"statmentslikethis:
05;PTCD_PTCD0=PTBD_PTBD5;
06;//DisplayPWMoutput,pinPTB5,intoLEDwiredtoPTC0
07;********************************************************************
08NOLIST
09INCLUDE'derivative.inc'
10LIST
11;
12;2)DEFINES
13
14ram:SETZ_RAMStart;$80
15rom:SETROMStart;$2080
16initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
17COP_Disable:EQU$42
18
19;====================================================================
20BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit

176

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

21;Example:BITCOPYSrc,3,Dst,5;Useanyvariables:DIRorEXT
22lda\1
23bit#1<<(\2&$07);IfSrcAdd[SrcBit]==0
24beq\@Clr_DstAdd;..gotoClr_DstAdd[DstBit]
25;Set_DstAdd[DstBit]:;Else,Set_DstAdd[DstBit]
26lda\3
27ora#1<<(\4&$07)
28bra\@cont
29;Clr_DstAdd[DstBit]:
30\@Clr_DstAdd:
31lda\3
32and#~(1<<(\4&$07))
33\@cont:
34sta\3
35ENDM
36
37;********************************************************************
38;MAINPROGRAMHEADER:
39ORGram
40Src:DS1
41Dst:DS1
42
43ABSENTRYMain
44ORGrom
46Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
47staSOPT1;..SystemOptions1
48ldhx#initStack;SetupSP
49txs;...
50
51lda#0
52staSrc
53lda#$FF
54staDst
55BITCOPYSrc,3,Dst,5;copya0
56
57lda#$FF
58staSrc
59lda#$0
60staDst
61BITCOPYSrc,2,Dst,6;copya1
62
63bra*
64;
65nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
66;This'nop'MAYberemovedforCW6.3...
67;
68;InterruptVectors
70ORGVreset
71DC.WMain;RESET.Maximumpriority.Asynch.
73END

177

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Laboratorios\Proy\Buzzer\BitCopy.asm"]:
En C es relativamente fcil expresar estos movimientos de bits, de un lugar a otro,
talescomo:

05;PTCD_PTCD0=PTBD_PTBD5;
06;//DisplayPWMoutput,pinPTB5,intoLEDwiredtoPTC0

EnrealidadestnasignadosaunaStructdeBITS,enUnionconelByte(enestecaso,
delosregistrosCyB).
20BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit
21;Example:BITCOPYSrc,3,Dst,5;Useanyvariables:DIRorEXT

LaMacrotiene4parmetros:ladireccin(1)delavariableFUENTE(SRC),dedondese
vaatomarelbit(2)paratransportarloalavariable(3)DESTINO,DST,enlaposicin
debit(4)

OBSERVACIONES:

A)LasvariablespuedenestarcolocadasencualquierposicindelaRAM,porqueseusan
LDAySTAenlugardeMOV.

B) Los parmetros 2 y 4, correspondientes a las posiciones de los bits, NO SON


VARIABLES:SONCONSTANTES,porqueconstantesdel0al7sonlasquehayquedarleala
BITdelS08queaquseusa.Adems,esenmeroNOllevaelsmbolo'#':sonnmeros
decimalesSIMPLES,del0al7,sinningnotromodificadoragregado.>>>IMPORTANTE<<<

22lda\1

Secargaenelacumuladorelprimerparmetro:LavariableSRC.

23bit#1<<(\2&$07);IfSrcAdd[SrcBit]==0

SehaceunacomparacindelbitSRCdeseado,indicadoporelparmetro\2,paraversi
estencerooenuno.ParahacerlacomparacinseusalainstruccinBIT(BitTest),
quehaceunANDentreelAcumuladoryelOperando,ycomparaelresultadocontracero.

Obsrvese que el Operando es un uno colocado en la posicin de bit indicada por el


nmero\2;estoqueacabodedecirseescribeas:#1<<(\2&$07)

...un uno (#1) colocado en la posicin (<<) de bit indicada por el nmero \2
(<<(\2&$07). Al parmetro \2 se le ha hecho un AND (&) con el nmero $07 (binario
%111),afindequesiporerrorelusuariollamalaMacropasndoleunnmeroMAYORa
7,stequedaautomticamenteconfinadoalrangopermitidode0a7.

Claro?

24beq\@Clr_DstAdd;..gotoClr_DstAdd[DstBit]

SielbitesCerosesalta(BEQ)aBORRARelbitenladireccindestino:Clr_DstAdd.
ComostaesunadireccinqueserepetiracadavezqueseemplearalaMacro(locual
daraerror,porquenopuedehabermsdeunadefinicinparaunadireccin,nipara

178

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

unavariable),eltrucoconsisteenantecederladireccinqueseindicadentrodela
Macro,conun\@.EstoleindicaalAssemblerquegenereunadireccindiferente,cada
vezqueveaesesmbolo\@Clr_DstAdd.

AcontinuacinvieneelcdigoqueseejecutasielbiteraUNO,yportantohayque
colocar en uno (SET) el bit en el destino. Primero se carga el acumulador con la
variableDST:

26lda\3

y,paracolocarununoenelbitdeseadodeDST,selehaceunOR(ora)as:

27ora#1<<(\4&$07)

Aqu,denuevo,laposicines:un1(#1),desplazadoalaizquierda(<<)tantospasos
cuantosindiqueelltimoparmetro(\4),alqueselohaconfinadoautomticamente
alrangode0a7medianteelAND(\4&$07).

Finalmente sale de la Macro, no sin antes guardar el valor del Acumulador en la


variableDST,indicadaporelparmetro\3.

28bra\@cont

Si el bit estuvo en cero, hay que colocar en cero el bit correspondiente de DST,
haciendo un AND del valor (del Acumulador) con un nmero formado por TODOS UNOS,
ExceptounCEROenlaposicinquesequiereborrar:

29;Clr_DstAdd[DstBit]:
30\@Clr_DstAdd:
31lda\3
32and#~(1<<(\4&$07))

Laexpresin"and#~(1<<(\4&$07))"haceexactamenteeso:unAND(and)conunamscara
depurosUNOSqueseconsiguehaciendoelNEGADObooleanodeUNunoenlaposicinque
sequiereborrar:~:Negadobooleano;laposicinquesequiereborrar:(1<<(\4&$07)).

Claro?

Ejemplo:

SecargaunceroenSRC,ysellenadepurosunoselDST:

51lda#0
52staSrc
53lda#$FF
54staDst

Secopiaelbit3deSRC,albit5deDST:

55BITCOPYSrc,3,Dst,5;copya0

ConelDebuggerpuedeverseelvalorresultante.

179

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Secargaahoraalrevs,purosUNOSenSRC,ypurosCEROSenDST:

57lda#$FF
58staSrc
59lda#$0
60staDst

Ysecopiaelbit2deSRC,albit6deDST.VaseconelDebugger.

61BITCOPYSrc,2,Dst,6;copya1

34) USO Bsico del ADC, y Display en LEDs.


El siguiente programa habilita el Analog to Digital Converter para realizar
conversionescontinuamente(freewheeling)ypresentarlosresultadosenlosLEDs.La
entrada se toma del potencimetro del DEMOQE128. Sirve como ejemplo para cuando
necesitehacerconversionesdeanlogoadigital,programarymanejarlosLEDs.

01["Laboratorios\Proy\Buzzer\ADC.asm"]
02;********************************************************************
03;ADC.asm;LuisG.UribeC.,D01L2012L11M2013
04;L11M2013:ClarificationaboutADCpinsENABLE(APCTLx)
05;DESCRIPTION:TheADCmoduleisconfiguredincontinuousconversion
06;mode,everyobtainedvalueisdisplayinportC&E(8LEDs).
07;PTA0isthebluePOTENCIOMETERinDEMOQE128!!!
08;********************************************************************
09NOLIST
10INCLUDE'derivative.inc'
11LIST;..storageandTHISisit'splace
12;
13;2)DEFINES
14ram:SETZ_RAMStart;$80
15rom:SETROMStart;$2080
16initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
17COP_Disable:EQU$42
18;********************************************************************
19;MAINPROGRAMHEADER:
20ABSENTRYMain
21ORGrom
22Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
23staSOPT1;..SystemOptions1
24ldhx#initStack;SetupSP
25txs;...
26;
27;MCU_Init
28;;lda#$23;EnableBusClocktotheADCmodule
29;;staSCGC1
30;;clra;DisableunusedperipheralsBusclock
31;;staSCGC2
32;

180

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

33;GPIO_Init
34;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
35mov#%11110000,PTCD;Turnon4leds,toshowprogram
36mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
37mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
38mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
39;NOTE:PTC5isprogrammedforINPUTsowrittingtoPTC5doesNOTHING
40;********************************************************************
41;NOTE:GeniusworkingatPEMicrousesamePTC5pintoboth,drivea
42;LED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,THANKS!
43;So,ifyouuseBOTHCOMM1andLeds,doNOTusePTC5associatedLED.
44;********************************************************************

45;
46;ADC_configuration
47;Int.disable.Continuousconversion
48mov#$20,ADCSC1;..modeandchannel0active
49clrADCSC2;Softwaretriggerselected
50mov#$30,ADCCFG;Inputclock/2.LongSampletime
51;..config.8bitconversion
52;====================================================================
53;See"02MC9S08QE128RM(ReferenceManual)U.pdf",10.5.1ADCModule
54;..InitializationExample,10.5.1.2PseudoCodeExample:
55;APCTL1=0x02means:AD1pinI/Ocontroldisabled.
56;..AllotherADpinsremaingeneralpurposeI/Opins
57;Manualsays:A"1"inAPCTLx:PinI/OcontrolDISABLED.
58;..Itmeans:A"1"inAPCTLx:ADCpinENABLED!!!<<<<<<<<<<<<
59;
60;Thesepeoplecannotevenwriteadecentmanual...

61clrAPCTL1;ALLADCpinsDISABLE;theyworkasGPIO
62bsetAPCTL1_ADPC0,APCTL1;ENABLEchannel0forADCinput
63bsetADCSC1_AIEN,ADCSC1;EnableADCinterrupt
64cli
65bra*

66;********************************************************************
67;interruptVectorNumber_VadcADC_ISR
68ADC_ISR:
69;
70;NOTE:ReadingADCRLclearCOCOFlag,ASITSHOULDBEDONEONALL
71;..PERIPHERALSTHATHAVEDATABUFFERSTOREADORWRITE!!!

72ldaADCRL;Negatebeforedisplay
73coma;..(LEDsturnonwith0's)
74staPTCD;MoveADCvaluetoportC
75staPTED;..andtoportE
76rti
77;
78nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
79;This'nop'MAYberemovedforCW6.3...
80;

181

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

81;InterruptVectors

82ORGVadc
83DC.WADC_ISR
84ORGVreset
85DC.WMain;RESET.Maximumpriority.Asynch.
86END
COMENTARIOS a ["Laboratorios\Proy\Buzzer\ADC.asm"]

Importante notar que el Potencimetro Azul del DEMOQE128 se conecta al ADC por la
entradaPTA0:

07;PTA0isthebluePOTENCIOMETERinDEMOQE128!!!

El siguiente cdigo no se ejecuta, pero se lo ha incluido de todas maneras para


ilustrar la configuracin del MCU cuando hay que habilitar el mdulo de ADC. Est
comentadoporquelasaccionesqueaqusetomaran,sehanejecutadoduranteelPower
OnReset,ycomonolashemosmodificado,nonecesitamosrepetirlas.

PERO,sisecambiaraalgunodeestos"settings",laformadeVOLVERaconfigurarloses
ejecutandoestas 4 lneas de cdigo. Para mayor informacin hay que revisar,como de
costumbre,elReferenceManual.

26;
27;MCU_Init
28;;lda#$23;EnableBusClocktotheADCmodule
29;;staSCGC1
30;;clra;DisableunusedperipheralsBusclock
31;;staSCGC2

Laexplicacindelainicializacindelos8LEDsesexactamenteigualalaquesehizo
en:30)CUARTOPROGRAMADECOMUNICACIONES,ynolavamosarepetiraqu.

Como la salida del potencimetroalimenta el terminal PTA0, en donde se encuentra el


canal0delADC,suconfiguracinconsisteenactivarelcanal0deentradaAnalgica,
y poner el ADC en modo de Conversin Continua, activado por Software (cuando podra
activarseporHardware).Tambinseseleccionaconversinde8bits,porqueelADCdel
MC9S08QE128puedetrabajarconotraslongitudesparaelresultadodelaconversin(as
seobtienemayorresolucin).Elcdigo:

46;ADC_configuration
47;Int.disable.Continuousconversion
48mov#$20,ADCSC1;..modeandchannel0active
49clrADCSC2;Softwaretriggerselected
50mov#$30,ADCCFG;Inputclock/2.LongSampletime
51;..config.8bitconversion

La siguiente es una aclaratoria sobre uno de los tpicos peor descritos en el


"02MC9S08QE128RM(ReferenceManual)U.pdf",10.5.1.

Hayunejemplodeinicializacin,10.5.1.2,escritoenPseudoCdigoycomentado:

182

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Primero se deshabilita el control de I/O para el pin o terminal AD1; los dems
terminalespermanecencomopinesdeI/Odepropsitosgenerales:

55;APCTL1=0x02means:AD1pinI/Ocontroldisabled.
56;..AllotherADpinsremaingeneralpurposeI/Opins

El manual, bien oscurecido, dice que un UNO en un pin x del APCTL (bit APCTLx) le
DESHABILITAaesepinelCONTROLDEI/O.

POR TANTO, ESE pin x del APCTL, por haberlo programado a UNO, hace que el
correspondientepindelADCSEHABILITE(parafuncionesdeADC)

Mucho ms sencillo hubiera sido expresar esta funcionalidad de la siguiente manera


(redactadolomsenPOSITIVOqueesposible):

"ParaHABILITARunpinxdelconversorADC,paraquefuncionecomoENTRADAANALGICA,
secolocaunUNOenelcorrespondientebitxdelregistroAnalgicoparaelControlde
Pines:APCTL(bitAPCTLx).

"Para HABILITAR como I/O digital un pin x, de los que pueden actuar como entrada
analgicadelADC(24canalesanalgicosenelMC9S08QE128),secolocaunCEROenel
correspondientebitxdelAPCTL,APCTLx.

"DespusdePowerOnReset(POR),todoslospinesquepotencialmentepuedenservircomo
entradasanalgicasdelADC,sonI/ODIGITALESGENRICOSyas,puedenprogramarsepara
entrada o salida, colocndoseles, o no, resistencias de Pullup, y todas las dems
funcionalidades definidas para las entradas y salidas digitales genricas. Por eso
nuestrosejemplosnuncahabilitaronesospinesmedianteunCEROenlosbitsAPCTLx:es
elvalorestndar.

57;Manualsays:A"1"inAPCTLx:PinI/OcontrolDISABLED.
58;..Itmeans:A"1"inAPCTLx:ADCpinENABLED!!!<<<<<<<<<<<<

Se programa el canal cero del ADC para que manipule entradas analgicas; los otro 7
bitsdeESEespecficogrupode24,enelMC9S08QE128,quedanenCERO,yporlotanto
siguensiendoEntradasySalidasDigitalesGenricas,GPIO.

61clrAPCTL1;ALLADCpinsDISABLE;theyworkasGPIO
62bsetAPCTL1_ADPC0,APCTL1;ENABLEchannel0forADCinput

Ennuestrocaso,podramoshaberhechosolamenteelBSETyaque,comohemosexplicado,
los otros 7 bits del APCTL1 estn en CERO (no necesitan un CLR). Desde luego, este
cdigosedejaac,porsiustedtienenecesidadderevertirenalgnotroejercicio,
lasentradasdeAnalgicas,aGPIO.

FINALMENTEsehabilitaelADCparaqueInterrumpa,lomismoquealCPU,ysesimulaun
HALTmedianteelBRA*:

63bsetADCSC1_AIEN,ADCSC1;EnableADCinterrupt
64cli
65bra*

183

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

NOTA:ComonofuemiintencinestablecerenestedocumentounsubsistemaparaelADC,
programadocontodaslasreglasdeTopDownDesignyBottomUpCodingqueseemplearon
enlaslibrerasquedesarrollparaTEMPORIZADORESyCOMUNICACIONESSERIALES,nous
nombres de un valor semntico ms elevado, establecidos mediante ALIAS a las, para
nuestros propsitos, oscuras identificaciones que definieron los diseadoresdel MCU.
Hubieransidodefinicionesalgoascomo"AdcIntEn"(parangndel"XmtIntEn"empleado
enanterioresejercicios...)

Cadavezqueseproduceunaconversin,secolocaenUNOlabanderadeREADY,queenel
conversorADCsellamaCOCO:COnversionCOmplete.LointeresantedelperifricoADCde
este MCU es que BASTA CON LEER EL REGISTRO DE DATOS, ADCRL, para AUTOMTICAMENTE
generarelAcknowledgedelaInterrupcin(reposicionandoCOCOenCERO).

Esto, aunque opera como las minicomputadoras Digital (PDP, VAX) lo hacan, o como
funciona el PC/AT Compatible, arquitectura desarrollada por la IBM y an en uso
actualmente, es decir, que OPERA COMO TODOS LOS PERIFRICO DEBAN HACERLO, introduce
unanuevaIRREGULARIDAD:

PerifricosalosqueelINTACKselesdaporsoftware,leyendolabanderadeREADY
enUNOy,acontinuacin,leyendoelDATABUFFER,talocomoestdefinidoelperifrico
SCIdeComunicacionesSeriales.

Perifricos que reconocen un INTACK con el solo hecho de leer el vector de


interrupciones asociado (la direccin de la IRQISR. Este modo se us en el ancestro
directodelMC9S08,elMC908,sinlaS).

ElADCslorequierequeseleaelDATABUFparaaceptarunACK(COCOretornaaCERO)

Enlarutinadeinterrupcin,ADC_ISR,seleeelvalordelBUFFER,ADCRL(RegisterLOW,
que proporciona los 8 bits requeridos). Esto produce, como ya dijimos, un ACK que
reseteaelCOCO.Invertimoselvalornegndolo(conCOMA,1'sComplementAccumulator),
porquecomoyasabemos,losLEDsenlatarjetadedesarrolloDEMOQE128seenciendencon
CEROS. El valor lo llevamos a los dos registros en que los genios de PE Micro
descompusieronlos8LEDs(6enPTCy2enPTE).Porltimo,larutinahaceunRTI.

68ADC_ISR:
72ldaADCRL;Negatebeforedisplay
73coma;..(LEDsturnonwith0's)
74staPTCD;MoveADCvaluetoportC
75staPTED;..andtoportE
76rti

NOTE:NosehasalvadoporprogramaelregistroHalcomienzo,porqueestarutinano
usaparanadaelregistrondice,H:X.

35) Uso Bsico del ADC, Reversar Datos Antes de ir a los LEDs.
Supongaquevaaalojardentrodeunacajasutarjetadedesarrollo,yquequieredejar
unaventanillapordondepuedanversedesdeelexterior.Simirabien,notarquelos
bitsquedanalrevs,conelbit0alaizquierda.Asquelasecuencia1,2,3,4,5,
6,7severcomo:1000..,0100..,0110..,0001..,1001..,0011..,0111

184

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

EsomedalabaseadecirquePEMicroALAMBRLOSLEDsALREVS.

Esteejercicioesparecidoalanterior,peroalosbitsdelresultadodelaconversin
deLADCselosreordenaparaquelainformacinenbinarioquesepresentamediantelos
LEDs,quedeALDERECHO.

["Laboratorios\Proy\Buzzer\ADC_Reverse.asm"]
001;********************************************************************
002;ADC_Reverse.asm;LuisG.UribeC.,D01L2012
003;DESCRIPTION:TheADCmoduleisconfiguredinContinuousConversion
004;..Mode,everyobtainedvalueisdisplayinportC&E(8LEDs).
005;PTA0isthebluePOTENCIOMETERinDEMOQE128!!!
006;
007;********************************************************************
008;NOTEfromLuisG.UribeC.Desktop:
009;
010;GeniusworkingatPEMicronotonlyusedsamePTC5pintobothdrive
011;anLED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,!THANKS!,
012;butREVERSEWIREDtheLEDswithBit0attheLEFT!!!THANKS!,
013;andREVERSEDRIVEtheLEDssotheylightwitha'0'!THANKS!,
014;andREVERSEWIREDthePOTENCIOMETER,toprovide0Voltswhenfully
015;..turnedCLOCKWISE,and3VoltswhenturnedBACKWARDS!THANKS!.
016;..DidtheyeveruseaKNOBtoraisethemusicvolumealoud???
017;********************************************************************
018NOLIST
019INCLUDE'derivative.inc'
020LIST;..storageandTHISisit'splace
021;
022;2)DEFINES

023ram:SETZ_RAMStart;$80
024rom:SETROMStart;$2080
025initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
026COP_Disable:EQU$42

027;====================================================================
028BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit
029;Example:BITCOPYSrc,3,Dst,5;Useanyvariables:DIRorEXT
030lda\1
031bit#1<<(\2&$07);IfSrcAdd[SrcBit]==0
032beq\@Clr_DstAdd;..gotoClr_DstAdd[DstBit]
033;Set_DstAdd[DstBit]:;Else,Set_DstAdd[DstBit]
034lda\3
035ora#1<<(\4&$07)
036bra\@cont
037;Clr_DstAdd[DstBit]:
038\@Clr_DstAdd:
039lda\3
040and#~(1<<(\4&$07))
041\@cont:
042sta\3
043ENDM

185

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

044;====================================================================
045;GlobalVariables

046ORGram
047ADC_tmp1DS.B1
048ADC_tmp2DS.B1

049;********************************************************************
050;MAINPROGRAMHEADER:
051ABSENTRYMain
052ORGrom

053Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
054staSOPT1;..SystemOptions1
055ldhx#initStack;SetupSP
056txs;...
057;
058;Thisisthe'MCU_Init'fromtheOriginalCprogram.However,Iam
059;..usingPOR(PowerOnReset)defaults:ClocktoEVERYperipheral.
060;
061;MCU_Init
062;;lda#$23;EnableBusClocktotheADCmodule
063;;staSCGC1
064;;clra;DisableunusedperipheralsBusclock
065;;staSCGC2
066;
067;GPIO_Init
068;InitLEDsPORTsPTCD(bits05)andPTED(bits67)
069;
070;NOTE:ForOUTPUTPins,alwaysSetupfirsttheinitialvalueyou
071;desireforthem,andTHENprogramthepinforOutput.

072mov#%11110000,PTCD;Turnon4leds,toshowprogram
073mov#%11110000,PTED;..start(0?LedON.1?LedOFF)
074mov#%00011111,PTCDD;SetPortsbitsforoutput:C=5,D=2
075mov#%11000000,PTEDD;..(theydrivetheLEDsonDEMOQE128
076;NOTE:PTC5isprogrammedforINPUTsowrittingtoPTC5doesNOTHING

077;********************************************************************
078;NOTE:GeniusworkingatPEMicrousesamePTC5pintoboth,drivea
079;LED,ANDFORDISABLINGCOMMUNICATIONS,viaJumperJ8,THANKS!
080;So,ifyouuseBOTHCOMM1andLeds,doNOTusePTC5associatedLED.
081;
082;ADC_configuration
083;Int.disable.Continuousconversion
084mov#$20,ADCSC1;..modeandchannel0active
085clrADCSC2;Softwaretriggerselected
086mov#$30,ADCCFG;Inputclock/2;LongSampletime
087;..config;8bitconversion
088clrAPCTL1;ADC0pindisable;itworksasGPIO...
089;===================================================================
090bsetAPCTL1_ADPC0,APCTL1;SelectchannelforADC0input

186

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

091bsetADCSC1_AIEN,ADCSC1;EnableADCinterrupt
092cli;GlobalEnableCPUInterrupts.
093bra*

094;********************************************************************
095;interruptVectorNumber_VadcADC_ISR
096ADC_ISR:
097;*******************************
098;NOTE:ReadingADCRLclearCOCOFlag,ASITSHOULDBEDONEON
099;..ALLPERIPHERALSTHATHAVEDATABUFFERSTOREADORWRITE!!!
100;*******************************

101ldaADCRL;Negatebeforedisplay,THANKSPEMicro!
102coma;..(LEDsturnonwith0's)
103staADC_tmp1

104;Exchangebitpositions,THANKSPEMicro!
105BITCOPYADC_tmp1,0,ADC_tmp2,7
106BITCOPYADC_tmp1,1,ADC_tmp2,6
107BITCOPYADC_tmp1,2,ADC_tmp2,5
108BITCOPYADC_tmp1,3,ADC_tmp2,4
109BITCOPYADC_tmp1,4,ADC_tmp2,3
110BITCOPYADC_tmp1,5,ADC_tmp2,2
111BITCOPYADC_tmp1,6,ADC_tmp2,1
112BITCOPYADC_tmp1,7,ADC_tmp2,0

113movADC_tmp2,PTCD;MoveADCvaluetoportC
114movADC_tmp2,PTED;..andtoportE
115rti
116;
117nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
118;This'nop'MAYberemovedforCW6.3...
119;
120;InterruptVectors

121ORGVadc
122DC.WADC_ISR

123ORGVreset
124DC.WMain;RESET.Maximumpriority.Asynch.

125END

COMENTARIOS a ["Laboratorios\Proy\Buzzer\ADC_Reverse.asm"]:
SeincluyelaMacroBITCOPY,anteriormenteexplicadayusada:
028BITCOPYMACROSrcAdd,SrcBit,DstAdd,DstBit

DosvariablesGlobalestemporales(Bytes)paramanipularelvalordelaconversin:
046ORGram
047ADC_tmp1DS.B1
048ADC_tmp2DS.B1

187

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Se programan los LEDs y el ADC como en el ejercicio anterior; y se culmina con una
esperaeterna,medianteelBRA*.

LaISRdelconversorcomienzacomoantes,leyendoelBUFFER:ADCRLynegndolo(COMA:
1'sCOMPLEMENTACCUMULATOR),yloalmacenaenADC_tmp1:

101ldaADCRL;Negatebeforedisplay,THANKSPEMicro!
102coma;..(LEDsturnonwith0's)
103staADC_tmp1

UsaADC_tmp1comovariableSRCparalaMacroBITCOPY,ycruzalosbitsalmacenndolos
enlasegundavariabletemporal,ADC_tmp2.Notecmocopiaelbit0al7,el1al6,2
al5,3al4,4al3,5al2,6al1yfinalmente,elbit7albit0.

104;Exchangebitpositions,THANKSPEMicro!
105BITCOPYADC_tmp1,0,ADC_tmp2,7
106BITCOPYADC_tmp1,1,ADC_tmp2,6
107BITCOPYADC_tmp1,2,ADC_tmp2,5
108BITCOPYADC_tmp1,3,ADC_tmp2,4
109BITCOPYADC_tmp1,4,ADC_tmp2,3
110BITCOPYADC_tmp1,5,ADC_tmp2,2
111BITCOPYADC_tmp1,6,ADC_tmp2,1
112BITCOPYADC_tmp1,7,ADC_tmp2,0

Terminadalareasignacindebits,lospresentamosenlos8LEDsyterminamosconRTI:

113movADC_tmp2,PTCD;MoveADCvaluetoportC
114movADC_tmp2,PTED;..andtoportE
115rti

DadoqueestaIRQnoresguardaporprogramaelregistroH,ustedtienequeasegurarse
dequelaMacoBITCOPYTAMPOCOUSEelregistrondiceH:X.

DETALLES,DETALLES...

UNPUNTOMS:

ComoelPOTENCIMETROTAMBINSECABLEALREVS:significaquealestarcompletamente
a la izquierda entrega el mayor voltaje (3V), y al rotarlo hacia la derecha baja el
voltaje linealmente hasta llegara CERO V,una truco para arreglar ese problema, por
software,esconvertirlasmedidasqueenhexadecimalvande$FFa$00(deizquierdaa
derecha),enmedidasquevayande$00a$FF.SevequebastaconNEGARlamedidadel
conversorparasolucionarelproblemadelalambradoilgicodelpotencimetro.

Pero,YAHAYUN'COMA'pararesolverelproblemadequelosLEDsenciendenalrevs,en
CERO:

102coma;..(LEDsturnonwith0's)
RecuerdequenegardosvecesequivaleaNONEGAR.

Por tanto, NO HAY NECESIDAD del 'COMA de la lnea 102; basta con eliminarla, o
comentarla,yahoratodoparecerfuncionarbien.

188

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

36) Contador de UNOS.


Contar los bits que estn en uno, o en cero, en una variable, es un clsico en los
cursosdeprogramacin.

EnCdossonlassolucionesmspublicitadas;laprimeraconsisteentenerunavariable
auxiliarquevale...001ysevadesplazandoalaizquierda,Nveces(8paraunbyte):
...001 ...010 ...100. Cada vez se hace un AND con el operando y si el resultado es
diferentedeceroseincrementaelcontadordeunos.

Una,msinteresantean,consisteenaplicarlaexpresinx&=(x1);queELIMINAde
'x'elUNOqueestmsalaizquierda:

while(x){
cnt++;
x&=(x1);
}

Unaventajadeestaltimaaproximacinconsisteenqueslohayquerepetirelciclo
mientrashayaUNOS,nonecesariamente8veces(8,paraBytes)

Elejemploqueincluyoacontinuacin,haceusodelainstruccindeLEFTSHIFT,que
desplazalavariableencuestin,unaposicinalaizquierdayelbitqueSALEqueda
almacenadoenlabanderaC(Carry).SeincrementaelcontadorcadavezqueC==1.Si
serepiteelcdigo8veces(paraBytes),habremoscontadoelnmerodeunos.

Unatajoconsisteendisponerdeunasegundacondicin,paradetenerelprocedimiento
si la variable llega a cero (antes de terminar los 8 ciclos). Esto agrega la misma
ventajadelltimoejemploenC,ytambinpermiterepetirelcicloslomientrashaya
UNOS,nonecesariamente8veces(8,paraBytes)

Este ejercicio est pensado para ejecutarse con el DEBUGGER, paso a paso, a fin de
poder introducir las entradas a mano (simuladas), va PTAD. Usted puede emplear los
interruptores de la tarjeta DEMOQE128 que usan, por ejemplo, el PTC, o usar otra
variablepuestaenelprogramaparaesepropsito.

["Books\InterfacingHCS08\Examples\bitcount3.asm"]
01;********************************************************************
02;BitCount3.asm,HCS08_CPU,LuisG.UribeC.,M05F2013
03;
04;Includefiles
05NOLIST
06INCLUDE'derivative.inc'
07LIST
08;
09;Parameterdefinitions
10ram:SETZ_RAMStart;$80.Cfr.'MC9S08QE128U.inc'
11rom:SETROMStart;$2080
12initStack:EQURAMEnd+1;$17FF+1=$1800
13COP_Disable:EQU$42
14;===================================================================

189

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

15;BeginofCodeSection
16ABSENTRYMain;Exportsymbol(DEBUGGERentry)
17ORGrom;$2080:HCS08ROMStart(Flash)
18;
19;***ALWAYS***includethefollowing4instructions
20Main:lda#COP_Disable
21staSOPT1;SystemOptions1
22ldhx#initStack;InitSP.H:X<$1800
23txs;..SP<=$17FF
24;
25clra;InitializeAto0
26ldxPTAD;LoadoperandintoX
27Loop:lslx;Shiftoutabitofoperand
28beqZero
29adc#0;Accumulateit
30braLoop
31Zero:adc#0;Accumulateit
32bra*
33;
34nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
35;This'nop'MAYberemovedforCW6.3...
36;********************************************************************
37;InterruptVectors

38ORGVreset
39DC.WMain;RESET:HCS08PowerOn(PON)procedure.
40END

COMENTARIOS a ["Books\Interfacing-HCS08\Examples\bitcount3.asm"]:

ElcontadorserelAcumulador,yseloinicializaencero.Sloparaelejercicio,se
suponequelaentradaquefuncionacomoeloperandoalaqueselecontarnlosunosse
tomadelPuertoA(PTAD);comoyasedijo,ustedpuedecolocarotravariablesiaslo
desea. El operando se lee desde PTAD y se almacena en la parte BAJA del registro
ndice:X

25clra;InitializeAto0
26ldxPTAD;LoadoperandintoX

El ciclo Desplaza el operando (X) un bit a la Izquierda; si encuentra que esta


operacinprodujoCero(ConjuntodeInstruccionesEnriquecido,quecomparaelresultado
delamayoradelasoperacionescontraCERO),seterminalaaccin.

27Loop:lslx;Shiftoutabitofoperand
28beqZero

SianlavariablenovaleCero,sesumaelCarryalAcumulador;comocadabitquesale
del operando al hacerse un desplazamiento, se almacena en el bit de Carry, C, ste
quedar en Cero o en Uno segn corresponda. Si se suma el Carry a Acumulador, se
produce un Incremento si lo que se desplaz era un UNO; si era un CERO, la suma no

190

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

generaningnincremento.Deestamanerasevancontabilizandocuntosunoshabaenel
operando.Luegorepiteelciclo.

NotequenohayunainstruccinsimpleparasumarelCarryalAcumulador;loquehayes
uncompuesta,ADC,quesumaunoperandoalAcumulador,yalavezlesumaelvalordel
Carry. Como lo nico que queremos es sumar el Carry, y nada ms, usamos ADC con un
operandodeCERO:ADC#0

29adc#0;Accumulateit
30braLoop

SilavariablesllegaCero,seterminaelprocedimiento,sumandoanteselCarryal
Acumulador,loqueproduceunIncrementosiloquesedesplazeraunUNO.

31Zero:adc#0;Accumulateit
32bra*

37) Programacin de un TONO en el BUZZER.


Recuerdequeestamosenunaseccinde"Miscelneos";estosprogramasseincluyencomo
EJEMPLO para cuando necesiten emplear funcionalidades similares. No estn construidos
con todas las tcnicas profesionales que se emplearon en las primeras secciones, que
culminaronconlasColasylasComunicacionesSeriales.

Sinembargo,sillegaanecesitarprogramarelBuzzerquetraelatarjetadedesarrollo
DEMOQE128,estaesunaGUAELEMENTAL.

NOTA: Este programa en Assembly Language lo adapt tomndolo de uno de Freescale:


PWM.c. FUNCIONA BIEN y ha sido empleado durante varios trimestres como base para
proyectostalescomoMorse,Piano,Walkman,generacindesonidosdiversos,etc.

Sinembargo,ahoraquefuiaescribirlaexplicacinlneaporlnea,encuentroqueen
PWM.c,yportantoaqutambin,seprogramacomosalidalalneaPTC0,sinqueeneste
momentoyoencuentreunajustificacinapropiadaparaesto.

Ustedespuedeneliminaresalnea,yagradecermereportensitodofuncionabien,para
removerlasdelcdigoenfuturasediciones.

["Laboratorios\Proy\Buzzer\Buzzer.asm"]
01;********************************************************************
02;Buzzer.asm;LuisG.UribeC.,D01L2012
03;DESCRIPTION:ThisprojectusesthePWMfunctionalityoftheTPM1
04;module.APWMsignalisgeneratedandwhentheMCUisinterrupted.
05;PTB5isconnectedtoBUZZERinDEMOQE128!!
06;********************************************************************
07NOLIST
08INCLUDE'derivative.inc'
09LIST;..storageandTHISisit'splace
10;
11;2)DEFINES

12ram:SETZ_RAMStart;$80

191

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

13rom:SETROMStart;$2080
14initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
15COP_Disable:EQU$42

16;********************************************************************
17;MAINPROGRAMHEADER:
18ABSENTRYMain
19ORGrom

20Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
21staSOPT1;..SystemOptions1
22ldhx#initStack;SetupSP
23txs;...
24;
25;MCU_Init
26lda#$20;EnableBusClocktotheTPWM1module
27staSCGC1
28clra;DisableunusedperipheralsBusclock
29staSCGC2
30;
31;GPIO_Init
32clrPTCD;Put0'sinPTC0port
33mov#$01,PTCDD;ConfigurePTC0pinasoutput
34;
35;TPM_configuration
36mov#$68,TPM1C1SC;Chan.1IntEn;PWMEdgeAlign.Or$24
37;*******************************
38;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
39;C1D1E1F1G1A1B1C2
40;20941976176016611480131911751047

41FREQEQU2094
42FREQ_4EQUFREQ>>2;25%DuttyCycle

43ldhx#FREQ;Really...itisPERIOD...
44sthxTPM1MOD
45ldhx#FREQ_4;25%DuttyCycle
46sthxTPM1C1V
47mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
48;MoreDividers:Table164in02MC9S08QE128RM(ReferenceManual)U.pdf
49;mov#%1111,TPM1SC;Bus_rate_clock/128=TPMClockSource
50;mov#%1110,TPM1SC;Bus_rate_clock/64=TPMClockSource
51;mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource

52;====================================================================
53cli
54bra*

55;********************************************************************
56;interruptVectorNumber_Vtpm1ch1TPM_ISR
57TPM_ISR:
58ldaTPM1C1SC;ClearTPWMflags

192

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

59bclr7,TPM1C1SC;Twostepflagacknowledgement
60rti
61;
62nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
63;This'nop'MAYberemovedforCW6.3...
64;
65;InterruptVectors

66ORGVtpm1ch1
67DC.WTPM_ISR
68ORGVreset
69DC.WMain;RESET.Maximumpriority.Asynch.
70END

COMENTARIOS a ["Laboratorios\Proy\Buzzer\Buzzer.asm"]:
LosgeneradoresdefrecuenciaqueempleamosenesteMCU,sonfundamentalmentelosPWM,
quegeneranseales"moduladas"poramplituddepulso,PulseWidthModulation.

Enparticular,seusalafuncionalidadPWMdelmduloTPM1.

04;APWMsignalisgeneratedandwhentheMCUisinterrupted.
05;PTB5isconnectedtoBUZZERinDEMOQE128!!

La inicializacin del MCU incluye habilitar el Bus Clock para el mdulo TPM1; a los
perifricos no utilizados se les deshabilita el BusClock. Usted debe revisar con el
ReferenceManual,silosvaloresaquprogramadosparahabilitarelTPMWM1sononolos
estndarcuandohayunPOR.Deseras,puedeeliminar(comoyasehizoenelcasodel
ADC)estecdigosinningnproblema

25;MCU_Init
26lda#$20;EnableBusClocktotheTPWM1module
27staSCGC1
28clra;DisableunusedperipheralsBusclock
29staSCGC2

LosiguienteesprogramarelterminalPTC0comosalida.

Comodijeanteriormente,NOencuentroahoraunaJUSTIFICACINapropiadaparaesto.

Luego de que usted logre que el programa funcione (TODOS funcionan!), eliminen esas
dos(2)lneasyreportesitodofuncionabien,paraprocederaremoverlasdelcdigo
enfuturasediciones.OsialguienencuentraalgnmotivoplausibleparahabilitarPTC0
comosalida...

YoimaginoqueesunaimprecisindelprogramaoriginalPWM.c
31;GPIO_Init
32clrPTCD;Put0'sinPTC0port
33mov#$01,PTCDD;ConfigurePTC0pinasoutput

193

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

La configuracin del TPM consiste en programar las interrupciones del Canal 1, y


selecciona "alineacin por Eje" para el PWM (Edge Align). Revise el Reference Manual
paraverquotrasalternativasexisten.

35;TPM_configuration
36mov#$68,TPM1C1SC;Chan.1IntEn;PWMEdgeAlign.Or$24

LosvaloresquecolocoenTPM1MOD(cfr.ReferenceManual)yenTPM1C1VparagenerarUNA
escaladelpiano(8notasBLANCAS,nohayNEGRAS),SONEMPRICOS(lanocheanteriora
laprimeravezquebamosausarlaescalamusical,melapascambiandovaloreshasta
lograrestalista.EnnuestroDEMOQE128,noesslocuestindeconocerlasfrecuencias
de la escala; hay que ver la RESPUESTA del transductor de sonido, o BUZZER). Usted
puede ajustar estas cantidades a sus necesidades pero... todos los proyectos, hasta
ahora,loshanusadoconxitorelativo.

RecuerdenqueestosvaloressondePerodo,nodeFrecuencia.

38;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
39;C1D1E1F1G1A1B1C2
40;20941976176016611480131911751047

Esaeslaescalacompleta.EnesteejercicioseGENERARUNASLANOTA.

41freqequ2094

AlgenerarPWM,unvalorfundamentaleslaFrecuenciadelaonda;elotroeselllamado
Dutty Cycle, que es el porcentaje, de 0% a 100%, que la seal debe estar en UNO.
Despusdeprobardurantealgntiempo,encontrexperimentalmentequeelDuttyCycle,
para obtener la mayor intensidad sonora (volumen) sobre el Buzzer de la tarjeta de
demostracin, DEMOQE128, era del 25% (1/4). Por eso el clculo de FREQ / 4. Esto es
absolutamente arbitrario y, a lo mejor, lo que funciona bien en mi transductor
piezoelctrico,puedenoserlomsapropiadoparaeldesutarjetadedesarrollo.Hay
queexperimentar.

42FREQ_4EQUFREQ>>2;25%DuttyCycle

NOTA:Recuerdequeaquelloslosclculostalescomoeldefinidoenlalnea42(FREQ>>
2),serealizanenAssemblyTime,noenRunTime;esdecir,loejecutaelAssembler,y
noelMCU.

SeprogramaentonceselPerodoenelregistroTPM1MOD(cfr.elReferenceManualpara
todaestaexplicacin)

43ldhx#FREQ;Really...itisPERIOD...
44sthxTPM1MOD

YenelregistroTPM1C1V,endondesedefineelDuttyCycle,colocamos1/4delvalor
delPerodo.

45ldhx#FREQ_4;25%DuttyCycle
46sthxTPM1C1V

194

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

EscogemoslaFuentedeRelojparaelTMP:

47mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource

Una lista adicional de posibles divisores es la siguiente, segn la Tabla 164 del
02MC9S08QE128RM(ReferenceManual)U.pdf

49;mov#%1111,TPM1SC;Bus_rate_clock/128=TPMClockSource
50;mov#%1110,TPM1SC;Bus_rate_clock/64=TPMClockSource
51;mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource

FinalmenteseactivanlasinterrupcionesenelCPU,ysesimulaunHALTconelBRA*:

53cli
54bra*

La Rutina de Interrupciones (TPM_ISR) realiza el PROTOCOLO de Reconocimiento de


Interrupciones(InterruptAcknowledge)paraesteperifrico,quetienedos(2)pasos,
siempre segn el Reference Manual: Se lee el registro TPM1C1SC, y a continuacin se
borra(BCLR)enesemismoregistro,elbit7(CH1F:ReadyFlagdelCanal1)

56;interruptVectorNumber_Vtpm1ch1TPM_ISR
57TPM_ISR:
58ldaTPM1C1SC;ClearTPWMflags
59bclr7,TPM1C1SC;Twostepflagacknowledgement
60rti

38) Un "WALKMAN" Elemental.


Hay una gran cantidad de aspectos que habra que programar para interpretar
automticamenteunamelodaenundispositivoelectrnico,tipoWalkman,perolosdos
esencialessonaltura(frecuencia)yduracin.

Porsimplicidad,esteejerciciopretendeinterpretarunacancindeUnaSolaVoz,con
un solo instrumento musical (a diferencia de las obras en general, que emplean
mltiples voces e instrumentos). Se basa en el programa anterior, al que le han
agregado varias cosas: una tabla que represente precisamente cada nota, o punto de
sonido,mediantelosdosaspectosreferidos,frecuenciayduracin.

Enrealidad,comovimosenelejercicioanterior,enlugardelafrecuenciasecolocar
el perodo, y se incluyen slo algunas de las Duraciones estndar de la notacin
musical (Redonda, Blanca con Puntillo, Blanca, Negra), que se han definido en
milisegundos,medianteunaasignacinaproximadayarbitraria,yquepuedemodificarse.

Una meloda se interpretar de la siguiente manera: Se comienza al principio de la


tabla, se lee el valor de altitud (que en nuestro caso, como ya dijimos, no es
frecuencia,sinosuinverso:perodo),seprogramaelosciladorqueestconectadoala
pequeacorneticadelDEMOQE128,oBuzzer,yseempleaelparmetrocorrespondientea
la duracin para llamar una de las rutinas de Esperar Milisegundos, incluida en la
libreradeTimersqueyaestudiamos.

195

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Alexpirarellapsoprogramado,seprocedeconlasiguienteentrada(dedosposiciones)
delatablayashastasuterminacin.

["Laboratorios\Proy\Buzzer\Walkman.asm"]
001;********************************************************************
002;Walkman.asm;LuisG.UribeC.,D01L2012L09D2013
003;DESCRIPTION:ThisprojectusesthePWMfunctionalityoftheTPM1
004;module.APWMsignalisgeneratedandwhentheMCUisinterrupted,
005;theDuttycycleisincrementedin1.PTB5isBUZZERinDEMOQE128!!
006;********************************************************************
007NOLIST
008INCLUDE'derivative.inc'
009LIST
010;
011;2)DEFINES
012ram:SETZ_RAMStart;$80
013rom:SETROMStart;$2080
014;;initStack:EQURAMEnd+1;$1800=$17FF+1.SP=$17FF
015;;COP_Disable:EQU$42
016;====================================================================
017;GlobalVariables
018ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<
019NOLIST
020include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
021LIST
022SongPtr:DS.W1
023NNotes:DS.W1
024NoteTime:DS.W1
025DCycle:DS.W1
026;********************************************************************
027;MAINPROGRAMHEADER:
028ABSENTRYMain
029ORGrom
030;*******************************
031;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)

032;C1D1E1F1G1A1B1C2
033;20941976176016611480131911751047
034C1:EQU2094
035D1:EQU1976
036E1:EQU1760
037F1:EQU1661
038G1:EQU1480
039A1:EQU1319
040B1:EQU1175
041C2:EQU1047

042Div:EQU0
043;StandardDurationsinMusic:
044;
045r:EQU2000>>Div;Redonda
046b_:EQU1500>>Div;BlancaconPuntillo

196

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

047b:EQU1000>>Div;Blanca
048n:EQU500>>Div;Negra

049;;;Song:DC.WC1,b_,D1,n
050;;;DC.WE1,b_,G1,b
051;;;DC.WC2,n,B1,n,A1,n,G1,n
052;;;DC.WA1,b,G1,b
053;;;DC.WF1,n,A1,n,E1,n,G1,n
054;;;DC.WF1,n,D1,n,C1,b
055;;;SongSizeEQU(*Song)/4

056;SongtableisformedbyNOTE&DURATIONpairof16bitvalues
057;
058Song:DC.WC1,b,D1,b
059DC.WE1,b,F1,b
060DC.WG1,b,A1,b,B1,b,C2,b
061DC.WC2,b,B1,b,A1,b,G1,b
062DC.WF1,b,E1,b
063DC.WD1,b,C1,r
064DC.W0,1
065SongSizeEQU(*Song)/4
066;*******************************
067Main:lda#COP_Disable;RSTE=0:PTA5isNOTfor~RESET
068staSOPT1;..SystemOptions1
069ldhx#initStack;SetupSP
070txs;...
071;
072;Thisisthe'MCU_Init'fromtheOriginalCprogram.However,Iam
073;..usingPOR(PowerOnReset)defaults:ClocktoEVERYperipheral.
074;
075;MCU_Init
076;;lda#$20;EnableBusClocktotheTPWM1module
077;;staSCGC1
078;;clra;DisableunusedperipheralsBusclock
079;;staSCGC2
080;
081;GPIO_Init
082clrPTCD;Put0'sinPTC0port
083mov#$01,PTCDD;ConfigurePTC0pinasoutput
084;
085;TPM_configuration
086mov#$68,TPM1C1SC;Chan.1IntEn;PWMEdgeAlign.Or$24
087mov#%1000,TPM1SC;Bus_rate_clock/1=TPMClockSource
088;
089Init8Timers;InitTimers&GloabalEnableCPUinter
090cli;..rupts(TPM&RTCarealreadyenabled)
091;====================================================================
092ldhx#SongSize;GetSongSize,constantrepresenting#of
093sthxNNotes;..NOTES;storeitintovariable'NNotes'
094beqEndSong;IfNNotesis0,finishthesong...
095ldhx#Song;GetAddressoftheSong:'#Song'itis!
096Loop:sthxSongPtr;StoreSong'sAddressintoSongPointer&

197

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

097ldhx,X;..usingit,loadthenextNOTEintoH:X
098sthxTPM1MOD;StoreintoTPM1MODtofixTPM1'sPERIOD
099sthxDCycle;StoreintoDCycletoo
100ldhx#DCycle;GetDCycleADDRESSintoH:Xtobeused
101lsr,X;..asapointertoDCycle.DivideDCycle
102lsr,X;..by4toget25%DuttyCycle
103ldhx,X;UsingDCycleaddressinH:X,getDCycle
104sthxTPM1C1V;..valueintoH:X,andmoveittoTPM1C1V
105;..tosettheDuttyCycle...
106ldhxSongPtr;GettheSongPointer;
107aix#2;..add#2topointtonextDURATION
108sthxSongPtr;..andsavenewvalue.
109ldhx,X;Usingthisnewaddress,getthenext
110sthxNoteTime;..NoteTIMEfromSongTable
111WaitMS_on0,NoteTime;NowTPM1generatesPWMpulsestodrive
112;..buzzer;Waithereforthedesiredtime
113ldhxNNotes;AtendgetNNotes,decreaseby1andsee
114aix#1;..iftheSongisdone.
115sthxNNotes;..
116beqEndSong;..
117ldhxSongPtr;Ifnot,loadaddressofnextSongtable
118aix#2;..possition,pointittothenextNOTE
119braLoop;..andLoopagain

120;====================================================================
121EndSong:
122clrTPM1C1SC;Chan.1IntDisable
123bra*;..andWaitForever

124;********************************************************************
125;InterruptVectorNumber_Vtpm1ch1TPM_ISR
126TPM_ISR:
127ldaTPM1C1SC;ClearTPWMflagsinthisTwostepflag
128bclr7,TPM1C1SC;..acknowledgementtoreenableTPM1INTs.
129rti;ReturnfromInterrupt

130;
131;RTCInterruptServiceRoutine
132RTC_INTERRUPT:
133TIMERS8ISR
134;
135nop;<<<NEEDEDbyCodeWarrior10.1&2(not6.3).INCREDIBLE<<<
136;This'nop'MAYberemovedforCW6.3...
137;
138;InterruptVectors
139ORGVtpm1ch1
140DC.WTPM_ISR
141ORGVrtc
142DC.WRTC_INTERRUPT
143ORGVreset
144DC.WMain;RESET.Maximumpriority.Asynch.
145END

198

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Laboratorios\Proy\Buzzer\Walkman.asm"]:
RecordarsiempreelsitioapropiadoparacadaINCLUDE:

017;GlobalVariables
018ORGram;<<<Putthis*BEFORE*'timers8HS.inc'<<<
019NOLIST
020include'timers8HS.inc';<<<TIMERS8:Code,Vars&Macros
021LIST

Haycuatro(4)variablesde16bits(WORDS):

SongPtr con el apuntador a la cancin (a la tabla que la representa, y que est


compuestaporPAREJASdevalores:PerodoyDuracin)

NNotes,quellevalacantidaddenotas(deDOSvalores)faltantesparafinalizarla
cancin

NoteTime,dondesealmacenatemporalmenteladuracindecadanota,paraemplearcon
facilidadlafuncindelalibreradeTimers

DCycle, en donde se calcula el Dutty Cycle para cada nota (empleando la misma
aproximacindelejercicioanterior)

022SongPtr:DS.W1
023NNotes:DS.W1
024NoteTime:DS.W1
025DCycle:DS.W1

Las definiciones de las notas (sus ALTURAS, aqu: sus perodos) son las mismas
introducidosenelejercicioanterior:

031;PIANOFREQUENCYTABLEFROMDO(C)...SI(B),DO(C)
032;C1D1E1F1G1A1B1C2
033;20941976176016611480131911751047
034C1:EQU2094
035D1:EQU1976
036E1:EQU1760
037F1:EQU1661
038G1:EQU1480
039A1:EQU1319
040B1:EQU1175
041C2:EQU1047
AcontinuacinsedefinenalgunasdelasDuracionesestndardelanotacinmusical(r:
Redonda,b_:BlancaconPuntillo,b:Blanca,n:Negra),enmilisegundos,comosedijo
antes,medianteasignacinaproximadayarbitraria.

Paramodificarconciertafacilidadestasduraciones,sehaincluidounparmetro,Div,
medianteelcualselaspuededividirpor2,4,etc.Asselograquelacancinvaya
msrpido,sieslodeseado:

199

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

042Div:EQU0
043;StandardDurationsinMusic:
044;
045r:EQU2000>>Div;Redonda
046b_:EQU1500>>Div;BlancaconPuntillo
047b:EQU1000>>Div;Blanca
048n:EQU500>>Div;Negra

Comoejemplo,nohemosincluidounaverdaderacancinsinounaESCALAquesubedesdela
notamsbaja,C1,hastalamsaltaC2,yluegoseregresahastaelprincipio.Para
finalizar,hemosagregamosalatabla,luegodelacancin(oescala),unaentradacon
un perodo de CERO y una duracin de un Milisegundos. Su propsito es que NO quede
sonandoindefinidamenteelBuzzer(CEROPerodolosilencia).

058Song:DC.WC1,b,D1,b
059DC.WE1,b,F1,b
060DC.WG1,b,A1,b,B1,b,C2,b
061DC.WC2,b,B1,b,A1,b,G1,b
062DC.WF1,b,E1,b
063DC.WD1,b,C1,r
064DC.W0,1
065SongSizeEQU(*Song)/4

Comosehasugerido,elNMERODENOTAS(enlatabla)localculaelAssemblerempleando
elsmboloSongSizequesecolocaLUEGOdelatablayqueenestecasotieneelvalor:

SongSize=(*Song)/4;

es decir, SongSize es igual a la posicin ACTUAL (*), que es justo la POSICIN


posterioralatabla,menoselPRINCIPIOdelatabla(Song),divididoporcuatro(4),
puescadaNOTAtienecuatro(4)BYTES.

Lainicializacin:GPIO_InityTPM_configuration,yalashemosrepasadovariasveces.

SeinicializanlosTimers:

089Init8Timers;InitTimers&GlobalEnableCPUinter
090cli;..rupts(TPM&RTCarealreadyenabled)

Yahorascomienzaelcdigonuevo,parainterpretarunacancin:

Primero se inicializa la variable NNotes, que indica cuntas notas faltan para
finalizarlacancin:

092ldhx#SongSize;GetSongSize,constantrepresenting#of
093sthxNNotes;..NOTES;storeitintovariable'NNotes'

SiNNotesfueraCERO,seterminaralainterpretacindelacancin:

094beqEndSong;IfNNotesis0,finishthesong...

200

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

LuegosealmacenaelPRINCIPIOdelacancin,esdecir,laDIRECCINdelatablaSong,
enlavariableAPUNTADORAparaeseefecto:SongPtr

095ldhx#Song;GetAddressoftheSong:'#Song'itis!
096Loop:sthxSongPtr;StoreSong'sAddressintoSongPointer&

Para comenzar, ese ser el PRINCIPIO de la cancin (o de la Tabla); luego ser la


posicinACTUALdelatabla;poreso,ahseestableceel"Loop".

EmpleandoelAPUNTADOR,seleeel"siguiente"valordelaNOTA,ALMISMOregistroH:X.

097ldhx,X;..usingit,loadthenextNOTEintoH:X

NOTA:EsGENIALpodertenerenH:XladireccindeloquesequierecargarENEL
PROPIOH:X!!!

Sealmacena,despus,elvalordeH:X:enelregistroTPM1MOD,quedefineelPERODO,y
enlavariableDCycle,paracalcularelDuttyCycle:

098sthxTPM1MOD;StoreintoTPM1MODtofixTPM1'sPERIOD
099sthxDCycle;StoreintoDCycletoo

LuegosecopiaLADIRECCINdeDCycle(#DCycle:NOTEEL#!!)enH:X,ycondosLSR,
Logical Shift Right, se divide el valor inicial por CUATRO (4) (que es el valor
EXPERIMENTALconelcualconseguquesonaraMEJORelBuzzerenMItarjetaDEMOQE128):

100ldhx#DCycle;GetDCycleADDRESSintoH:Xtobeused
101lsr,X;..asapointertoDCycle.DivideDCycle
102lsr,X;..by4toget25%DuttyCycle

Despus de dividir el Perodo por 4, se lo almacena en el registro TPM1C1V, que es


dondesedetermina,finalmente,elDuttyCycle:

103ldhx,X;UsingDCycleaddressinH:X,getDCycle
104sthxTPM1C1V;..valueintoH:X,andmoveittoTPM1C1V
105;..tosettheDuttyCycle...

Luegocargamosenelregistrondice,ladireccindelaSIGUIENTEnotadelacancin
(que,alcomenzar,eslaPRIMERAnota):

106ldhxSongPtr;GettheSongPointer;
Como cada nota est compuesta dedos valores: Altura (representada por su perodo: 2
BYTES)yporsuDuracin,2BYTEStambin,unavezqueseApuntaalaprimeranota(su
Perodo),hayqueapuntaralaDuracin;poresoseincrementaelH:XenDOS(2),que
esloquemideelPERODO:

107aix#2;..add#2topointtonextDURATION
108sthxSongPtr;..andsavenewvalue.

201

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

SealmacenatemporalmenteesenuevovalorenSongPtry,usandoesanuevadireccin,que
corresponde a la DURACIN (TIME), se carga ese valor en H:X (Genial modo de
Direccionamiento)yseloalmacenadondecorresponde:enNoteTime:

109ldhx,X;Usingthisnewaddress,getthenext
110sthxNoteTime;..NoteTIMEfromSongTable

Y,usandoesevalorNoteTime,sellamamirutinaWaitMS_on(timer0);ashemoslogrado
activarelvalordePerodo,yactivarelTimer0paraqueespereduranteNoteTime:

111WaitMS_on0,NoteTime;NowTPM1generatesPWMpulsestodrive
112;..buzzer;Waithereforthedesiredtime

Alfinalizar,sedecrementaelvalordeNNotes;seloalmacena(enNNotes),ysiyase
llegaCEROsesaledel"Loop"(BEQ)yseterminalacancin:EndSong:

113ldhxNNotes;AtendgetNNotes,decreaseby1andsee
114aix#1;..iftheSongisdone.
115sthxNNotes;..
116beqEndSong;..

SiNNotesNOlleganaCero,yportantolacancinNOsehaterminado,sevuelvea
cargarenelregistrondiceladireccindelaPRXIMAnota,H:X;sehacerapuntaresa
direccinalaSIGUIENTEnotaysevuelveal"Loop":

117ldhxSongPtr;Ifnot,loadaddressofnextSongtable
118aix#2;..possition,pointittothenextNOTE
119braLoop;..andLoopagain

Paraterminar,sedeshabilitanlasinterrupcionesdeTMP1,ysesimulaunHALT:

121EndSong:
122clrTPM1C1SC;Chan.1IntDisable
123bra*;..andWaitForever

La rutina de interrupciones, TPM_ISR, opera igual que en el ejercicio anterior y no


comentaremosaqumssobreella.

La rutina de interrupciones de la librera de Timers tambin funciona como de


costumbre.

39) "SWITCH", va "COMPUTED GOTO".


Una manera muy eficiente de ejecutar la funcionalidad equivalente al SWITCH del
lenguaje C, consiste en tomar la variable de Control del Switch, y en base a ella
saltaralcdigodelcorrespondienteCASE.Hayciertasvariacionesalrespecto;enel
siguienteejemplo,losCASEstienenqueserCONTIGUOS,del0enadelante:case0:case
1: case 2:, etc., lo cual sirve en una gran cantidad de ocasiones, en especfico,
cuandoseestnimplementandoFiniteStateMachines,FSM.

202

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

En este ejemplo, tambin, se ha supuesto que el nmero de posiciones o estados ser


siempre POTENCIA DE DOS. Si ese no es el caso, hay que reestructurar un poco el
programaparaacomodarlo.

Otras veces los CASEs pueden tener valores que no comienzan en Cero (0), o que sean
nmeroscualesquiera,nonecesariamenteconsecutivoscomoenelejerciciomssimple.
Estopuedesolucionarsedemuchasmaneras,porejemplo,medianteunaseriedeCBEQ.Lo
cualesmenoselegantequelasolucindelpresenteejercicio,peromsgeneral...

Este ejercicio est pensado para ejecutarse con el DEBUGGER, paso a paso, a fin de
poderintroducirlasentradasamano,vaelpuertoSIMULADOPTAD.Ustedpuedeemplear
losinterruptoresdelatarjetaDEMOQE128queusan,porejemplo,elPTC,ousarotra
variablepuestaenelprogramaparaesepropsito.

["Laboratorios\FSMFiniteStateMachines\ComputedGoTo.asm"]
01;*************************ComputedGoTo.asm*************************
02;LuisG.UribeC.,Implement"SWITCH";D17F2013J05D2013
03;1)UseCOMPUTEDGOTO(CasesAREsequential:0,1,2,...)
04;
05;ThisexampleisonlymeanttobeDebugged/Simulated.Forreal,you
06;..willneedtodebounceinputs,perhapsincludesome'InputReady'
07;..signal(debounced),useTimersandproducesomerequiredoutputs.
08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;2)DEFINES
15ram:SETZ_RAMStart;<<<TIMERS8:<<<
16rom:SETROMStart;HCS08ROMStart(Flash)

17initStack:EQU$1800
18COP_Disable:EQU%01000010;$42
19;====================================================================
20;3)GlobalVariables
21ORGram
22STATE:DS.W1
23;********************************************************************
24;BeginofCodeSection
25ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
26ORGrom
27;
28;***ALWAYS***includethefollowing4instructions

29Main:lda#COP_Disable
30staSOPT1;SystemOptions1
31ldhx#initStack;InitSP
32txs
33;
34clrSTATE;HIGHendalwayswillbe0intheexample

203

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

35;
36Forever:
37ldaPTAD
38and#LOW(Table_Mask);Makeinput<8(0..7),nomaterwhat
39lsla;Multiplyby2(Tableis2bytes/entry)
40staSTATE+1;>>>BIGENDIAN...REMEMBER???<<<
41ldhxSTATE
42ldhxTable,X;o=Table[ix];
43jmp,X

44;
45;THISISTHEWAYTODECLARE*TABLESOFADDRESSES*(Constants):
46;1:TheywillgoinROMFlash(constants...)
47;2:TheyhaveaNAME('Table'inthisexample)
48;3:Youpopulatetableswithvalues,usingDC.Wassemblerdirective,
49;becauseaddressesare16bitslong.
50;4:NORMALLY,youneedtoknowtheLENGHTofthetable.Soyou
51;putamarkerattheend:'Table_End:'inthisexample,the
52;assemblercalculateslenghtas:(Table_EndTable_Begin)/2
53;(YoudoNOTshallcalculateanythingtheassemblerwill!)

54Table:
55DC.WSTART,S1,S2,S3;Anysequenceforthisexample
56DC.WS2,S3,S2,START
57Table_End:
58TSIZE:EQU(Table_EndTable)/2
59Table_Mask:EQUTSIZE1;TSIZE*IS*apowerof2
60START:nop;'nop':ReplaceitwithYOURcode!
61braForever;'bra':useJMPiftoofaraway
62S1:nop
63braForever
64S2:nop
65braForever
66S3:nop
67braForever
68;
69;InterruptVectors
70dummy_isr:;<<<MustbeplacedinROMSpace
71rti
72ORGVswi;VswiandVreset
73DC.Wdummy_isr;SWI
74DC.WMain;RESET.Maximumpriority.Asynch.
75END

COMENTARIOS a ["Laboratorios\FSM-FiniteStateMachines\ComputedGoTo.asm"]:
AlprincipioseINICIAlavariabledeControl:STATE,de16bits(2Bytes),delacual,
enesteejercicioqueslotiene8estadosoposicionesenlatabla,sloseutilizarn
los 3 bits MENOS significativos y, en general, slo se emplear el BYTE MENOS
significativodeSTATE.Poreso,seborra(CLR)SUBYTE**MS**SIGNIFICATIVO:

34clrSTATE;HIGHendalwayswillbe0intheexample

204

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Recuerden: Esta mquina es BIG ENDIAN. Para borrar EL BYTE MS SIGNIFICATIVO de una
variable de 16 bits,como nuestra variable'STATE, hay que borrar la posicin STATE;
poreso',el'CLRSTATE'delalnea34.

OJO:
34clrSTATE;HIGHendalwayswillbe0intheexample
NOBORRATODALAVARIABLE'STATE',solosuparteMSSIGNIFICATIVA.

ElcicloinfinitoparaesteejerciciocomienzaleyendolavariabledeControl,PTAD,en
elacumulador,yasegurndosequeestdentrodelrangovlido,queparaesteejercicio
esentre0y7,inclusive:

36Forever:
37ldaPTAD
38and#LOW(Table_Mask);Makeinput<8(0..7),nomaterwhat

Comoesunrequisitoparaesteejemplo,quelatablaseasiemprepotenciadeDOS,seha
calculadomsabajoelvalor'Table_Mask',queesigualalapotenciade2quedefine
eltamao(OCHOenesteejercicio),MENOS1:SIETE,queenbinarioes:00..111.As,el

38AND#LOW(Table_Mask)

toma (LOW) los 8 bits menos significativos de 'Table_Mask' (00000111) y hace un AND
entreesaConstante(elNUMERAL:#)yelAcumulador,conloque,noimportaculseael
valoralimentado,siemprequedarconfinadoanmerosentre0y7,ambosinclusive.

LuegoquetenemoslavariabledeentradaapropiadamenteVALIDADA,lamultiplicamospor
DOS (LSLA) porque la tabla es de DIRECCIONES (a dnde Saltar) y en esta mquina las
direccionessonde16bits(DOSbytes)

39lsla;Multiplyby2(Tableis2bytes/entry)

Ese valor, que es la Entrada, confinada, multiplicada por 2, se la almacena en la


Variable STATE. Como slo estamos usando el Byte MENOS significativo de STATE, se la
almacena en 'STATE+1', porque esta mquina es BIG ENDIAN, y la posicin MENOS
SIGNIFICATIVAestDELTIMO:

40staSTATE+1;>>>BIGENDIAN...REMEMBER???<<<

Ahora,setomaelvalordeSTATE(16bits,deloscualesyahemosgarantizadoqueel
MSBesCero),selocargaenelregistrondice,H:X:

41ldhxSTATE
Yempleandoesendicecargamos,enelmismoregistrondice,H:X,elvalor'Table+
STATE'.Esevalorquesecarga(observebien!),correspondealaDIRECCIN,sacadade
laTabla,delarutinaadondehayqueSaltarparaejecutarloquecorrespondeaese
NmerodeCase,identificadoporlavariabledeControl!Finalmente,sesaltaadicha
rutina. Se emplea a fondo el direccionamiento Indexado. Pocos MCUs de 8 bits tienen
tantaexuberanciadeArquitectura!

42ldhxTable,X;o=Table[ix];
43jmp,X

205

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

VeamosahoracmoseestructuralaTabladeDirecciones.Enprimerlugar,lasentradas
en la Tabla son Direcciones de las diferentes Rutinas que han de materializar la
funcionalidad de cada Case; as que la Tabla normalmente ir en ROM (Flash). Podra
pensarse en tablas dinmicas, que recibieran sus valores en RUN TIME, pero no es el
caso de este ejemplo.Esas Tablas iran enRAM, y habra que inicializarlasmediante
cdigo.LasTablasenROM(Flash)lasinicializaelAssembler,yelQUEMADORdelcdigo
enelMPUlascopiainicializadasalaFlashdePrograma.

Segundo, las Tablas tienen una identificacin, o nombre, que en nuestro ejemplo es
"Table".

En caso de tablas de Direcciones, se inicializan con valores declarados mediante la


directivadeAssemblerDC.W(DefineConstantWord:16bits).

Casisiempreestilconocereltamaoolongituddelatabla,loquehemoscalculado
siempre de una manera simple y automtica: se coloca una etiqueta en la posicin
siguientealaltimadelatabla,selerestaladireccindelaposicindearranque,
lo cual nos da el tamao en BYTES. Si se desea calcular el tamao en Cantidad de
ELEMENTOS (en nuestro ejemplo, el nmero de direcciones almacenadas en la tabla), se
divideporelnmerodebytesquemidelaentidadalmacenada,enestecaso,sedivide
por2,puesdosbytestienecadadireccin:(Table_EndTable_Begin)/2

UstedNUNCAtienequehacerclculos;paraesoesttrabajandoenunaCOMPUTADORA.

Latablaparanuestroejemplo,quecontieneunasecuenciainventada,eslasiguiente:

54Table:
55DC.WSTART,S1,S2,S3;Anysequenceforthisexample
56DC.WS2,S3,S2,START
57Table_End:
58TSIZE:EQU(Table_EndTable)/2
59Table_Mask:EQUTSIZE1;TSIZE*IS*apowerof2

En otra localidad se colocan las rutinas que materializarn cada CASE. Pueden estar
colocadasantesodespusdeestaposicin,puedenestarseparadasportodoelprograma
(locual,sibienesposible,NOparececonveniente)oirencualquierorden:

60START:nop;'nop':ReplaceitwithYOURcode!
61braForever;'bra':useJMPiftoofaraway
62S1:nop
63braForever
64S2:nop
65braForever
66S3:nop
67braForever
Hemos reemplazado todo lo que sera el cdigo necesario para implementar cada uno de
losCASEs,porNOPs,queustedpuedecambiaravoluntadporlasrutinasnecesariaspara
susprogramasparticulares,segnseaelcaso.

NOTAS:

Encasoquelaetiqueta'Forever'(enelejemplo)estmuyapartada,porlacantidadde
cdigonecesarioparalosCASEs,enlugardeBRAForeverustedpuedecolocarJMP.

206

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Si el nmero de elementos de la tabla, NO es potencia de 2, habr que cambiar la


metodologaqueaquseaplic,deconfinarlasvariablesdeControlanmerosentre0
y7,medianteunANDconel#7.UnaformapuedeserComparandolavariabledecontrol
conlaparteBajaylaAltadelRANGOpermitidoparasuejemplo.

Es IMPORTANTE garantizar que su programa, aunque sea por error en la informacin de


entrada, NO saltar a ejecutar cdigo que no sea apropiado: Si la tabla tiene 5
entradas,saltaralaposicin6oala7...ESunerrorGRAVE.

Peroobserve:aunquelaInformacindeEntradanodebesobrepasarciertorango;sise
EXTRALIMITA por error en su adquisicin, procesarla mediante un AND, o empleando
comparaciones,paraobligarlaapermanecerconfinadadentrodeeserango,PUEDENOSER
LASOLUCIN.

Esdecir,enlavidareal,ambascosassonerrores:a)ejecutarunarutinaquesesabe
que NO se corresponde con la entrada, y que seguramente NI EXISTE, y b) ejecutar la
rutinaqueresultadeconfinarobligadamentealavariableaquepermanezcadentrodel
rangoacordado.

Porejemplo,silatablatiene8valores,delasposiciones0ala7,ylavariablede
Controlindica,porerrordelecturaoporequivocacindeloperador,etc.,quesedebe
ejecutarlaRUTINA"10"(%1010),seraunERRORGRAVEtratardeejecutardichaRUTINA
"10"delatabla,PORQUENOEXISTE!perotambinpuedeestarMUYMALejecutarlarutina
'DOS',queesennuestroejemploloqueresultaalhacerunANDentre%1010y%0111:
%0010.

Asqueenunejercicioreal,ustedtienequedecidirquhacersiseproduceunerror;
porejemplo,avisaraloperadoryqueltomeladecisin,tomarunvalor"estimado"
porunalgoritmoapropiado,tomarunvalormnimosiesquelavariableestpordebajo
del,omximosiseubicaporencimadeltecho,etc.Cadacasoserdistinto.PeroNO
puededejarquesuvariabledeControlobligueasuCPUaejecutarunarutinaqueusted
nisiquieraescribi.

40) La FBRICA de CHOCOLATES.


Este ejercicio est definido en el libro "Ingeniera Digital", que ha sido publicado
comopartedelcursodeArquitecturaI.Allpuedeverdequsetrata.Acontinuacin
seincluyelasolucin.

ObservequeMUCHOSejerciciosdeRedesCombinatorias,comolasolucinalproblemadel
EDPCENTER,quetambinseencuentraenellibro"IngenieraDigital",seresuelvende
unamaneraSimilaroIGUALalproblemadeLaFbricadeChocolates.

01["Laboratorios\Tables\FabricaDeChocolates.asm"]
02;********************************************************************
03;FabricaDeChocolates.asm,LuisG.UribeC.,V15F2013
04;SeehowtoreadaTable.UseHXregisterasindextotravel'Table'
05;inputcomesfromPTAD.YouneedtoMASKoutallnotusedbits.
06;UseANDwith0x07[%00000111;#LOW(Table_Mask)]toMask'input'.
07;MainloopreadsPTADvalues(youwillfakeinputsfromdebugger);
08;..readRESPONSESfromTable,andoutputthemto'output'variable
09;..(inreallife,youwilloutputthisvaluestotheoutputPORT)

207

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

10;
11;Includefiles
12NOLIST
13INCLUDE'derivative.inc'
14LIST
15;
16;2)DEFINES

17ram:SETZ_RAMStart;<<<TIMERS8:<<<
18rom:SETROMStart;HCS08ROMStart(Flash)

19initStack:EQU$1800
20COP_Disable:EQU%01000010;$42
21;====================================================================
22;3)GlobalVariables
23ORGram
24input:DS.W1;DS.W:HXregisterneeds16bitsvalues..
25output:DS.B1
26;********************************************************************
27;BeginofCodeSection
28ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
29ORGrom
30;
31;***ALWAYS***includethefollowing4instructions
32Main:lda#COP_Disable
33staSOPT1;SystemOptions1
34ldhx#initStack;InitSP
35txs
36;
37clrinput;HIGHendalwayswillbe0intheexample
38Forever:
39ldaPTAD;Besure:input<8(0..7)
40and#LOW(Table_Mask)
41stainput+1;>>>BIGENDIAN...REMEMBER???<<<
42ldhxinput
43ldaTable,X;o=Table[ix];
44staoutput;..
45braForever
46;
47;THEFOLLOWINGISTHEWAYTODECLARE*TABLESOFCONSTANTS*:
48;1:TheygoinROMFlash(constants...)
49;2:TheyhaveaNAME('Table'inthisexample)
50;3:Youpopulatetableswithvalues,usingDCassemblerdirective
51;4:NORMALLY,youneedtoknowtheLENGHTofthetable.Soyou
52;putamarkerattheend:'Table_End:'inthisexample,the
53;assemblercalculatesthelenghtas:'Table_EndTable_Begin'
54;(YoudoNOTliketocalculateanythingtheassemblercan!)

55Table:
56DC.B%100,%100,%100,%100;Stop,Half,Fullarebits
57DC.B%100,%010,%010,%001;..b2,b1,b0on'output'
58Table_End:

208

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

59TSIZE:EQUTable_EndTable
60Table_Mask:EQUTSIZE1;TSIZE*IS*apowerof2

61;
62;InterruptVectors
63dummy_isr:;<<<MustbeplacedinROMSpace
64rti

65ORGVswi;VswiandVreset
66DC.Wdummy_isr;SWI
67DC.WMain;RESET.Maximumpriority.Asynch.

68END

A estas alturas, ustedes deben poder comprender por completo la solucin que aqu
presento,sincomentariosadicionales.

41) TABLAS de DATOS; Implementacin del "FOR".


SemuestracomoleerunatablaparaefectuarconsecutivamentelaexpresinenC:o=
Table[ix];dentrodeuncicloFOR.

Enmuchasaplicacioneslavariabledesalida("o",output)serunPuertodelMCU,o
unainterfazdecomunicacionesseriales.Ustedsabrcambiarelejercicioparaacomodar
susnecesidadesespecficas.

Aprovechparadefinirlavariable"o"enelStack,cosaqueyaaprendimosahacer.

Adems,lavariable'ix',ndicedentrode"Tabla",sehadefinidocomoUNSIGNED.Usted
puede designar en sus programas el calificativo SIGNED. Es importante resaltar que
usteddebesaberaplicarlasRamificaciones(Branches)APROPIADOSPARACADAOCASIN.De
locontrarioustedhabrcometidolamismaTORPEZAqueAndrewS.Tanenbaumaldisear
sufallidoMIC(1,2y3)parasulibrodearquitectura.

01["Laboratorios\Tables\Tables0.asm"]
02;********************************************************************
03;Tables0.asm,LuisG.UribeC.,V15F2013
04;SeehowtoreadaTable.UseHXregisterasindextotravel'Table'
05;"o"varhasspacereservedinStack
06;SeehowtoimplementaFORLOOP
07;Inthisexample,'ix'varisUNSIGNEDchar

08;
09;Includefiles
10NOLIST
11INCLUDE'derivative.inc'
12LIST
13;
14;2)DEFINES

15ram:SETZ_RAMStart;<<<TIMERS8:<<<
16rom:SETROMStart;HCS08ROMStart(Flash)

209

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

17initStack:EQU$1800
18COP_Disable:EQU%01000010;$42
19;====================================================================
20;BeginofCodeSection
21ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
22ORGrom
23;
24;***ALWAYS***includethefollowing4instructions

25Main:lda#COP_Disable
26staSOPT1;SystemOptions1
27ldhx#initStack;InitSP
28txs
29;
30pshh;Reservespacefor"o"varstoredin1,SP
31For01_Init:;for(ix=0;ix<TSIZE;ix++)
32For01:;IPREFERLABEL'For01:',notFor01_Init
33clrx;INITFOR:ix=0;
34clrh;..
35For01_Tst:;Intheexample,ixIS'unsigned'char;
36cphx#TSIZE;..if(!(ix<TSIZE)gotoFor01_End;
37;..NOTE:HERE(ix<8)youmayuse'cpx'...
38bhsFor01_Exit;..Dontuse'BGT';use'BHS':ixISuchar
39For01_Code:
40ldaTable,X;o=Table[ix];
41sta1,SP;..
42For01_End:
43aix#1;ix++.HERE(ix<8)youmayuse'incx'...
44braFor01_Tst
45For01_Exit:
46pulh;restoreStack}//endmain
47bra*

48;
49;THEFOLLOWINGISTHEWAYTODECLARE*TABLESOFCONSTANTS*:
50;1:TheygoinROMFlash(constants...)
51;2:TheyhaveaNAME('Table'inthisexample)
52;3:Youpopulatetableswithvalues,usingDCassemblerdirective
53;4:NORMALLY,youneedtoknowtheLENGHTofthetable.Soyou
54;putamarkerattheend:'Table_End:'inthisexample,the
55;assemblercalculatesthelenghtas:'Table_EndTable_Begin'
56;(YoudoNOTliketocalculateanythingtheassemblercan!)
57Table:
58DC.B7,6,5,4,3,2,1,0
59Table_End:
60TSIZE:EQUTable_EndTable
61;
62;InterruptVectors
63dummy_isr:;<<<MustbeplacedinROMSpace
64rti
65ORGVswi;VswiandVreset

210

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

66DC.Wdummy_isr;SWI
67DC.WMain;RESET.Maximumpriority.Asynch.
68END

COMENTARIOS a ["Laboratorios\Tables\Tables0.asm"]
Despusdelarutinariainicializacin,sepasaareservarespacioenelStackparala
variable"o";estosehacedecrementandoelSP,medianteunpushdeunbyte:

30pshh;Reservespacefor"o"varstoredin1,SP

AcontinuacinelcdigogenricoparalosFOR,quecomoserecordar,tienena)una
parte de Inicializacin de variables, b) un Cuerpo con las instrucciones que usted
quiererepetirdentrodelcicloyc)unapartedeFinalizacin,luegodelacualest
laSalidadelFOR.

LaInicializacinaqu[for(ix=0;ix<TSIZE;ix++)]consisteencolocarenCERO
lavariablendice,queestenelStack:

31For01_Init:;for(ix=0;ix<TSIZE;ix++)
32For01:;IPREFERLABEL'For01:',notFor01_Init
33clrx;INITFOR:ix=0;
34clrh;..

Acontinuacinseverifica(TST)quetodavahaytrabajoquehacer,[ix<TSIZE;];si
yaseterminsevaalaseccindesalida,Exit:

35For01_Tst:;Intheexample,ixIS'unsigned'char;
36cphx#TSIZE;..if(!(ix<TSIZE)gotoFor01_End;
37;..NOTE:HERE(ix<8)youmayuse'cpx'...
38bhsFor01_Exit;..Dontuse'BGT';use'BHS':ixISuchar

Observe dos cosas importantes: en este ejemplo usted puede emplear simplemente
comparacionesconX,elLSBdelregistrondiceH:X,porque'ix'soloasumirvalores
inferioresa8.

Lo segundo es que no se pueden usar Ramificaciones (BRANCHES) de las definidas para


nmeros SIGNED, como BGT; tiene que revisar y emplear solamente las definidas para
UNSIGNED,comoBHS(o,sifueraelcaso,hayungrupodeellasdefinidasparaAMBOS:
SignedyUnsigned,comoBEQ,BNE,etc.)
La parte del Cuerpo de su programa en este caso es simplemente cargar de Table el
elementocorrespondientea'ix'yalmacenarlo(comoejemplo)enlavariabledesalida
'o':

39For01_Code:
40ldaTable,X;o=Table[ix];
41sta1,SP;..

EnlapartedefinalizacindelFORseincrementaelndice,[ix++]ysecontinaen
lapartedeTSTdelFOR,yelciclocontina:

42For01_End:

211

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

43aix#1;ix++.HERE(ix<8)youmayuse'incx'...
44braFor01_Tst

Se suele usar AIX para incrementar (#1) el ndice H:X directamente, pero en este
ejemploenparticular,enqueelvalordelndicenosobrepasarde8,tambinpodra
haberseempleadoINCX,queincrementasloX,laparteLSBdeH:X

ParafinalizarelFOR,sedejabalanceadoelStack(COSAFUNDAMENTAL)medianteelPULH,
ysesimulaunHALT:

45For01_Exit:
46pulh;restoreStack}//endmain
47bra*

En este sencillo ejemplo, la tabla est compuesta de 8 nmeros. Para diferenciarlos


perfectamentedel'ix',heescogidolos8nmerosenREVERSA.Ustedpuedeemplearlos
queleresultenmsconvenientes:

57Table:
58DC.B7,6,5,4,3,2,1,0
59Table_End:
60TSIZE:EQUTable_EndTable

PORLTIMO,sisuvariablenoestuvieraenStack,ustedtendraquedefinirlaenRAM
SpaceyelCdigocambiarasutilmentedeSTA1,SPenlalnea41,aSTAVAR:

Estocorrespondeaunextractodelprograma:
["Laboratorios\Tables\Tables1.asm"]
nolistado:

39For01_Code:
40ldaTable,X;o=Table[ix];
41STAVAR;..

Aplicaigualparaunpuertodesalida.Sifueraatransmitirlosvaloresdelatabla
poruncanaldecomunicacinserial,tendraquereemplazarlalnea41porelllamado
a una rutina de transmisin (lo que ya hicimos en los ejercicios dedicados a
COMUNICACIONES)

42) Last, but not Least: 8 Bits Rotate Left.


Comorecordar,lasinstruccionesdeROTATE(izquierdayderecha)dirigenalCarry,C,
elbitquesaledelavariable,yalimentanelotroextremoconC;estoproducenuna
rotacindeNUEVE(9)bits.

EsteejerciciomuestracmorealizarlamismainstruccinperodentrodeOCHO(8)bits.
CorrespondeaunRotateLEFT,perobastaconcambiarlasinstruccionesROLAyROLpor
las equivalentes hacia la derecha, RORA y ROR, para invertir el sentido del giro de
rotacin:

01["Evaluaciones\201301Ene\Evaluaciones\Ex#1\Rotate8.asm"]
02;********************************************************************

212

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

03;Rotate8.asm,LuisG.UribeC.,D17F2013
04;
05;Includefiles
06NOLIST
07INCLUDE'derivative.inc'
08LIST
09;
10;2)DEFINES
11ram:SETZ_RAMStart;<<<TIMERS8:<<<
12rom:SETROMStart;HCS08ROMStart(Flash)
13initStack:EQU$1800
14COP_Disable:EQU%01000010;$42
15;====================================================================
16;3)GlobalVariables
17ORGram
18var:DS.B1
19;********************************************************************
20;BeginofCodeSection
21ABSENTRYMain;Exportsymbol(ABSOLUTEAssemblyselect)
22ORGrom
23;
24;***ALWAYS***includethefollowing4instructions
25Main:lda#COP_Disable
26staSOPT1;SystemOptions1
27ldhx#initStack;InitSP
28txs
29;
30mov#%10101010,var
31;
32ldavar
33rola
34rolvar
35bra*
36;
37;InterruptVectors
38dummy_isr:;<<<MustbeplacedinROMSpace
39rti
40ORGVswi;VswiandVreset
41DC.Wdummy_isr;SWI
42DC.WMain;RESET.Maximumpriority.Asynch.
43END

COMENTARIOS a ["Evaluaciones\2013-01Ene\Evaluaciones\Ex#1\Rotate8.asm"]:
Variablequeestarsujetaalarotacinde8bits:

17ORGram
18var:DS.B1

Inicializacinconunvalorarbitrario:
bits76543210
30mov#%10101010,var

213

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Se carga 'var' en el Acumulador y se rota el Acumulador a la izquierda, lo cual


almacenaelbit7de'var'enelcarry,C:

32ldavar
33rola

ResultandodespusdelROLAen:

Acc=%0101010x
C=1(originalbit7de'var')

La 'x' en el bit0 del Acc es porque el valor del carry C, es indeterminado para
comenzar.

Ahora se rota 'var' a la izquierda, con lo cual el C, que era el bit7 de 'var',
alimentasubit0:

34rolvar
35bra*

Resultandoen:

var=%01010101(ROTATELEFTenOCHOBITS)
C=1(peroyanoseusams)

214

Captulo

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

PROGRAMACIN EN "C"
Unix, Linux, iOS, Windows, QNX... hacen del lenguaje C el
ms usado desde 1970 (44 aos). Ningn otro ostenta esa marca.

NOTAS INICIALES

ugieroencarecidamentequecadavezqueencuentrealgnaspectodelLenguajeCen
losejerciciosqueacontinuacinpresento,queustedNOENTIENDA,loANOTEpor
aparte, Y ME HAGA LLEGAR LA LISTA COMPLETA AL FINALIZAR la lectura de esta
seccincorrespondientealLenguajeC.

Servir para QUEJARME NUEVAMENTE a ver si logramos que CAMBIEN DE UNA VEZ LOS DOS
CURSOSDEPROGRAMACIN.
YaustedledarunaideaDEMUCHASCOSASQUELEFALTANPORAPRENDERDELLENGUAJE.En
su profesin, ES MUY IMPORTANTE MANEJAR EL "C", y aqu YA NO LE ENSEARN MS
PROGRAMACIN. As que le corresponde a usted estar DESCONTENTO y... ESTUDIAR POR SU
CUENTA!

DNDE ESTAMOS

na vez que hemos aprendido los aspectos ms importantes de la Arquitectura,


que resumo a continuacin, para estudiar las cuales nos hemos auxiliado con
ejercicios hechos en el Lenguaje Ensamblador, se justifica poco trabajar en
Assembler, y menos como profesionales. Slo utilizamos el ASM como vehculo
paracomprenderyaplicarlossiguientesconceptosimportantes:

ConfiguracionesdelasmquinasdeVonNeummanvs.lasHarvard
ClasesyrelevanciadeconjuntosdeinstruccionesCISCyRISC
Poderoyabundanciadelosmodosdedireccionamiento
ImportanciadelosmtodosdeEntradaySalida
ElementosdeinformacincomoelStack
Definicindevariableslocales,enelStack
Usodemtodosrecursivos
Direccionamientosindexados,vaSPyvaregistrondiceH:X
Interrupciones
Interrupcionesanidadas
Inversindeprioridades

215

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

HabilitacindeinterrupcionesaciertaalturadelasISR
AplicacindeinstruccionestanimportantescomoelSWI
UsodeTPAyTAPparaguardarelProcessorStatusWord

EnelreadelaaplicacindeMicrocontroladoresalossistemasEMBEBIDOS,elusodel
lenguaje"C"estmuyextendido.OtrosqueseempleanenmenorescalasonJava,ciertos
BASICs,FORTH...
PoresointrodujelaprogramacindeMC9S08QE128empleandoel"C",queesellenguaje
usadoenloscursosmsavanzadosdeArquitecturayLaboratoriodeProyectos.

GENERALIDADES

ividiremoslosejerciciosdeCentrespartes:Introduccin,conlosprogramas
ms simples, comparados con los similares en Assembler; el manejo de
temporizadores,enlaquepresentomilibreradeTimers,confuncionalidades
casiexactasalasdeelcaptuloanterior;lalibreradedeComunicaciones
Seriales, iguales a su contraparte en ASM, y la librera para el manejo de Colas,
imprescindibleparaoperarapropiadamentelasComunicacionesconflexibilidad.

Lascarpetasendondeseencuentranlosejerciciosintroductoriosson:
LabsC\Fibonacciy
LabsC\Lab1

43) Programa INTRODUCTORIO en C, para HCS08, Comparativo con ASM.


Consulte el programa Laboratorios\Lab1\02Fibonacci.asm como referencia para nuestro
programaintroductorioenC.Alprincipio,lasdiferenciasentrelosdosprogramasson
mnimas, segn se dar cuenta, pero a partir de 'mainLoop', los dos son (casi)
IDNTICOS.

["LabsC\Fibonacci\060Fibonacci.c"]
01//Fibonacci.c(02Fibonacci.asm),LuisG.UribeC.,M10D2013
02//******************************************************************
03//02Fibonacci.asm,LuisG.UribeC.,V10A2009V08J2012
04//ADAPTEDfrom:HCS08RS08_Assembler_MCU_Eclipse.pdf,Listing4.1
05//
06//Includefiles
07#include"derivative.h"//Includeperipheraldeclarations
08#include"Fibonacci_.h"

09//
10//Definicindevariables(ds:bytepordefecto)

11byteCounter;
12byteFiboRes;//Aquvalarespuesta

13voidmain(void)/*()*/
14{
15mainLoop:
16clra;

216

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

17cntLoop:
18inca;
19cbeqa(14,mainLoop);//Largervaluescauseoverflow
20sta(Counter);//Updateglobalvariable
21bsr(CalcFibo);
22sta(FiboRes);//Storeresult
23lda(Counter);//..ActivateBREAKPOINTheretosee..
24//..123581321345589144233
25bra(cntLoop);//Nextround

26for(;;){/*EMPTYFOR*/}
27}//endmain

28//==================================================================
29//FunctiontocomputeFibonaccinumbers.ArgumentisinA

30voidCalcFibo()
31{
32dbnza(fiboDo);//FibonacciDo
33inca;
34rts;
35//
36fiboDo:
37psha;//Thecounter
38clrx;//Secondlast=0
39lda(0x01);//Last=1
40//
41FiboLoop:
42psha;//Pushlast
43txa;
44add(1,sp);
45pulx;
46dbnz(1,sp,FiboLoop);

47//
48FiboDone:
49pulh;//Releasecounter
50rts;//ResultinA
51}//endCalcFibo()

COMENTARIOS a ["Labs-C\Fibonacci\060Fibonacci.c"]:
LamagiaquenospermitehacerunprogramaenC,queseVcasiIGUALalequivalenteen
Assembler, y que CORRE "IGUAL" (puede simularlo...) se encuentra en el include file:
Fibonacci_.h, que tiene las definiciones que mimetizan el ASM en C. Lo analizaremos
posteriormente.

Adelante, cuando comencemos en serio, hablaremos en detalle acerca de los Include


files;porelmomentoomitocomentarlos.

Ladefinicindevariables,queenASMeran:"ds",bytepordefecto:

217

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

11byteCounter;
12byteFiboRes;//Aquvalarespuesta

Sabeques"byte"?LASSUPOSICIONESNUNCAPUEDENCONVERTIRSEENINFORMACIN.

SIUSTEDAVANZASINESCLARECERLASCOSASQUENOSABE,NOLEVAAIRBIENENLAVIDA

La definicin de (casi) todo lo que tiene que ver con este MCU se encuentra en
"mc9s08qe128.h".YotengounaversinREDUCIDA:"mc9s08qe128U.h",fcildeconsultar.
Enparticular,allfiguran:

typedefunsignedcharbyte;
typedefunsignedintword;

ElcomienzoenASMeraen'Main';aqu:

13voidmain(void)/*()*/

ElcicloprincipalsellamaigualenASM,ylasinstruccionesaquloMIMETIZANdeuna
manera casi IGUAL. Inclusive, como los punto y comas se usan en ASM para comenzar
COMENTARIOS, y en C para terminar 'SENTENCES', podemos rearreglarlos (;) para que se
veancomoelcomienzodeloscomentariosenASM:

15mainLoop:
16clra;//comienzodecomentario
17cntLoop:
18inca;//..tantoenASMcomoen...C!

Aqu viene una DIFERENCIA: aunque no es imposible evitar los parntesis que se
necesitanenC,peronoenASM,paraelllamadodelassubrutinas,noesfcil,porlo
queloshemosdejado...:

19cbeqa(14,mainLoop);//Largervaluescauseoverflow
20sta(Counter);//Updateglobalvariable
21bsr(CalcFibo);
22sta(FiboRes);//Storeresult
23lda(Counter);//..ActivateBREAKPOINTheretosee..
25bra(cntLoop);//Nextround

PoresodecimosqueelresultadoesCASIidntico.

LafuncintambinestmimetizadademaneraCASIigual,as:

30voidCalcFibo(){
32dbnza(fiboDo);//FibonacciDo
33inca;
34rts;

36fiboDo:

218

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

37psha;//Thecounter
38clrx;//Secondlast=0
39lda(0x01);//Last=1

41FiboLoop:
42psha;//Pushlast
43txa;
44add(1,sp);
45pulx;
46dbnz(1,sp,FiboLoop);

48FiboDone:
49pulh;//Releasecounter
50rts;//ResultinA

["Labs-C\Fibonacci\Fibonacci_.h"]:
Analicemosahoraelincludefile:

["LabsC\Fibonacci\Fibonacci_.h"]
01//==================================================================
02//Fibonacci_.h(02Fibonacci.asm),LuisGUribeC,S09N2013M10D2013

03//MimicCPURegisters
04byteA;//UseAasacounter
05byteX;
06byteH;

07#defineclraA=0
08#defineincaA++
09#definecbeqa(v,l)if(A==v)gotol
10#definesta(v)v=A
11#definebsr(l)l()
12#definelda(v)A=v
13#definebra(l)gotol
14#definedbnza(l)if(A)gotol
15#definedbnz(c,v,l)if(stack[v+c]=1)gotol
16#definertsreturn
17#defineMAX_SP16
18#defineclrxX=0
19#definetxaA=X
20#defineadd(n,v)A=A+stack[v+n]
21#definepshastack[sp]=A
22#definepulxX=stack[++sp]
23#definepulhH=stack[++sp]

24wordstack[MAX_SP];
25wordsp=MAX_SP1;

26voidCalcFibo();

219

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Fibonacci\Fibonacci_.h"]:
["LabsC\Fibonacci\Fibonacci_.h"]:
Como en C no tenemos acceso a los registros internos del CPU, los definimos como
variables:

04byteA;//UseAasacounter
05byteX;
06byteH;

UnaseriedeMACROS(enC),definenlasinstruccionesdelHCS08,medianteoperaciones
enCquesimulenelcomportamientooriginal.Porejemplo,'clra'enCsera:A=0

07#defineclraA=0

El BSR indica como parmetro, cul es el nombre de la subrutina a la que se quiere


saltar, bsr(l); la codificacin es simplemente el "Label", o nombre de la rutina,
seguidoporungrupodeparntesis:l()

11#definebsr(l)l()

Ademsescogunejercicioqueemplearecursin,asquevernquesimulelStackcon
un arreglo de Words. Para decrementar la variable que est en el Techo del Stack, y
saltaraun"Label":

15#definedbnz(c,v,l)if(stack[v+c]=1)gotol

EltamaodelStacklodefinoarbitrariamenteen16:

17#defineMAX_SP16

SumarlealacumuladorunavariabledinmicamentedefinidaenelStack:

20#defineadd(n,v)A=A+stack[v+n]

ManipularelStack(pushypop)paraelAcumuladoryelregistrondiceH:X

21#definepshastack[sp]=A
22#definepulxX=stack[++sp]
23#definepulhH=stack[++sp]

LadefinicindelStack,yladefinicineinicializacindelStackPointerSP:

24bytestack[MAX_SP];
25bytesp=MAX_SP1;

Elprototipodelafuncinrecursiva:
26voidCalcFibo();

NOENTIENDEALGUNODELOS#define?OTRASDECLARACIONES?

TIENEQUEESTUDIAR"C"

220

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

44) FIBONACCI PROGRAMADO EN C, NORMALMENTE, PARA COMPARAR


["LabsC\Fibonacci\090FibonacciOK.c"]
01//******************************************************************
02//FibonacciOK.c(090FibonacciOK.c)LuisGUribeC,D10N2013M10D2013
03//
04//Includefiles
05#include"derivative.h"//Includeperipheraldeclarations
06#include"FibonacciOK_.h"
07
08//******************************************************************
09voidmain(void)/*()*/
10{wordi,first=0,last=14;
11volatilewordfibonacci;
12volatilebytetmp;
13
14//
15//>>>ALWAYSincludethefollowing2lines
16//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
17
18#defineCOP_Disable0x42
19SOPT1=COP_Disable;//SystemOptions1
20
21//
22//Mainloop
23
24for(i=first;i<last;i++){
25fibonacci=fib(i);
26tmp^=tmp;
27}//BREAKPOINTheretosee:123581321345589144233
28
29for(;;){/*EMPTYFOR*/}
30
31}//endmain()
32
33//
34wordfib(wordn)/*()*/
35{
36//returnn<2?n:fib(n2)+fib(n1);//Extended
37returnn<2?1:fib(n2)+fib(n1);//Conventional
38}

COMENTARIOS a ["Labs-C\Fibonacci\090FibonacciOK.c"]:
EsteprogramaesCestndarynoameritamscomentarios.

NOENTIENDEELOPERADORTERNARIO?NISABESEALARCULES?

TIENEQUEESTUDIAR"C"

221

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

45) EXPONENCIACIN POR MULTIPLICACIONES Y SUMAS SUCESIVAS: WHILE


["LabsC\Lab1\010Lab0e1.c"]
01//******************************************************************
02//010Lab0e1.c:EXPONENCIACIN.LuisG.UribeC.M10D2013
03//**UsaELSTACK;>>>SOLO<<<VARIABLESDINMICAS**
04//******************************************************************
05//IncludeFiles
06#include<hidef.h>//ForEnableInterruptsmacro
07#include"derivative.h"//Includeperipheraldeclarations

08#include"several_U.h"//Def:CpuIntEn,CpuIntDsb,EOF,Wait

09//******************************************************************
10voidmain(void)/*()*/
11{bytebase=2,exponent=5;//EXAMPLE2^5=32.See3^5=243
12byteresultExp=1;
13bytemultiplicand,multiplier,resultMpy;

14while(exponent){//...byrepeatedmultiplications
15multiplier=base;
16multiplicand=resultExp;
17resultMpy=0;
18while(multiplier){//...byrepeatedadditions
19resultMpy+=multiplicand;
20}
21resultExp=resultMpy;
22}

23Wait(0);//WaitforEver
24}

COMENTARIOS a ["Labs-C\Lab1\010Lab0e-1.c"]:
EsteprogramaesCestndar,portantonoameritamscomentarios.

46) EXPONENCIACIN, MULTIPLICACIONES Y SUMAS SUCESIVAS: FUNCIONES


["LabsC\Lab1\020Lab0e2Sub.c"]
01//******************************************************************
02//020Lab0e2Sub.c:EXPONENCIACIN.LuisG.UribeC.J21N2013
03//**UsaELSTACK>>>SOLO<<<VARIABLESDINMICAS**
04//******************************************************************
05//IncludeFiles
06#include<hidef.h>//ForEnableInterruptsmacro
07#include"derivative.h"//Includeperipheraldeclarations

08//
09//FunctionsPrototypes
10byteexpo(bytebase,byteexponent);
11bytemply(bytemultiplicand,bytemultiplier);

222

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

12//******************************************************************
13voidmain(void)/*()*/
14{bytebase=2,exponent=5;//EXAMPLE2^5=32.See3^5=243
15volatilebyteresultExp;

16resultExp=expo(base,exponent);

17Wait(0);//WaitforEver
18}

19//
20byteexpo(bytebase,byteexponent)/*()*/
21{byteresultExp=1;

22while(exponent){//...byrepeatedmultiplications
23resultExp=mply(resultExp,base);
24}
25returnresultExp;
26}

27//
28bytemply(bytemultiplicand,bytemultiplier)/*()*/
29{byteresultMpy=0;

30while(multiplier){//...byrepeatedadditions
31resultMpy+=multiplicand;
32}
33returnresultMpy;
34}

COMENTARIOS a ["Labs-C\Lab1\020Lab0e-2Sub.c"]:
EsteprogramaesCestndarynoameritamscomentarios.

47) EXPONENCIACIN, FUNCIONES: PARA VISUAL STUDIO


["LabsC\Lab1\030Lab0e2SubVisualStudio.c"]
01//******************************************************************
02//030Lab0e2SubVisualStudio.cEXPONENCIACINLG.UribeC.J21N2013
03//**UsaELSTACK;>>>SOLO<<<VARIABLESDINMICAS**
04//******************************************************************
05#defineWait(e)while(!(e))
06typedefunsignedcharbyte;

07//
08//FunctionsPrototypes
09byteexpo(bytebase,byteexponent);
10bytemply(bytemultiplicand,bytemultiplier);

11//******************************************************************
12voidmain(void)/*()*/
13{bytebase=3,exponent=5;//EXAMPLE2^5=32.See3^5=243

223

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

14volatilebyteresultExp;

15resultExp=expo(base,exponent);

16Wait(0);//WaitforEver
17}

18//
19byteexpo(bytebase,byteexponent)/*()*/
20{byteresultExp=1;

21while(exponent){//...byrepeatedmultiplications
22resultExp=mply(resultExp,base);
23}
24returnresultExp;
25}

26//
27bytemply(bytemultiplicand,bytemultiplier)/*()*/
28{byteresultMpy=0;

29while(multiplier){//...byrepeatedadditions
30resultMpy+=multiplicand;
31}
32returnresultMpy;
33}

COMENTARIOS a ["Labs-C\Lab1\030Lab0e-2SubVisualStudio.c"]:
Este programa es C estndar para ser procesado por Visual Studio, y no amerita ms
comentarios.

48) PRIMER PROGRAMA PARA HCS08: MINIMUM C PROGRAM


["LabsC\lab1\00a_l1.c"]
01//******************************************************************
02//00a_L1.c,MINIMUM'C'ProgramforHCS08,J21N2013
03//LuisG.UribeC.,ForCodeWarrior10.3
04//==================================================================
05
06voidmain(void)/*()*/
07{
08for(;;){
09/*EMPTYFOR*/
10}
11}

COMENTARIOS a ["Labs-C\lab1\00a_l1.c"]:
Como ya se indic, FORMA y PRESENTACIN deCdigo en nuestro trabajo, es FUNDAMENTAL
para la vida de los proyectos. Los programas deben poder entenderse, por quien los
hace,cuandovuelvaamirarlos,yporlaspersonasquevengandespusamodificarloso
repararlos.

224

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Paraesoserequieren,entreotrascosas,comentariostiles,resaltantesyclaros.

IgualqueenprogramasescritosparaotrosLenguajes,enlasprimeraslneassecoloca
el Nombre del programa, su propsito, para qu plataforma y qu revisin
(identificacinquepermitellevarlapistadelasmodificacionesqueselehanhecho);
hay que incluir siempre fechas que indiquen el comienzo del programa, cundo se lo
modificyladatacindelarevisinactual.Cuandoesimportante,hayqueagregaruna
lista de fechas e indicar explcitamente qu cosas se aadieron, se quitaron o se
modificaron. Tambin,las iniciales de lapersona quehizo cambios en el cdigo, que
permitaidentificarlasparasaberaquinpreguntarsifueranecesario.

02//00a_L1.c,MINIMUM'C'ProgramforHCS08,J21N2013
03//LuisG.UribeC.,ForCodeWarrior10.3

Programa desarrollado el Jueves 21 de Noviembre de 2013, para el CodeWarrior 10.2


(ahorasesabequefuncionatambinenCW10.5).

SIEMPRE hay que indicarle al CPU dnde comienza su cdigo pero, a diferencia del
trabajoqueyahicimosanteriormenteenAssembler,aqueselcompiladordeC,ylas
dems herramientas asociadas a l y a su entorno de desarrollo, como el Linker, el
AbsoluteLoader,etc.)losquedeterminanladireccindearranque(manejoautomtico
delosVectoresdeInterrupcin).GraciasaDios.

Nohaymuchomsquesepuedaagregarparaexplicaresteejerciciotansencillo.

06voidmain(void)/*()*/
07{
08for(;;){
09/*EMPTYFOR*/
10}
11}

NOCOMPRENDEALGUNODELOSELEMENTOSDEESTEPROGRAMA?DESISTA!

NOENTIENDEELFOR?TIENEQUEESTUDIAR"C"

49) PROGRAMA EN C PARA HCS08, UN POCO MS TIL


El programa anterior compila bien (aun cuando no hace nada ms; es una forma
equivalente al "BRA *" que hemos usado ya antes), hay un par de COSAS QUE SIEMPRE
TENEMOSQUEAGREGARENNUESTROSPROGRAMAS,ylasrevisaremosacontinuacin:

["LabsC\Lab1\01c_L1.c"]
01//******************************************************************
02//01c_L1.c,SmallCprogramM10D2013
03//LuisG.UribeC.,ForCodeWarrior10.3
04
05//
06//IncludeFiles
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
09

225

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

10//******************************************************************
11voidmain(void)/*()*/
12{
13bytevar;//Dependingonoptimizationoptions,
14//..Ccompilermaylearnthatnothing
15var=0;//..isrealybeingdone,andreplace
16while(1){//..var,orallyourcodeforempty/
17var++;//..null,block.Ifvarisnotseen
18}//..inDebugremovesomeoptimization
19}//..declaring:volatilebytevar;

COMENTARIOS a ["Labs-C\Lab1\01c_L1.c"]:
Losdos"includefiles"listadosacontinuacin,casisiempreseincluyen.

07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations

En "derivative.h" CodeWarrior incluye la particularizacin del MCU SUYO. As, los


programasNOcambiansisonparaunouotroMCU;yCWparametrizaenesteIncludeFile
todoloquetienequeverconcadaMCUenparticular.

Porejemplo,paranuestromicro,laseccinmsimportanteen"derivative.h"es:

#include<mc9s08qe128.h>

<hidef.h>(HardwareInterfaceDefinitions)seusamenos,yaquefundamentalmenteloque
incluyesondefinicindeMacrosparalahabilitacindeInterrupciones.Msadelante
veremoscmomanejamosnosotrosestasfuncionalidades.

Elejercicioloquetratadehacer,ensusimplicidad,esincrementarpermanentemente
unavariable'var',detipo'unsignedchar'(byte).

Laaclaratorioquehayquehacer,paraqueustedesrecuerdensusCONOCIMIENTODEC,es
queelCompiladorpuededarsecuenta,dependiendodelasopcionesdeoptimizacin,que
nosehaceNADAcon'var':apesardeincrementarla,nadielausa.Asque,comobuen
"optimizador", puede quitar la variable por completo, y si yo hubiera diseado el
Optimizador,eliminaraTODOELCDIGO.

Como ustedes deben saber, de sus cursos de C, pueden deshabilitarse las opciones de
OPTIMIZACIN para que el compilador NO elimine ni la variable intil, ni el cdigo
INTIL.

Otra forma que ustedes debieron aprender en sus cursos del lenguaje, es que si se
declaraesavariablecomo"volatilebytevar;",elcompiladorasumirque,sinquel
entiendacmo,esavariableserusadaenalgunaotrapartequeldesconoce(como,por
ejemplo,siassehacereferenciaaunPuertoDigitaldeSalida:Elentornoexterno
USAR los valores calculados DENTRO del programa, aunque no se haga evidente para el
compiladorqueestoseaas.

13bytevar;//Dependingonoptimizationoptions,
14//..Ccompilermaylearnthatnothing

226

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

15var=0;//..isrealybeingdone,andreplace
16while(1){//..var,orallyourcodeforempty/
17var++;//..null,block.Ifvarisnotseen
18}//..inDebugremovesomeoptimization
19}//..declaring:volatilebytevar;

NoteenlosprogramasenC,similarmentealoquehicimosenloscdigosenAssembler,
lamuyajustadalneaendondesecolocanloscomentarios.Enprincipio,//comienzaen
la columna 32. Y aqu tambin puede haber ocasiones en las que haya que mover los
comentarios,peromientrasmsestandarizadoestlaformadepresentacindelcdigo,
mejorparatodos.

50) "INTERRUPTS" EN EL LENGUAJE C


Las Interrupciones NO forman parte del lenguaje C, ni tampoco una gran cantidad de
Extensiones,comolamanipulacindeapuntadores,identificndoloscomo'far'o'near',
o los Vectores de Interrupcin, o el manejo de memoria Segmentada mediante la
aplicacin de Modelos: Short, Tiny, Large, Medium, Data. (SABE USTED LO QUE
SIGNIFICAN?)

Muchos dispositivos dividen su memoria en Segmentos; por ejemplo, los modelos de la


escalabajadelafamilia0x86deIntel.Ellosusan16bitsdedireccin,conlocual
puedenaccederaunmximode64KBytes(65536).Medianteunregistroqueindicadnde
comienzaunSegmento(ycuyovalorpuedealterarsedemaneradinmica,paraseleccionar
en Run Time VARIOS Segmentos de memoria), se puede llegar hasta posiciones mucho ms
alldelos64KBdelmodelo.ElPCoriginaltena640KBytesdeRAM(nollegabanial
Megabyte).

En Intel hay 4 registros de Segmento, con una funcin similar, llamados CS, Code
Segment; DS, Data Segment, SS, Stack Segment y EX, Extra Segment. El CS confina el
cdigodelprograma,quehadesercapturadomedianteelCSyelPC(ProgramCounter).

EnAssembler,sielprogramaesmsgrandeque64KB,seprogramaelCSy,enelmomento
enquesedeseasaltaraunaposicinqueestfueradeeseSegmento,sereprogramael
CSparautilizarotros64KB.Lamanipulacinsuelenosermuysencilla,yaquesise
cambiaelCS,DESAPARECENlasinstruccionesqueestnhaciendolareprogramacin,pero
haytrucosqueseacostumbran.

LociertoesqueparatrabajarenC,sielprogramaesmsgrandequeunSegmento,una
maneradeindicarlealcompiladorquelsehagacargodeesetrabajodereprogramacin
delCSes,porejemplo,definiendoapuntadoresquepuedanbarrermuchomsdelos64KB
(porejemplo,TODAlamemoria).Laformaesmedianteelindicativo'far',as:

farchar*ptr;

As,elcompiladorseencargadeirhaciendoeltrabajoqueenAssemblercorrespondera
alprogramador,deverificarsicadadireccinest,ono,confinadaaunsegmento.En
caso de no estarlo, el compilador incluye cdigo para la reprogramacin del CS y la
transicin,invisibleparaelprogramador,aotroSegmento.

AlgoparecidoocurreconelDS,oSegmentodeDatos.EldeCdigoverificaquealgn
salto(JMP)ollamadoasubrutina(JSR),secomportebiennoimportaenqupartedela

227

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

memoriaseencuentreelcdigo.EldeDato,DS,operadelamismamanera,peroyano
para cdigo, sino para manipularaquellas reas de memoria que estn en unaposicin
msalldelasfronterasde64KBimpuestasporelDataSegment.

Este ejercicio muestra cmo manejar las Interrupciones, con la Extensin para ese
propsito definida por Motorola, Freescale, CodeWarrior, mediante un cdigo sencillo
quehaceunamanipulacincualquierasobreunavariable'var',ycadavezqueserecibe
una interrupcin del botn IRQ (external Interrupt Request), se niega una variable
global,GlobalVar.

["LabsC\Lab1\03b_L1_M.c"]
01//******************************************************************
02//Programa03b_L1_M.C,HCS08_CPU,LuisG.UribeC,M10D2013
03//
04//UsodeRutinasdeInterrupcin:
05//A)HabilitacindelperifricoparaInterrumpir
06//B)HabilitacindelCPU(cli)paraqueacepteInterrupciones
07//(apartedelRESET,que**NO**esenmascarable)
08//C)InclusindelcdigodelarutinadeInterrupcin(Interrupt
09//ServiceRoutine,ISR).

10//******************************************************************
11//IncludeFiles
12#include<hidef.h>//ForEnableInterruptsmacro
13#include"derivative.h"//Includeperipheraldeclarations

14#include"several_U.h"//Def:CpuIntEn,CpuIntDsb,EOF,Wait

15//
16//FunctionsPrototypes
17byterutina(bytevar);

18//
19//GlobalVariables
20volatilebyteGlobalVar;

21//******************************************************************
22voidmain(void)/*()*/
23{volatilebytevar=30;

24//
25//>>>ALWAYSincludethefollowing2lines
26//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
27#defineCOP_Disable0x42
28SOPT1=COP_Disable;//SystemOptions1

29//
30//EnableInterruptsforIRQ
31//
32//1a)
33IRQSC_IRQPE=1;//BSETIRQSC_IRQPE,IRQSC:EnableIRQPIN

228

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

34//1b)
35//..Clearanypossibleprevious,false,interruptsbySetting
36//..IRQACKbitinIRQSC(IRQStatusandControlregister)
37IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC

38//
39//>>>>>Try:IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK<<<<<<
40//2)
41//
42IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC//IRQpinIntEn

43//===============================================================
44cli;//CPUInterruptENABLE

45//
46loop:
47while(1){
48var=rutina(var10);
49var=var;//COLOCARBREAKPOINTAQU(Debugger)
50}

51Wait(0);//WaitforEver
52}

53//==================================================================
54byterutina(bytevar)//Subrutinadeejemplo/*()*/
55{
56while(var<30){
57var++;
58}
59returnvar;
60}

61//==================================================================
62//EJEMPLOdeRutinadeInterrupcin(ISRforIRQsignal)
63//NOTE:EsnecesariorealizarunACKNOWLEDGEparaquevuelvaasuce
64//derlainterrupcin(InterruptHandshaking...differentfor
65//eachperipheral:YouneedtoreadManualforeachone...:(

66interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
67{
68GlobalVar^=(byte)1;
69IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
70}//..(RearmIRQInterrupts)

COMENTARIOS a ["Labs-C\Lab1\03b_L1_M.c"]:
LosIncludeFilesnormalesyunoextra,"several_U.h"(LOSPRESENTOMSADELANTE):

12#include<hidef.h>//ForEnableInterruptsmacro
13#include"derivative.h"//Includeperipheraldeclarations

229

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

14#include"several_U.h"//Def:CpuIntEn,CpuIntDsb,EOF,Wait

Elprototipodelafuncin'rutina',queretornaun'byte'yalacualselepasaun
tambinbyte,(bytevar):

17byterutina(bytevar);

Variableglobal.Ntesequeselahadefinidocomo'volatile',paraqueelOPTIMIZADOR
delcompiladorNOLAOMITA,nialcdigoquetambinseradetectadocomointil(este
programaesbastanteinane):

20volatilebyteGlobalVar;

Comienzodelprogramaydefinicinde'var',tambincomo'volatile':

22voidmain(void)/*()*/
23{volatilebytevar=30;

En los programas que escribimos en lenguaje ensamblador, se incluan siempre al


comienzo4instrucciones,dosparainicializarelSP,ydosparadetenerelCOP,CPU
OperatingProperly.EnC,elcompiladorincluyecdigoinvisibleparaelprogramador,
mediante el cual inicializa apropiadamente el Stack, por lo que nos desentendemos de
eso.

PeroelCOPshayquedeshabilitarloporprograma.Unposibleequivalentea:

Main:lda#$42;$42(%0100_0010)?COPE(SOPT1b7)=0($1802)
sta$1802;(SOPT1Pupinitto$C2=%1100_0010)

eselsiguiente:

27#defineCOP_Disable0x42
28SOPT1=COP_Disable;//SystemOptions1

Ahora, para habilitarlas interrupciones del IRQ, ste es el cdigo en Assembler que
siemprehemosusado,

BSETIRQSC_IRQPE,IRQSC;EnableIRQPIN
BSETIRQSC_IRQACK,IRQSC
BSETIRQSC_IRQIE,IRQSC;IRQpinInterruptEnable
cli;CPUInterruptENABLE

enCelquecorrespondeeselsiguiente:

33IRQSC_IRQPE=1;//BSETIRQSC_IRQPE,IRQSC:EnableIRQPIN
37IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC
42IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC//IRQpinIntEn
44cli;//CPUInterruptENABLE

Ustedpuedeensayartambin(muchoMEJOR):

39IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK

230

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Funcionaigual,peroesmssimple.

Elcicloprincipaldelprogramaesmuysencillo,yenrealidadcorrespondeaunaespera
artificialhastaqueocurralainterrupcin.Estecdigodebeserseguidoempleandoel
Debugger(colocandounBreakpointdondeseindica):

46loop:
47while(1){
48var=rutina(var10);
49var=var;//COLOCARBREAKPOINTAQU(Debugger)
50}

51Wait(0);//WaitforEver

La'rutina'llamada,tambinesartificial:

54byterutina(bytevar)//Subrutinadeejemplo/*()*/
55{
56while(var<30){
57var++;
58}
59returnvar;

La rutina de Interrupciones tiene varios ASPECTOS NOVEDOSOS. Como dijimos que las
funcionalidades no definidas por el estndar ANSI se manejan como Extensiones al
lenguaje, y al compilador, las define cada proveedor, y si bien es cierto que se
parecenbastanteentreunoyotro,nosoniguales!Portanto...NOSONPORTABLES.Y
hayqueaprenderlasparacadasuplidor.

La definicin introduce el modificador no estndar 'interrupt'; lo tienen casi TODOS


losquehacencompiladores.

A continuacin se agrega una constante, 'VectorNumber_Virq', definida de manera


simblicamediantelainclusinde<mc9s08qe128.h>(queasuvez,hasidoincluidapor
"derivative.h", junto con las declaraciones de los smbolos de los perifricos).
Obviamente este 'VectorNumber_Virq' define la posicin de la ISR en la tabla de
VectoresdeInterrupcin(muysimilaraloquehicimosenASM)

LuegovieneelTIPOdeinformacinquelarutinaretorna;lasrutinasdeInterrupcin,
ISR,JAMSDEVUELVENNADAysutipoSIEMPREes'void'.SiunaISR,InterruptService
Routine,debecomunicarseconelprogramaprincipal,tienequehacerlointercambiando
valoresmediantevariablesglobales,como'GlobalVar'enelpresenteejemplo.

Las ISR JAMS RECIBEN PARMETROS, como las subrutinas convencionales; por eso el
'(void)';silaISRtienequeleervaloresque'main'oalguienmsproduce,tienenque
intercambiarseTAMBIN(leerse,escribirse)envariablesglobales:

66interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
67{

231

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

IRQISR (Rutina de Servicio de Interrupciones, ISR, para la Interrupcin del botn de


Interrupt Externo, IRQ), hace en este ejercicio algo muy simple: negar la variable
GlobalVar(demanerabooleana:cambiandocerosporunosyviceversa):

68GlobalVar^=(byte)1;

ENTIENDELAEXPRESIN?SINO,TIENEQUEESTUDIAR"C"

Luego, ejecuta el protocolo de reconocimiento (Acknowledge) de Interrupcin del IRQ,


queleindicaalharwarequeelsoftwareYAatendisusolicituddeinterrupcin.Como
hemosdichoatodololargodeestedocumento,enFreescalecadaperifricotienesu
propioprotocolodeIntACK,quehayqueestudiarenlosmanualesdereferencia.Enel
casodelIRQesmuysimple(refirasetambinalosejerciciosenAssembler):

69IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
70}//..(RearmIRQInterrupts)

NOTA: En la familia anterior: HC08 (sin la 'S'), el IRQ tena dos diferencias
fundamentalesconlafamiliaactual,HCS08:

1) Las interrupciones de IRQ estaban HABILITADAS SOLO CON ENCENDER EL MCU! Esto es
**MUYPOCOORTODOXO**,yfueeliminadoenelHCS08...

2) Bastaba con que el PC cargara el contenido del Vector de Interrupciones del IRQ,
como parte del proceso de atender esa interrupcin, para que automticamente el
HardwaretuvieraunAcknowledge.

Estobienpodranhaberlodejado,perolocambiaron:ahorahayquedarleexplcitamente
unACK,segnlalnea69arriba.

EL INCLUDE FILE "SEVERAL_U.H":


01//******************************************************************
02//several_U.h,LuisG.UribeC,S30N2013
03
04//
05//SeveralDefines
06
07#undefWait
08#defineWait(e)while(!(e))
09#undefCpuIntEn
10#defineCpuIntEn__asmCLI
11#undefCpuIntDsb
12#defineCpuIntDsb__asmSEI
13#undefEOF
14#defineEOF((word)1)

COMENTARIOS a ["Labs-C\Lab1\several_U.h"]:
Primero se define un 'Wait', empleando un 'while'. Wait es muy conveniente expresado
cosas como: Wait( kbhit() ): espere hasta que llegue una tecla. Empleando un while
habraqueescribir

232

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

while(!(kbhit());

ComoestaesunaproposicinenNEGATIVO,sehacemsdifcilsucomprensin.

En general nunca uso expresiones en negativo; las convierto en positivo, como es el


casodelWait,perotambin,enAssembler,nousoBNEsinoqueintroduzcounmnemnico
nuevo: BDIFF. Es lo mismo, pero la comprensin es mucho mejor con la instruccin en
positivo:SALTESISONDIFERENTES.

MuchomejorqueSALTESI*NO*SONIGUALES.

Antes de definir el Wait, lo '#undef' ('undefine'), por si este compilador tiene


definido su propio Wait (y comoNO voy ausar ese Wait del compilador, si es que lo
tuviera, aqu puedo cambiarlo por EL MO. El Visual Studio de Microsoft, tiene UN
WAIT!,yalgunosotroscompiladorestambin)

07#undefWait
08#defineWait(e)while(!(e))

Para habilitar las interrupciones del CPU se emplea una instruccin de lenguaje
ensamblador,queNOpuedeexpresarseenlenguajeC!

Pero una de las extensiones de CASI todos los compiladores modernos, permite incluir
instruccionesdeAssembler,ENLNEAconelcdigoenC.Estoesexactamenteloquese
haceacontinuacinconel'asm':

10#defineCpuIntEn__asmCLI

Lomismosehaceparaladeshabilitacindeinterrupciones:

12#defineCpuIntDsb__asmSEI

(Adems, que mis nombres, CpuIntEn y CpuIntDsb, con seguridad que son MUCHO ms
INTELIGENTES,DIGO:INTELIGIBLES,quelosoriginalesdeFreescale!)

Y, finalmente, hay un smbolo equivalente a su homnimo en el ANSI C que ya hemos


empleado,yqueyolodefinoamiconvenienciaaqu(enelpresenteejercicio,NOse
emplea):

14#defineEOF((word)1)

NOENTIENDEEL#defineDELALNEA14?

TIENEQUEESTUDIAR"C"

OBSERVACIN:
NihemoscomenzadolosejerciciosenC,ylespregunto:

Sabanalgode#undef?

233

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

QuvalorinicialtieneGlobalVar(lnea20)?

Porquenlalnea
48var=rutina(var10);
'rutina'estPEGADAalparntesisizquierdo,entantoqueen:
54byterutina(bytevar)//Subrutinadeejemplo/*()*/
'rutina'estSEPARADAdelparntesisizquierdo?

Paraqupuedeservirel'moito':/*()*/?

Imagino,peroestoydesconfiado,queshabanusado#define?

51) "Interrupts" en el lenguaje C, variacin


Elproblema["LabsC\Lab1\03b_L1_M2.c"]essimilaralanterioryutilizasimplemente:

39IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK

As:

//EnableInterruptsforIRQ
IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;

IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC//IRQpinIntEn

cli;//CPUInterruptENABLE

MANEJO DE TIMERS

qu les presento mi primera librera en C, el manejador de Temporizadores.


Primero les incluyo una breve resea acerca de las diversas versiones, en
LenguajeEnsambladoryahoraenLenguajeC.

Refirasealosejerciciosqueestnenlacarpeta:CarpetasLabsC\Lab2\TimersJ

52) LIBRERA DE TIMERS: timersJ.c


1)EstasegundaetapademidocenciaenlaUSBcomenzenAbrilde2003conelcursode
CircuitosDigitales.LaprimeraversindelabibliotecadeTimersenASM,Timers8,la
hice para mi primer curso de Arquitectura del Computador, el Lunes 24Nov2003,
seguramentelaterminalas3am,antesdecomenzarmiclasedeesedaalas9:30.El
microcontrolador que se empleaba en aquella poca era el Motorola 68HC908GP32, con
memoria Flash (el "9" significa eso) y 32 KBytes de Memoria (toda Flash, menos 512
Bytes de RAM). El ensamblador tena por nombre WinIDE y era gratuito. Tena serias
deficienciaseneltratamientodeMacros,loquemeoblig,porejemplo,adefinirDOS
tipos de 'Setimer' y de 'Wait_on': uno para Constantes, y otro para Variables
('SetimerK','Wait_onK','SetimerV','Wait_onV').

2) La siguiente revisin, Timers8B, la hice en mi siguiente curso de Arquitectura un


aodespus:Lunes08Nov2004,siendolamsnovedosamejoraelhaberhecholaISRdel

234

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Timer(TBM:TimerBasicModule)interrumpibleporotrosdispositivos,yNOreentrante.
Estopermitaestudiarelconcepto,yalavezhacerquemistimers,querealidadno
requieren una exactitud ajustada al microsegundo, no molestaran a los dems
perifricos, en caso de que aquellos necesitaran interrumpir. La no reentrancia se
requera para evitar que el mismo TBM auto interrumpiera su propia ISR, en caso de
haber terminado un conteo por Hardware antes de haber terminado su Interrupt Service
Routine(pormotivodelosdemsperifricos).Noesconcienteaceptarunainterrupcin
de un perifrico sin haber terminado su ISR para una interrupcin anterior. Esta
funcionalidadselograprincipalmente,haciendoquelaISRdelTBMautoinhabilitesu
InterruptEnableyrehabilite(CLI)lasinterrupcionesdelCPU.RecuerdequeMotorola
ensusManualesdeReferencia,advierteEQUIVOCADAMENTEencontrariodeestaprctica.

3)LarevisinTimers8CesdelJueves01Dic2005paramisiguientecurso;allinclula
capacidaddequeOTRASISRspudieranemplearlasMacrosdelalibreradeTimers;as,
porejemplo,elIRQolascomunicacionespodan,dentrodesusISRs,temporizarciertos
eventos que el programador necesitara (timeouts y similares; control de "throttle" o
reguladordevelocidad).

4) Timers8D, 2007: esencialmente la diferencia fue modificar la programacin del


Oscilador maestro del CPU para que en vez de 8Mhz trabajara a 7,987,200 Hz para
aproximarmejorlavelocidadde9600bpsenelSCI.

5)Timers8G:CuandofuiadictarelcursodeArquitecturaenAbrilde2009meencontr
queelLaboratoriohabaadoptadoelcompiladorCodeWarriorporvariasrazones:

a)manejabaCademsdeASM;
b)eraelqueMotorolapromocionaba;
c)WinIDEseestabaquebrando,imaginoquenoganabanmuchoregalandosucompilador,y
ahoraqueracobrarlo,loqueobligacompararloconCW.

El cambio no ofreca en ese momento NINGN beneficio para mi clase de Arquitectura,


perodesarraigarondefinitivamenteelWinIDEdetodoslosPCsdellaboratorio,yyano
le dieron ms soporte. Eso me oblig a generar el Jueves 16Abr2009 esta versin
Timers8G especficamente para CodeWarrior. Las diferencias no eran tantas, pero de
todasmanerasfueuntrabajn:

Porejemplo,enWinIDEyenCWunbitseidentificabacomo:
Timer0ReadyEQU0;..Bit#0;forbrclr&brset
Timer0.RdyEQU0;..Bit#0;forbrclr&brset

EnWinIDEyenCWladefinicindelasmacrostenaelsiguiente
aspecto:
$MACROSetimerKtimer,time;timeisaCONSTANT(K)
Setimer:MACROtimer,time;timeisaCONSTANT(K)

Desapareceel$de$MACRO,ycambiadeposicin...ElnombredelaMacroahoraesLA
ETIQUETA.

EnWinIDE,porejemplo,alprimerparmetrodelaMacroselehacareferenciacomo%1,
entantoqueenCWes\1;el%enCWidentificanmerosbinarios.Losnmerosenbase
diezahorasonelestndar,noprecisanidentificadorespecial;enWinIDEseescriban
como:!10

235

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

6)Misclaseshastael2012noincluyeronlasdeArquitectura;cuandoregresdespus
de3aos,acababandecambiarahora...ELCHIP.ElsucesorfueeldelafamiliaHS:
HC9S08QE128 y se inclua la tarjeta de desarrollo DEMOQE128. TODO VOLVI A CAMBIAR:
habaperifricosnuevosquereemplazabanfuncionesantiguas.Porejemplo,elTMByano
existayloreemplazelRTC.LosADCsiguieronsiendolosmismos,peroCAMBIARONlos
NOMBRES de los puertos y bits, de los originales de Motorola a los de nomenclatura
Freescale. Algunos cambios sutiles, como los del IRQ que ya hemos mencionado; ya el
osciladormaestrodelCPUpermiteusarloSINprogramacin,porloqueeliminesaparte
delabibliotecadesoporte.

Paracolmo,laversinactualdelCodeWarrioresla10.5,aunqueenelLaboratorioslo
se le da soporte a la antigua 6.3, que difieren bastante las dos. Incluso, la nueva
10.xtienenuevosbugsquehacenqueprogramasquecorranbienenla6.3,ahoranolo
hagan.

AsquecorrespondalaversinTimersH,yaprovechandolanuevadenominacindelchip,
larebauticcomoTimersHS.

La librera que aqu presento para el lenguaje C est basada en TimersHS, pero con
diferenciasquemeobligaronaavanzarlaversin;poresoenClabibliotecadeTimers
quelesofrezcoeslaTimersJ.c(LasiguienteaHeslaI,perohayciertasletrasque
enloslistadosanseprestanparaconfusin,dependiendoavecesdeltipodeletra:
Laiconel1,laOconel0;laAconel4...poresonoestimersIsinoTimersJ)

SiustedentendialaperfeccinlaversinenAssembler,nodeberatenerproblemas
conelestudiodeTimesrJ.c

["LabsC\Lab2\TimersJ\timersJ.c"]
001//******************************************************************
002//TimersJ.c,LuisG.UribeC.C19D2013
003//
004//******************************************************************
005//IncludeFiles
006#include"timersJ_.h"
007
008//
009//GlobalVariables
010volatilewordtimersMS[NTIMERS];
011
012//==================================================================
013voidIniTimers(bytentimers)/*()*/
014{//BydefaultLINKinitALLtimers(timersMS[NTIMERS])toZERO
015//'ntimers'NOTusedhere.CustomizeNTIMERS,intimersJ_.h
016
017//AssureuserdefinedNTIMERS(timersJ_.h)is2'spower!
018Sassert(!(NTIMERS&(NTIMERS1)));
019
020RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
021//..ClearRTCIF;IntEnableRTC
022}/*IniTimers()*/

236

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

023
024//
025wordSetimerMS(bytetimer,wordtimeMS)/*()*/
026{wordtmp=timersMS[timer&(NTIMERS1)];//Remindingtime
027
028timersMS[timer&(NTIMERS1)]=timeMS;//ticks(mSeconds)
029returntmp;
030
031}/*SetimerMS()*/
032
033//
034byteTimeout(bytetimer)/*()*/
035{
036if(timersMS[timer&(NTIMERS1)]){
037return0;
038}
039return1;//else...
040
041}/*Timeout()*/
042
043//
044voidWTimer(bytetimer)/*>>>WARNING<<<:BLOCKSCPU*//*()*/
045{
046while(!Timeout(timer)){
047/*EmptyWhile*/
048}
049
050}/*WTimer()*/
051
052//
053voidWaitMS_on(bytetimer,wordtimeMS)/*()*/
054{/*>>>WARNING<<<:BLOCKSCPU*/
055
056SetimerMS(timer,timeMS);
057WTimer(timer);
058
059}/*WaitMS_on()*/
060
061//
062voidWaitISR_on(bytetimer,wordtimeMS)/*()*/
063{//Save/RestoreCCRisNOTpossiblefrom'C'.WeneedtheASSEMBLER
064
065//
066//SAVEACTUALINTERRUPTMASKVALUE
067asm{
068tpa//PushCCRsavesIMaskstatus
069psha//..
070}
071
072//
073//CCode
074CpuIntDsb;//DISABLEINTERRUPTS(IMask=1):Let

237

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

075SetimerMS(timer,timeMS);//..SetimerusedinsideInt.Routines
076CpuIntEn;//REENABLEINTERRUPTS:LetRTCCount
077WTimer(timer);
078
079//
080//RESTORESAVEDINTERRUPTMASKVALUE.
081asm{//PopCCSrestoressavedIMaskstatus
082pula//..>>>URGENT<<<:Seepage183of
083tap//01CPU08RM!ReferenceManual2013U.pdf
084}//THISWAS***EXACTLY***MYEXAMPLEINTHERE!
085//(Stupidguy)
086}/*WaitISR_on()*/
087
088//==================================================================
089interruptVectorNumber_VrtcvoidTIMERS8ISR(void)/*()*/
090{bytei;
091
092for(i=0;i<NTIMERS;i++){
093if(timersMS[i]){
094timersMS[i];
095}
096}
097RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
098//..>>ClearRTCIF<<//IntEnableRTC
099}/*TIMERS8ISR*/
100
101//******************************************************************
102//NOTE:Thefollowingcode***DOESNOTWORK***(Seeabove...);WHY?
103//if(timersMS[i]<0){
104//timersMS[i]=0;
105//}
106
107//WHATis'Sassert'?HOWitworks?TryusingNTIMERS=6

COMENTARIOS a ["Labs-C\Lab2\TimersJ\timersJ.c"]:
HechaelMircoles19Dic2013

Adelantesepresentael"timersJ_.h",peroslosonlosPrototiposdelas6Funciones,
definicinde3parmetrosdelRTC,ylaMacroSassert(e)(StaticAssert.Assertesde
C.SABAUSTED?SINO,TIENEQUEESTUDIARC)

LarepresentacindecadatimeresunWORD,talcomoenASM.Hayunarreglo(vector),
timersMS,compuestoporlacantidadNTIMERS(8enestapresentacin,peroustedpuede
ajustarlaen"timersJ_.h"segnsuspreferencias)

El arreglo es Global para facilitar su visibilidad en los programas que usan esta
librera.Adems,sehadeclarado'volatile'paraevitaroptimizacionesindeseadasen
estasvariables.

010volatilewordtimersMS[NTIMERS];

238

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Laprimerafuncionalidadpermitelainicializacindelabiblioteca,IniTimers.Seusa
comoIniTimers(8)(olapotenciadedosqueusteddefina),paramantenerlaSEMNTICA
delafuncin,peroese#8NOseempleaenlabiblioteca:lavalidacinsehacecontra
laconstanteNTIMERS,definibleporusteden"timersJ_.h"

Como parte de la inicializacin habra que colocar en CERO las variables que
representan los timers; esto NO se hace explcitamente porque, SABA USTED que el
LINKER inicializa en CERO TODAS LAS VARIABLES "GLOBALES" QUE NO TIENEN ASIGNADO UN
VALOREXPLCITO?NO?SABELOQUEESLINKER?NO?TIENEQUEESTUDIARC

013voidIniTimers(bytentimers)/*()*/

AsegresedeentendercmoSassertvalidaenCOMPILETIME(nohaceNADAenRUNTIME)que
elnmerodetimersporusteddefinidoseapotenciadedos.

018Sassert(!(NTIMERS&(NTIMERS1)));

La nica operacin que termina hacindose explcitamente, es la seleccin de "1KHz"


como reloj Interno (clock/1, lo que produce interrupciones cada milisegundo. Nuestra
librera CUENTA TICKS de UN milisegundo. Si usted llegara a necesitar contar tiempos
menores,elReferenceManualleindicacmoprogramarelRTCSCparalograrlo)

020RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick

La siguiente funcionalidad es la de activar uno de los timers: SetimerMS. Recibe dos


parmetros:'bytetimer'(elnmerodeltimer,del0a7paraestaimplementacin)y
'word timeMS', la cantidad de MILISEGUNDOS que ese temporizador debe contar antes de
declararseREADY.

La funcin retorna la cantidad de MS que an faltaban para que ese timer terminara
(guardadaalcomienzoen'tmp');estopuedeservirdeverificacinpuessinoescero,
seestabortandountimerparavolverloainicializar.

Finalmente,seinicializalavariablecorrespondienteal'timer'conelvalordeseado
enmilisegundos:timeMS,talcomosucontraparteenASM.

025wordSetimerMS(bytetimer,wordtimeMS)/*()*/
026{wordtmp=timersMS[timer&(NTIMERS1)];//Remindingtime
028timersMS[timer&(NTIMERS1)]=timeMS;//ticks(mSeconds)
029returntmp;

Lafuncionalidadqueseusaparaaveriguarsiexpir(llegaCero)ono,algunodelos
timers es Timeout, que recibe como parmetro un 'byte timer' (de 0 a 7 en esta
implementacin)ydevuelvesono,sihuboTimeout(retorna0siNOhaytimeout;1si
sexpiresetimer)

034byteTimeout(bytetimer)/*()*/
036if(timersMS[timer&(NTIMERS1)]){
037return0;
038}
039return1;//else...

239

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Esperarbloqueandoelflujodelprograma,hastaquetermineunciertotemporizador,que
fue PREVIAMENTE inicializado por SetimerMS, es la funcin de WTimer, que recibe como
parmetro el ID del timer (byte timer), y no retorna ningn valor; solo bloquea el
programa.

044voidWTimer(bytetimer)/*>>>WARNING<<<:BLOCKSCPU*//*()*/
046while(!Timeout(timer)){
047/*EmptyWhile*/
048}

Esta es una de las oportunidades en las que es preferible expresar la condicin de


maneraafirmativa:046Wait(Timeout(timer));

Locambiarenalgunaotraoportunidad.

Paraaquellasocasionesquerequieranprogramaruntimeryesperarhastaquetermine,
todoenunasolaoperacin,estWaitMS_on,querecibedosparmetros,comoSetimerMS,
ynoregresaningnvalor,comoWTimer.

053voidWaitMS_on(bytetimer,wordtimeMS)/*()*/
056SetimerMS(timer,timeMS);
057WTimer(timer);

Para realizar una espera estando en INTERRUPT STATE (es decir, ha ocurrido una
interrupcin y se est ejecutando la ISRdel perifrico en cuestin, y sta requiere
hacer una espera, se emplea WaitISR_on, equivalente de WaitMS_on, para ejecutarse en
ISRs). WaitISR_on recibe 2 parmetros, igual que WaitMS_on: byte timer (nmero del
temporizadorquehadeusarse,del0al7)yelnmerodeMilisegundos,wordtimeMS.

062voidWaitISR_on(bytetimer,wordtimeMS)/*()*/

EstafuncinsalvaguardaelCCRenelStack,ycomoelCnopuededirectamenterealizar
estaoperacin,selaimplementavaInlineASM:

ElobjetodeguardarelvalordelCCResparapreservarelInterruptStatedelCPU(I,
Interrupt Mask), pues SetimerMS no se puede ejecutar si las interrupciones estn
activas(CLI),asqueestafuncinlasdeshabilita,ejecutaelSetimerMSy...comoya
explicamos en la seccin de ASM, NO PUEDE SIMPLEMENTE HABILITAR LAS INTERRUPCIONES.
Tiene que dejar el Interrupt State TAL COMO ESTABA ANTES de DESHABILITAR las
interrupciones.Poreso,envezdeCLI,serecuperadesdeelStackelvalorpreviode
I,queestabaenelCCR.

066//SAVEACTUALINTERRUPTMASKVALUE
067asm{
068tpa//PushCCRsavesIMaskstatus
069psha//..
070}
073//CCode
074CpuIntDsb;//DISABLEINTERRUPTS(IMask=1):Let
075SetimerMS(timer,timeMS);//..SetimerusedinsideInt.Routines
076CpuIntEn;//REENABLEINTERRUPTS:LetRTCCount
077WTimer(timer);

240

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

080//RESTORESAVEDINTERRUPTMASKVALUE.
081asm{//PopCCSrestoressavedIMaskstatus
082pula//..>>>URGENT<<<:Seepage183of
083tap//01CPU08RM!ReferenceManual2013U.pdf
084}//THISWAS***EXACTLY***MYEXAMPLEINTHERE!

Desdeluego,seempleanlasinstruccionesTPAyTAPqueelReferenceManualindica
QUENOSIRVENPARANADA!

La rutina de Interrupciones, TIMERS8ISR, ni recibe parmetros ni devuelve valores


(void) como ya se explic. Es de tipo 'interrupt' e indica cul es el Vector de
interrupciones,VectorNumber_Vrtc,paraqueelLoadercoloqueladireccindelaISRen
laposicinapropiada,enelVectordeInterrupciones.

SABEUSTEDLOQUEESELLOADER?NO?TIENEQUEESTUDIARC

Elcdigoesmuysencillo:incrementarcadatemporizadorQUENOHAYAEXPIRADO(locual
sedeterminaenel'if'porquesuvalorESdiferentedeCERO),yseguirelprotocolode
AcknowledgedeInterrupcionesparaelperifrico:

089interruptVectorNumber_VrtcvoidTIMERS8ISR(void)/*()*/
090{bytei;
092for(i=0;i<NTIMERS;i++){
093if(timersMS[i]){
094timersMS[i];
095}
096}
097RTCSC=RTC_FLAGS;//Use1KHzinternalclock/1:1mStick
098//..>>ClearRTCIF<<//IntEnableRTC

SeasignaRTCSC=RTC_FLAGS,comolarutinadeinicializacin,loqueBorralaInterrupt
Flag,IF,delRTC,rearmando(permitiendootrasposteriores)susinterrupciones.

TambinhubiramospodidoborrarexclusivamenteesebitRTCIF,peroelresultadoesel
mismo.

OBSERVACIN:PorqureescribiendoelIFcomosigue,elcdigoNOTRABAJA?

CdigoORIGINAL:

093if(timersMS[i]){
094timersMS[i];

Cambiadoa:

103//if(timersMS[i]<0){
104//timersMS[i]=0;
105//}

NOSABEPORQUNOTRABAJA?TIENEQUEESTUDIARCURGENTEMENTE!

241

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab2\TimersJ\timersJ_.h"]:
["LabsC\Lab2\TimersJ\timersJ_.h"]
01#ifndefTIMERSJ_H_INCLUDED
02#defineTIMERSJ_H_INCLUDED
03//******************************************************************
04//timersJ_.h,LuisG.UribeC.C11D2013
05//
06#defineNTIMERS8//2'sPower:2,4,8,16...128(max)
07
08//******************************************************************
09//IncludesFiles
10//<<<INCREDIBLE:CW10.3**NEEDS**toREIncludethisfiles**AGAIN**
11
12#include<hidef.h>//ForEnableInterruptsmacro
13#include"derivative.h"//Includeperipheraldeclarations
14
15//
16//FunctionPrototypes
17
18voidIniTimers(bytentimers);//UsedNTIMERS,notntimershere
19wordSetimerMS(bytetimer,wordtimeMS);
20byteTimeout(bytetimer);
21voidWTimer(bytetimer);
22voidWaitMS_on(bytetimer,wordtimeMS);
23voidWaitISR_on(bytetimer,wordtimeMS);
24
25//
26//ParameterDefinitions
27
28#defineRTCPS_BY_ONE8U//Dividedby1,gives1mSTick
29#defineONE_KHZ0//Usesinternal1Khzclock
30
31#defineRTC_FLAGS(RTCSC_RTIF_MASK|ONE_KHZ|RTCSC_RTIE_MASK|\
32RTCPS_BY_ONE)
33//RTCSC_RTCPS0_MASK1U<<<2,ONE_KHZ(bits2,1,0)
34//RTCSC_RTCPS3_MASK8U...
35//RTCPS_BY_ONE8U<<<4,Divideby1;gives1mSTick
36//RTCSC_RTIE_MASK16U<<<3
37//RTCSC_RTIF_MASK128U<<<1
38
39//
40//DefineSassert,incaseyouneedaStaticassert
41#defineSassert(e)do{enum{assert_static__=1/(e)};}while(0)
42
43//
44//SeveralDefines
45#undefWait
46#defineWait(e)while(!(e))
47#undefCpuIntEn
48#defineCpuIntEn__asmCLI
49#undefCpuIntDsb

242

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

50#defineCpuIntDsb__asmSEI
51#undefEOF
52#defineEOF((word)1)
53
54#endif//TIMERSJ_H_INCLUDED

Nohaymuchoquecomentar.Ustedtienequepoderdecirquhaceycmo,elSassert.

53) EJEMPLO #1 USANDO LIBRERA DE TIMERS


Obsrvese cmo est de OCULTA la librera de Timers: No figura ni la definicin de
funciones, ni las variables que se usan, ni siquiera aparece aqu la ISR del RTC.
OCULTAR (HIDE) la informacin y hacer que el acceso a ella sea ESTRUCTURADO, es el
objetivodelOOPS(ObjectOrientedProgrammingSystem)

Este ejercicio enciende los 8 leds a diferentes TIEMPOS, que han sido definidos
mediante la tabla "const word Delays[]". Una activacin del botn de IRQ detiene el
programa;lasiguienteactivacinhacequeelprogramacontine.Paraexperimentar,se
usTAMBINlalibreradeTimersenlaISRdelIRQ,afindesepararlaspulsaciones
delbotn,almenos1segundo(1000MS)

["LabsC\Lab2\TimersJ\100TimedFlash8.c"]
01//******************************************************************
02//Program100TimedFlash8.c:LuisG.UribeC.D24N2013C11D2013
03//8LEDsflashingatdifferentrates.IRQtoggle'sprogramOFF/ON
04//
05//******************************************************************
06//IncludeFiles
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
09
10#include"timersJ_.h"//Definescli,sti
11
12constwordDelays[]={150,355,511,673,1002,1398,2755,3000};
13//constwordDelays[]={673,150,2755,1398,511,1002,3000,355};
14
15byteToggle=1;//BegininRUNstate(1)
16
17//******************************************************************
18voidmain(void)/*()*/
19{bytei,LEDsMask;
20
21//
22//>>>ALWAYSincludethefollowing2lines
23//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
24
25#defineCOP_Disable0x42
26SOPT1=COP_Disable;//SystemOptions1
27
28//
29//EnableInterruptsforIRQ
30

243

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

31IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
32IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
34//
35//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
36PTCDD=0xFF;//..(theydriveLEDsonDEMOQE128)
37PTEDD=0xFF;
38
39//
40//EnableTimers
41IniTimers(8);
42
43//
44//Start8timers
45for(i=0;i<8;i++){
46SetimerMS(i,Delays[i]>>1);
47}
48
49//===============================================================
50CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!
51
52//
53//Loopforever...IRQtogglesRUN/~STOP
54
55while(1){
56Wait(Toggle);//IRQ:RUN/~STOP
57for(LEDsMask=0,i=0;i<8;i++){
58if(Timeout(i)){
59LEDsMask|=1<<i;
60SetimerMS(i,Delays[i]>>1);
61}
62}
63PTED=(PTCD^=LEDsMask);
64}
65}
66
67//==================================================================
68//IRQINTERRUPTSERVICEROUTINE
69//NOTE:EsnecesariohacerUNACKNOWLEDGEparaquelainterrupcin
70//vuelvaasuceder(InterruptHandshaking,differentforeach
71//peripheral!NeedtoreadManualforeachequipment...:(
72
73interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
74{
75IRQSC_IRQIE=0;//AutodisableIRQInterrupt
76Toggle^=(byte)1;
77WaitISR_on(7,1000);
78
79IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
80//..Interrupt(ReArmIRQInterrupts)
81IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:ReEnable
82//..IRQpinIntEn
83}

244

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab2\TimersJ\100TimedFlash8.c"]
TodocomienzacomoSIEMPRE.

Luego viene la tabla de Delays, acompaada de una Alternativa, para que usted
experimente. Ambas tablas han sido escogidos empleando una funcin random (en Perl)
paranmerosentre150y3000:

12constwordDelays[]={150,355,511,673,1002,1398,2755,3000};
13//constwordDelays[]={673,150,2755,1398,511,1002,3000,355};

LavariableGLOBALToggle,quecomienzaen1(RUNstate),serNEGADA(vaExor)porla
ISRdelIRQ,cadavezqueseoprimaelbotndeIRQ.

15byteToggle=1;//BegininRUNstate(1)

Dosvariableslocales:

18voidmain(void)/*()*/
19{bytei,LEDsMask;

Las2instruccionesqueSIEMPREhayqueincluir:

25#defineCOP_Disable0x42
26SOPT1=COP_Disable;//SystemOptions1

HabilitacindeInterrupcionesparaelIRQ:

31IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
32IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn

Inicializacin de los LEDs. Aqu hemos omitido el procedimiento RECOMENDADO, que ya


ilustramos,yqueindicacolocarenunestadoinicialadecuadoelvalordelassalidas,
ANTES de programar los correspondientes puertos como Salida, ya que en este caso NO
IMPORTA.

36PTCDD=0xFF;//..(theydriveLEDsonDEMOQE128)
37PTEDD=0xFF;

InicializamoslosTimers:
41IniTimers(8);

Arrancamosinicialmentetodoslos8timersleyendodelatablaDelays:

45for(i=0;i<8;i++){
46SetimerMS(i,Delays[i]>>1);
47}

HabilitamoslasinterrupcionesdelCPU:

50CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!

245

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

El ciclo infinito para este programa. Primero se bloquea el programa si la variable


ToggleindicaSTOP(comienzaenRUNState),asquesiseoprimeelbotndeIRQ,se
pausaosecontinaelprograma:

55while(1){
56Wait(Toggle);//IRQ:RUN/~STOP

Sicorrespondeejecutarelcicloinfinito,seinicializalavariableauxiliarLEDsMask
en0,yluegosevanrecorriendotodoslostimers,buscandoaquellosqueyaExpiraron
(Timeout),yselossealaconun1enLEDsMask,enlaposicincorrespondienteasu
ID, de 0 a 7; adems, como ya les expir el tiempo se los vuelve a activar con un
SetimerMS:

57for(LEDsMask=0,i=0;i<8;i++){
58if(Timeout(i)){
59LEDsMask|=1<<i;
60SetimerMS(i,Delays[i]>>1);
61}
62}

Alfinalizarelanlisisdetodoslostimers,secambia(NIEGA)elestadodelosLEDs
correspondientes a aquellos que ya expiraron (usando un Exor: PTCD ^= LEDsMask). El
resultadodeesenuevovalorseloreplicaenPTED:

63PTED=(PTCD^=LEDsMask);

LaIRQINTERRUPTSERVICEROUTINE:

Alcomienzoseautodeshabilitaparainterrupciones,afindequelaspulsacionesdel
botnIRQnotenganrepercusionesmientrasnoseterminelaIRQISR:

73interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
74{
75IRQSC_IRQIE=0;//AutodisableIRQInterrupt

LuegoseinvierteelestadodelavariableToggleempleandounExor:

76Toggle^=(byte)1;

Se habilita la ESPERA DENTRO DE INTERRUPCIONES usando el WaitISR_on para un Segundo,


empleandoelTimer#7:

77WaitISR_on(7,1000);

IMPORTANTSIMO:

NOPUEDEUSARSEELMISMOTIMER(7enelejemplo)ENNINGUNAOTRAPARTE.Bastaconque
seandistintosparaquenohayaconflictos

Terminadalaespera,quebloqueacualquierentradadelusuarioduranteunsegundo,se
procede al Protocolo de Acknowledge de interrupciones para este perifrico IRQ en

246

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

particular, que es diferente de los dems y que, como ya dijimos tantas veces, hace
necesarioestudiarcadaperifricoporseparado:

79IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
80//..Interrupt(ReArmIRQInterrupts)

Se vuelve a rehabilitar las propias interrupciones, deshabilitadas al comienzo de la


ISR,ysetermina:

81IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:ReEnable
82//..IRQpinIntEn

54) EJEMPLO #2 USANDO LIBRERA DE TIMERS


Este ejemplo es una extensin del anterior: Hay 4 tablas con valores seleccionados
tambinalazar,yseusaelbotndeIRQparaircambiandodetabla;secomienzapor
latabla#0(laprimera)ylaIRQISRhacepasarelndiceconqueseleelatabla,por
losnmeros0,1,2,3,0,1,2..:

["LabsC\Lab2\TimersJ\110TimedFlash8X4.c"]:
01//******************************************************************
02//ProgramTimedFlash8X4.c:LuisG.UribeC.L25N2013C11D2013
03//8LEDsflashingatdifferentrates.IRQstepsthroughDelayTables
04
05//******************************************************************
06//IncludeFiles
07#include<hidef.h>//ForEnableInterruptsmacro
08#include"derivative.h"//Includeperipheraldeclarations
09
10#include"timersJ_.h"//Definescli,sti
11
12constwordDelays[4][8]=
13{{673,150,2755,1398,511,1002,3000,355},
14{355,511,2755,1398,1002,673,150,3000},
15{1002,3000,1398,511,673,355,2755,150},
16{355,1002,2755,1398,150,511,3000,673},
17};
18byteIndex=0;
19
20//******************************************************************
21voidmain(void)/*()*/
22{bytei,LEDsMask;//BegininRUNstate(1)
23
24//
25//>>>ALWAYSincludethefollowing2lines
26//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
27
28#defineCOP_Disable0x42
29SOPT1=COP_Disable;//SystemOptions1
30
31//
32//EnableInterruptsforIRQ

247

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

34IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
35IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
36
37//
38//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
39PTCDD=0xFF;//..(theydriveLEDsonDEMOQE128)
40PTEDD=0xFF;
41
42//
43//EnableTimers
44IniTimers(8);
45
46//
47//Start8timers
48for(i=0;i<8;i++){
49SetimerMS(i,Delays[Index][i]>>1);
50}
52//===============================================================
53CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!
54
55//
56//Loopforever..PressingIRQstepsthroughDelayTables(Index)
57
58while(1){
59for(LEDsMask=0,i=0;i<8;i++){
60if(Timeout(i)){
61LEDsMask|=1<<i;
62SetimerMS(i,Delays[Index][i]>>1);
63}
64}
65PTED=(PTCD^=LEDsMask);
66}
67}
68
69//==================================================================
70//IRQINTERRUPTSERVICEROUTINE
71//NOTE:ItisneccesarytoACKNOWLEDGEtheInterrupt,inorderto
72//reArmit.'InterruptHandshaking'...isdifferentforeach
73//peripheral!soyouwillneedto...readtheManual&program
74//adifferentroutine...forEACHperipheraldevice.<;~(
75
76interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
77{
78IRQSC_IRQIE=0;//AUTODisableIRQInterrupt
79Index=(Index+1)&0x03;//0,1,2,3,0,1,2..
80WaitISR_on(7,1000);
81
82IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
83//..Interrupt(RearmIRQInterrupts)
84IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:ReEnable
85//..IRQpinIntEn
86}

248

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab2\TimersJ\110TimedFlash8X4.c"]:
Matrizde4vectores,c/ude8valores:

12constwordDelays[4][8]=
13{{673,150,2755,1398,511,1002,3000,355},
14{355,511,2755,1398,1002,673,150,3000},
15{1002,3000,1398,511,673,355,2755,150},
16{355,1002,2755,1398,150,511,3000,673},
17};

ndiceparaseleccionarentrelos4vectores,del0al3:

18byteIndex=0;
21voidmain(void)/*()*/
22{bytei,LEDsMask;//BegininRUNstate(1)
23

LamismahabilitacindeIRQparainterrumpir,ylainicializacindelosLEDs:

32//EnableInterruptsforIRQ
38//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput

LainicializacindesiempreparalosTimersyhabilitacindeinterrupcionesdelCPU:

44IniTimers(8);
48for(i=0;i<8;i++){
49SetimerMS(i,Delays[Index][i]>>1);
50}
53CpuIntEn;//CPUInterruptENABLE.DON'TFORGET!

Cicloinfinito,comoenelejercicioanterior,peroahoraelIRQNOdetieneyrearranca
elcdigo,sinoquecambiael'Index'entre0y3:

58while(1){
59for(LEDsMask=0,i=0;i<8;i++){
60if(Timeout(i)){
61LEDsMask|=1<<i;
62SetimerMS(i,Delays[Index][i]>>1);
63}
64}
65PTED=(PTCD^=LEDsMask);

Rutina de interrupciones para el botn de IRQ; todas las lneas de programa son
idnticasalejercicioanterior,exceptoporelcicladodeIndex:

79Index=(Index+1)&0x03;//0,1,2,3,0,1,2..

ENTIENDECMOESQUEINDEXCICLAENTRE0Y3?SINO,TIENEQUEESTUDIARC.

249

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

SERIAL COMMUNICATIONS & DATA QUES IN C

omoenelcasodelosejerciciosenLenguajeensamblador,laparteculminante
por el momento, de los programas en C, son las rutinas de Comunicaciones
Serialesysuscompaeros,losprocesadoresdeColasdeDatos.Lespresentomi
segunda librera en C, el manejador de Comunicaciones Seriales y, a
continuacin, mi librera para el manejo de Colas de Datos, auxiliar imprescindible
paraelmanejodeComunicacionesconflexibilidad.

Refirasealosejerciciosqueestnenlacarpeta:CarpetasLabsC\ Lab3\SciComm.

55) LIBRERA DE COMUNICACIONES SERIALES


PrimeroanalicemosSciComm.h,quedefinelabibliotecadeComunicacionesSeriales:

["LabsC\Lab3\SciComm\SciComm.h"]
001#ifndefSCICOMM_H_INCLUDED
002#defineSCICOMM_H_INCLUDED
003
004//******************************************************************
005//SciComm.h:SCIComm.Support
006//LuisG.UribeC.,D11M2007L12M07J16A09L08J09
007//..S16J2012(HCS08)D24J2012M26F2013J28N2013
008//S30N2013:Migratedbackto'C'S21D2013cosmetics:XmtRcvActivate
009
010//
011//**REFERto02MC9S08QE128RM(ReferenceManual)U.pdf**
012#undefWait
013#defineWait(e)while(!(e))
014#undefCpuIntEn
015#defineCpuIntEn__asmCLI
016#undefCpuIntDsb
017#defineCpuIntDsb__asmSEI
018#undefEOF
019#defineEOF((word)1)
020
021//==================================================================
022//THEFOLLOWINGMAIN**FUNCTIONALITIES**AREDEFINEDINTHISLIBRARY
023//>>MAIN<<:getchar(),putchar(),RcvIntEn,RcvIntDsb,XmtIntEn,
024//XmtIntDsb,XmtRcvActivate
025//
026//>>ANCILLARY<<:Bauds9600Value,CommIntEn,RcvChar,RcvRdy,
027//XmtChar,XmtRdy
028
029//==================================================================
030//***REDEFINE***MC9S08QE128REGISTERSANDREQUIREDBITS
031//..forSCISerialCommunicationsInterface
032//>>>ALIAS<<<areothernamesforsameaddresses.BECAREFUL!
033
034//******************************************************************
035//SCI1BD:EQU$0020;BaudeRateregister
036//LOOPMODE!!!

250

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

037
038#defineBauds9600Value0x001A//16BITS:4e6/(16*9600)=26.04=0x1A
039
040//
041//SCI1D:EQU$27
042
043#defineXMTBUFSCI1D//TransmiterBuffer
044#defineRCVBUFSCI1D//ReceiverBuffer
045
046//
047//SCI1C2:EQU$23
048
049#defineXMTCTRLREGSCI1C2
050#defineRCVCTRLREGSCI1C2
051
052#defineXMTENSCI1C2_TE_MASK//TE:TransmiterEnabl%00001000
053#defineXMTIENSCI1C2_TIE_MASK//TIE:XmtINTEnabl%10000000
054#defineXMTIEN_bitSCI1C2_TIE//7
055
056#defineRCVENSCI1C2_RE_MASK//RE:ReceiverEnable%00000100
057#defineRCVIENSCI1C2_RIE_MASK//RIE:RcvINTEnable%00100000
058#defineRCVIEN_bitSCI1C2_RIE//5
059
060#defineXmtRcvEnab(XMTEN|RCVEN)//EnableBOTHdevices%00001100
061
062//==================================================================
063//SCI1S1:EQU$24
064
065#defineXMTSTATREGSCI1S1
066#defineRCVSTATREGSCI1S1
067
068//Relevantbits:
069
070#defineXMTRDYSCI1S1_TDRE_MASK//TransmiterDataRegisterEmpty
071#defineXMTRDY_bitSCI1S1_TDRE//7(mSCI1S1_TDRE:%10000000)
072
073#defineRCVRDYSCI1S1_RDRF_MASK//ReceiveDataRegisterFull
074#defineRCVRDY_bitSCI1S1_RDRF//5(mSCI1S1_RDRF:%00100000)
075
076#defineXMTEMPTYSCI1S1_TC_MASK//TransmissionCompleteFlag
077#defineXMTEMPTY_bitSCI1S1_TC//6(mSCI1S1_TC:%01000000):LAST
078
079//
080//Receiver:
081
082#defineOVERRUNERRSCI1S1_OR//OR:Overrun%00001000
083#defineNOISERRSCI1S1_NF//NF:NoiseFlag%00000100
084#defineFRAMERRSCI1S1_FE//FE:FramingError%00000010
085#definePARERRSCI1S1_PF//PE:ParityError%00000001
086
087#defineRCVErrs(OVERRUNERR|NOISERR|FRAMERR|PARERR)
088

251

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

089//******************************************************************
090//MACRODEFINITIONS
091
092#defineSCI9600N8(SCI1BD=Bauds9600Value)//Prog.SCI@9600,8,N
093
094//
095#defineXmtRcvActivate(SCI1C2=XmtRcvEnab);/*ACTIVATEXmt&Rcv*/\
096SCI9600N8/*SerialCommunicationsInterface*/\
097/*..9600bps,Noparity,8bits*/
098
099//==================================================================
100#defineRcvRdyRCVRDY_bit
101
102//
103#defineRcvCharRCVBUF
104
105//
106//getchar()MAYRearmRcvInterruptsifinsideISR
107bytegetchar(){
108Wait(RcvRdy);
109returnRcvChar;
110}
111
112//==================================================================
113#defineXmtRdyXMTRDY_bit
114
115//
116#defineXmtChar(c)(XMTBUF=(byte)(c))
117
118//
119#defineputchar(c)_putchar((byte)(c))
120//putchar(c)MAYrearmXmtinterruptsifinsideISR
121byte_putchar(bytec)
122{
123Wait(XmtRdy);
124XmtChar(c);
125returnc;
126}
127
128//==================================================================
129#defineXmtIntEn(XMTIEN_bit=1)
130//
131#defineXmtIntDsb(XMTIEN_bit=0)
132//
133#defineRcvIntEn(RCVIEN_bit=1)
134//
135#defineRcvIntDsb(RCVIEN_bit=0)
136
137//
138//InterruptEnableforCommunications(Remember:Outputdevicesare
139//..enabled**ONLY**whentheyarereadyfortransmitting
140//ReadingRCVSTATREGandRCVBUF,clearanypossiblyRCVReadyFlag

252

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

141//..pendingatthemomentofinterruptenablingthedevice
142
143#defineCommIntEn{RCVSTATREG;RCVBUF;RcvIntEn;}
144
145//==================================================================
146//AnciliaryStuff
147
148#defineI//NULdefinition.Fromthispointon,'I'meansNOTHING!
149#defineForeverfor(;;){
150#defineEndforever}
151
152#endif//SCICOMM_H_INCLUDED

COMENTARIOS a ["Labs-C\Lab3\SciComm\SciComm.h"]:
001#ifndefSCICOMM_H_INCLUDED
002#defineSCICOMM_H_INCLUDED

LasprimerasdoslneassonmuycomunesentodoslosincludefilesdeC;suobjetivoes
que el cdigo del archivo NO se agregue mltiples veces, aun cuando el programador,
concienteoinconcientemente,lohayaincluidomsdeunavez.Sielsmbolo,eneste
caso:SCICOMM_H_INCLUDED,quenormalmenteseextraedelmismonombredelincludefile,
noexiste,entoncesseloDEFINEyseincluyeeltexto;siYAestdefinido,sesalta
todalainclusindecdigo(hastael#endif//SCICOMM_H_INCLUDEDfinal)

Refirasealmanual:02MC9S08QE128RM(ReferenceManual)U.pdf

Wait,CpuIntEn,CpuIntDsb,yEOFyalosvimosconanterioridad.

LasfuncionalidadesPRINCIPALESdefinidasaquson:

XmtRcvActivate:Energizayactivalosdosperifricos:XMTYRCV
getchar():Leeorecibeunsmbolodelpuertodecomunicaciones
putchar():Envaunsmboloporelpuertodecomunicaciones
RcvIntEn:HabilitalasinterrupcionesdelReceptor
RcvIntDsb:DeshabilitalasinterrupcionesdelReceptor
XmtIntEn:HabilitalasinterrupcionesdelTransmisor
XmtIntDsb:DeshabilitalasinterrupcionesdelTransmisor

Otrasfuncionalidadesauxiliaresson:

Bauds9600Value:ProgramaelpuertoSCIparatrabajara:9600,8N1:9600bps,8bitspor
smbolo,Noparity,1stopbit

Como de costumbre, se redefinen los smbolos definidos por el fabricante para


cambiarlosporotrosquetenganmayorsignificado,afindemejorarlainteligibilidad;
sonALIASoasignacionesnumricas:

035//SCI1BD:EQU$0020;BaudeRateregister
038#defineBauds9600Value0x001A//16BITS:4e6/(16*9600)=26.04=0x1A

253

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Se observa aqu lo mismo que ya incluimos en la contraparte en ASM: que tanto el


Registro de Transmisin (XMTBUF) como el de Recepcin (RCVBUF), siendo DOS entidades
DIFERENTES, tienen la MISMA direccin (0x27). La discriminacin entre uno y otro se
lograporelSENTIDOenquefluyenlosdatos.SihayunaasignacinSOBREelregistro
XMTBUF,esunatransmisin;silaasignacinesDESDEelregistro,seleeelRCVBUF

041//SCI1D:EQU$27
043#defineXMTBUFSCI1D//TransmiterBuffer
044#defineRCVBUFSCI1D//ReceiverBuffer

HayunsoloRegistrodeControldeintersenestalibrera:SCI1C2(SCI1,Control2);
de all, algunos bits son para XMT y otros para RCV. Otros fabricantes diferencian
mucho ms abruptamente los dos perifricos, el de transmisin y el de recepcin, e
incluyen DOS registros de Control; por eso yo he incluido DOS nombres, XMTCTRLREG y
RCVCTRLREG,perosonALIASdelnicoregistrofsico:

047//SCI1C2:EQU$23
049#defineXMTCTRLREGSCI1C2
050#defineRCVCTRLREGSCI1C2

LosbitsdeControlquenosinteresan,tantoparaXMTcomoparaRCV,son:

052#defineXMTENSCI1C2_TE_MASK//TE:TransmiterEnabl%00001000
053#defineXMTIENSCI1C2_TIE_MASK//TIE:XmtINTEnabl%10000000
054#defineXMTIEN_bitSCI1C2_TIE//7
055
056#defineRCVENSCI1C2_RE_MASK//RE:ReceiverEnable%00000100
057#defineRCVIENSCI1C2_RIE_MASK//RIE:RcvINTEnable%00100000
058#defineRCVIEN_bitSCI1C2_RIE//5

Hay que recordar que existe la Habilitacin (ENABLE: XMTEN, RCVEN), que equivale a
energizarelperifrico,yqueesdiferentedelIEN:InterruptENable:XMTIEN,RCVIEN.

Nuestra librera siempre Habilita los dos perifricos simultneamente, por lo que
tenemosunsmboloparaeso:XmtRcvEnab

060#defineXmtRcvEnab(XMTEN|RCVEN)//EnableBOTHdevices%00001100

ConloselementosdeStatusocurrelomismoqueconlosdeControl,queseencuentran
reunidostantolosdeXMTcomolosdeRCV,enelregistrodeStatus1:SCI1S1

063//SCI1S1:EQU$24
065#defineXMTSTATREGSCI1S1
066#defineRCVSTATREGSCI1S1

Losbitsquenosinteresanson:

070#defineXMTRDYSCI1S1_TDRE_MASK//TransmiterDataRegisterEmpty
071#defineXMTRDY_bitSCI1S1_TDRE//7(mSCI1S1_TDRE:%10000000)

073#defineRCVRDYSCI1S1_RDRF_MASK//ReceiveDataRegisterFull
074#defineRCVRDY_bitSCI1S1_RDRF//5(mSCI1S1_RDRF:%00100000)

254

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

076#defineXMTEMPTYSCI1S1_TC_MASK//TransmissionCompleteFlag
077#defineXMTEMPTY_bitSCI1S1_TC//6(mSCI1S1_TC:%01000000):LAST

LosERRORES,comovimosalanalizarlasrutinasdeComunicacionesenASM,slopodemos
detectarlosenelRECEPTOR:

082#defineOVERRUNERRSCI1S1_OR//OR:Overrun%00001000
083#defineNOISERRSCI1S1_NF//NF:NoiseFlag%00000100
084#defineFRAMERRSCI1S1_FE//FE:FramingError%00000010
085#definePARERRSCI1S1_PF//PE:ParityError%00000001

087#defineRCVErrs(OVERRUNERR|NOISERR|FRAMERR|PARERR)

LadefinicinesexactamentelamismaqueenASM,pueseselMISMOperifrico:

OVERRUN ocurre cuando el serializador de entrada completa de leer los 10 bits del
smboloquellega,ylecorrespondeahoratrasladarloalBUFFERderecepcin,perose
encuentraconqueelprogramaanNOhaledoelcarcteranterior;asquedetodas
maneras lo almacena en el registro de recepcin, sobrescribiendo la informacin que
allseencontraba,ysealamedianteestabandera,queseestperdiendoinformacin
deentrada,porsobreescrituradelRCVBUF.Elprogramadortienequetomarnotadeesto,
probablemente solicitando la retransmisin de la informacin al otro extremo de la
lnea. Normalmente hay que calibrar la cantidad de informacin y la velocidad de
entrada, para evitar que esto suceda. Manejar la entrada por interrupciones, y hacer
usodeFIFOsoCOLASeslomsindicado.

NOISERRocurrecuandolalneatieneruido,quesereflejaporvariacionesenlaseal
queseestleyendo,yqueocurrenentreelcomienzoyelfinaldelosbits.Sesupone
quelalneanocambiadevaloreneseintervalo.

FRAMERRsepresentacuando,habiendoelreceptordetectadounbitdeSTART,alllegara
laposicinendondedeberaestarelbitdeSTOP,NOhayun1.Estopuedesignificar
que el receptor se est descincronizando, y que a lo mejor el bit que detect como
Startnoloera.

PARERRocurrecuando,estandohabilitadoelclculodeparidad,seencuentraqueenla
recepcin sta no coincide con el valor que tendra que haber. Nosotros NO estamos
usandoParidadennuestrabibliotecadeComunicacionesSeriales.

090//MACRODEFINITIONS

092#defineSCI9600N8(SCI1BD=Bauds9600Value)//Prog.SCI@9600,8,N

095#defineXmtRcvActivate(SCI1C2=XmtRcvEnab);/*ACTIVATEXmt&Rcv*/\
096SCI9600N8/*SerialCommunicationsInterface*/\
097/*..9600bps,Noparity,8bits*/

Mirebien,paraentenderlaMacro,losCONTINUADORESdelnea:"\"

Sialgoallnoentiende,TIENEQUEESTUDIARC

255

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

100#defineRcvRdyRCVRDY_bit
103#defineRcvCharRCVBUF

getchar() es una funcin BLOQUEANTE, que suspende el flujo del programa hasta que se
hayarecibidoundato,loquesereflejaalencenderelbitde'RcvRdy'.Devuelveel
valorrecibido:RcvChar(quetienedosalias:RCVBUF,queasuvezesaliasdeSCI1D)

Lasecuenciade:leerelbitRcvRdyyacontinuacinleerelRCVBUF(vaRcvChar),es
tambin la necesaria para el protocolo de Acknowledge de interrupciones del RCV; por
esoseusa'getchar'tambinDENTROdelaISRdeRecepcin.

106//getchar()MAYRearmRcvInterruptsifinsideISR
107bytegetchar(){
108Wait(RcvRdy);
109returnRcvChar;
110}

En una prxima revisin, cambiar RcvChar por RcvChar(), para mimetizar mejor el
comportamientodeunafuncinyasemejarlamsaXmtChar().Suusocambiaras:

109returnRcvChar();
113#defineXmtRdyXMTRDY_bit
116#defineXmtChar(c)(XMTBUF=(byte)(c))

putchar()tambinesunafuncinBLOQUEANTE,quesuspendeelflujodelprogramahasta
queelTransmisorestlistoparaenviarundato,loquesereflejaalencenderelbit
de'XmtRdy'.

La secuencia de: leer el bit XmtRdy y a continuacin escribir en el XMTBUF, va


XmtChar(),estambinlanecesariaparaelprotocolodeAcknowledgedeinterrupciones
delXMT;poresoseusa'putchar()'tambinDENTROdelaISRdeTransmisin.

119#defineputchar(c)_putchar((byte)(c))
EstadefinicinobligamedianteunCASTaqueelsmboloquesetransmiteseaunBYTE,
aunqueelusuariohayaempleadounWORD.

SABELOQUEESUNCAST?SUUSOEIMPORTANCIA?NO?TIENEQUEESTUDIARC.

121byte_putchar(bytec)
122{
123Wait(XmtRdy);
124XmtChar(c);
125returnc;
126}

Smbolosimportantes:

129#defineXmtIntEn(XMTIEN_bit=1)
131#defineXmtIntDsb(XMTIEN_bit=0)
133#defineRcvIntEn(RCVIEN_bit=1)
135#defineRcvIntDsb(RCVIEN_bit=0)
143#defineCommIntEn{RCVSTATREG;RCVBUF;RcvIntEn;}

256

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

ElCommIntEn,ohabilitacindeinterrupcionesparaComunicaciones,hacelomismoque
mencionamosenelprogramaenASM:slohabilitalasinterrupcionesdeRCV;lasdeXMT
debe habilitarse caso a caso por el programador, cuando haya algo que enviar por
interrupciones.

Lafuncionalidad,queusteddebeCORROBORARconelReferenceManual,consisteenleer
elRCVSTATREG;luegoleerelRCVBUF;yporltimohabilitarlasInterrupcionesdeRCV,
mediante:RcvIntEn.

Cdigoauxiliar:

148#defineI//NULdefinition.Fromthispointon,'I'meansNOTHING!
149#defineForeverfor(;;){
150#defineEndforever}
152#endif//SCICOMM_H_INCLUDED
Paraqupuedeutilizarseel'#defineI'quehacequelaletraInovalgaNADA?

56) Send 'A' to 'z' letters for ever, to PC


["LabsC\Lab3\SciComm\1tstXmt.c"]
01//******************************************************************
02//Program1TstXmt.C:TestSCIComm.Support
03//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04//C11D2013(C)
05//..Send'A'to'z'lettersforever,toHyperterminal
07//******************************************************************
08//IncludeFiles
09#include<hidef.h>//ForEnableInterruptsmacro
10#include"derivative.h"//Includeperipheraldeclarations
12#include"SciComm.h"//SCIComm.Support
14#defineCR0x0D
15#defineLF0x0A
17//******************************************************************
18voidmain(void)/*()*/
19{byteLetter;
21//
22//>>>ALWAYSincludethefollowing2lines
23//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
24#defineCOP_Disable0x42
25SOPT1=COP_Disable;//SystemOptions1
27//
28SCI9600N8;//SetupSerialCommunicationsInter
29XmtRcvActivate;//..face:9600bps,Noparity,8bits
30//
32while(1){
33for(Letter='A';Letter<='z';Letter++){
34putchar(Letter);
35}
36putchar(CR);//CarriageReturn(CR:'\r'inC)
37putchar(LF);//LineFeed(LF:'\n')
38}
39}

257

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab3\SciComm\1tstXmt.c"]:
El comienzo es ya conocido. Se definen luego dos smbolos, ambos definidos por el
estndar ASCII (American Standard Code for Information Interchange) el CR, que es el
smbolo que hace que el cursor se vaya a la izquierda (Carriage Return, cuando se
tratabademquinasdeescribir,oTeletipos),yelNL(NewLine,quesaltaalalnea
siguiente)

14#defineCR0x0D
15#defineLF0x0A

18voidmain(void)/*()*/
19{byteLetter;

Luegodelapartemsconvencional,vienelainicializacindelSCI:

28SCI9600N8;//SetupSerialCommunicationsInter
29XmtRcvActivate;//..face:9600bps,Noparity,8bits

YQUPASCONELCLI?EstaaplicacinNOusainterrupciones.

Elcicloinfinitoparaesteprogramageneralasletrasdesdela'A'hastala'z'ylas
transmite con putchar( Letter ); al finalizar cada secuencia agrega un Retorno de
Cursor,CR('\r'enC)yunSaltodeLnea,LF('\n'enC),yrecomienzaconlasletras
enlasiguientelnea,parasiempre:

32while(1){
33for(Letter='A';Letter<='z';Letter++){
34putchar(Letter);
35}
36putchar(CR);//CarriageReturn(CR:'\r'inC)
37putchar(LF);//LineFeed(LF:'\n')
38}
39}

57) SEND STEP BY STEP (IRQ) 'A' TO 'Z' LETTERS TO PC & SHOW IN LEDS
["LabsC\Lab3\SciComm\1tstXmtLeds.c"]
01//******************************************************************
02//Programa1TstXmtLeds.C:TestSCIComm.Support
03//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04//C11D2013(C)
05//
06//..Send'A'to'z'lettersforevertoHyperterminal.LEDsdisplay
07//..StepbystepusingIRQ
08//******************************************************************
09//IncludeFiles
10#include<hidef.h>/*forEnableInterruptsmacro*/
11#include"derivative.h"/*includeperipheraldeclarations*/
12
13#include"SciComm.h"//SCIComm.Support
14

258

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

15//
16//GlobalVariables
17
18volatilebyteGlobalVar;
19
20//******************************************************************
21voidmain(void)
22{byteLetter;
23
24//
25//>>>ALWAYSincludethefollowing2lines
26//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
27#defineCOP_Disable0x42
28SOPT1=COP_Disable;//SystemOptions1
29
30//
31//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
32//InDEMOQUE128,DO***NOT***USEPTC5'sASSOCIATEDLED,asitis
33//..alsothepinusedtoDISABLECOMM1!!!viaJumperJ8,THANKS!
34//
35//NOTE1:ForOutputPins/Ports,FirstloadaSAFEvalue(youwill
36//..decideit),then,programthemforOutputs.Thisway,itwill
37//..NOTappearFALSEoutput,values/glitches.
38//
39//NOTE2:Supposeyourprogramhas,forexample,twooutputsthat
40//..willcontroltheaccessfor2devicestoacommonbus.The
41//..logicis:00:Noperipheralhasaccess.01:Ahasaccess.
42//..10:Bhasaccess.11:Neverhappens!Ifitwill,peripherals
43//..willburnout.
44//Now,atPowerUp,ALLdigitalpinsdefaulttoINPUTS.Without
45//..Pullupresistors:TheyFLOAT!!Forhowlong?Italldepends
46//..onoscilatorsetup,andthetimeyouexpendbeforeprogram
47//..mingthepinsforoutput.Itmeans:maybeBOTHA&Bdevices
48//..willreachthebus...andBURN!Shortcircuittheiroutputs!!
49//Sleeponthis,andcomeupwithasolution...
50
51PTCD=0xFF;
52PTED=0xFF;
53PTCDD=0x1F;//..(theydriveLEDsonDEMOQE128)
54PTEDD=0xC0;
55
56//
57//EnableIRQpin
58IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
59IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn
60
61//
62SCI9600N8;//SetupSerialCommunicationsInter
63XmtRcvActivate;//..face:9600bps,Noparity,8bits
64
65CpuIntEn;
66

259

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

67//
68while(1){
69for(Letter='A';Letter<='z';Letter++){
70putchar(Letter);
71Wait(GlobalVar);
72GlobalVar=0;
73PTCD=~Letter;
74PTED=~Letter;
75}
76putchar('\r');//CarriageReturn(CR)
77putchar('\n');//LineFeed(LF)
78}
79}
80
81//==================================================================
82interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
83{
84GlobalVar=1;
85IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
86//..(RearmIRQInterrupts)
87}

COMENTARIOS a ["Labs-C\Lab3\SciComm\1tstXmt-Leds.c"]:
Laparteinicialeslaconvencional.Leanotravez(yahabamosdicholomismocuando
hicimos los ejercicios en ASM) y con detenimiento los requisitos para programar los
terminalesdigitalescomoSALIDAS:

31//InitLEDsPORTsPTCD(bits05)andPTED(bits67)foroutput
32//InDEMOQUE128,DO***NOT***USEPTC5'sASSOCIATEDLED,asitis
33//..alsothepinusedtoDISABLECOMM1!!!viaJumperJ8,THANKS!
34//
35//NOTE1:ForOutputPins/Ports,FirstloadaSAFEvalue(youwill
36//..decideit),then,programthemforOutputs.Thisway,itwill
37//..NOTappearFALSEoutput,values/glitches.
38//
39//NOTE2:Supposeyourprogramhas,forexample,twooutputsthat
40//..willcontroltheaccessfor2devicestoacommonbus.The
41//..logicis:00:Noperipheralhasaccess.01:Ahasaccess.
42//..10:Bhasaccess.11:Neverhappens!Ifitwill,peripherals
43//..willburnout.
44//Now,atPowerUp,ALLdigitalpinsdefaulttoINPUTS.Without
45//..Pullupresistors:TheyFLOAT!!Forhowlong?Italldepends
46//..onoscilatorsetup,andthetimeyouexpendbeforeprogram
47//..mingthepinsforoutput.ITMEANS:maybeBOTHA&Bdevices
48//..willreachthebus...andBURN!Shortcircuittheiroutputs!!
49//Sleeponthis,ANDCOMEUPWITHASOLUTION...

Se determina que queremos que al iniciar las salidas, todas tengan unos en sus
terminales:
51PTCD=0xFF;
52PTED=0xFF;

260

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

LuegoseprogramaloscorrespondientesbitsenlosDirectionRegisters,5vanelPTCy
2enPTE(total7LEDs).

SeexcluyeelterminalPTC5,quequedacomoENTRADA,porquecomoyadijimosarriba,en
el DEMOQUE128 el PTC5, si est como salida (para manejar el LED asociado), tambin
INHABILITARelpuertodeComunicacionesSeriales,vaelJumperJ8.GRACIASPEMicro!

53PTCDD=0x1F;//..(theydriveLEDsonDEMOQE128)
54PTEDD=0xC0;

LahabilitacindelIRQysuautorizacinparaInterrumpir,eslaconvencional:

58IRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;
59IRQSC_IRQIE=1;//BSETIRQSC_IRQIE,IRQSC:IRQpinIntEn

Despusseinicializa,comodecostumbre,elpuertodecomunicacionesSCI,seActivan
losdosperifricos,elderecepcinyeldetransmisin,yAQUS,sehabilitanlas
interrupcionesdelCPU:

62SCI9600N8;//SetupSerialCommunicationsInter
63XmtRcvActivate;//..face:9600bps,Noparity,8bits
65CpuIntEn;

El ciclo indefinido es tan sencillo como el del anterior ejercicio, pero despus de
transmitircada letra, incluye una espera a que 'GlobalVar' valga uno (por qu est
inicializadaenCERO?Siannolosabe,DESISTA)

CuandolaIRQISRcolocaen1aGlobalVar,elprogramacontina,reponiendoacerola
variable,paraelprximoturno,ypresentandolaletraporlosLEDs.Semueve~Letter
(NEGADA booleanamente) porque, como ya sabemos, los genios de PE Micro encienden los
LEDsconCEROS:

68while(1){
69for(Letter='A';Letter<='z';Letter++){
70putchar(Letter);
71Wait(GlobalVar);
72GlobalVar=0;
73PTCD=~Letter;
74PTED=~Letter;
75}
76putchar('\r');//CarriageReturn(CR)
77putchar('\n');//LineFeed(LF)
78}
79}
LarutinaIRQISReslaconvencional,msGlobalVar=1;

82interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
83{
84GlobalVar=1;
85IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQInterrupt
86//..(RearmIRQInterrupts)
87}

261

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

58) ECHO
HaceECHOaloscaracteresquelelleganalequipodesdeotraestacin.

Para no engaarse con el ECO LOCAL el programa retransmite la letra recibida,


INCREMENTADAenuno:sireciboun'A',transmitouna'B'yassucesivamente.

Recuerdeprobarloenvindole"HAL"(lasupercomputadorade"2001OdiseadelEspacio"):
apareceenlapantalla...IBM.

["LabsC\Lab3\SciComm\2echo1.c"]
01//******************************************************************
02//Program2Echo1.c:TestSCIComm.Support
03//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)
04//C11DN2013(C)
05//LuisG.UribeC.,D11M2007J16A09L08J09S16J2012(HCS08)L25N2013
06//Tobesurethatthereis"ECHO",returnback'letter+1',
07//..i.e:ifHyperterminalsends'A',HC9S08willreturn'B'...
08//..fortherange:'A'<=char<'z'.
09//Anyothercharsarereturnedbackwithoutmodification.

10//******************************************************************
11//IncludeFiles
12#include<hidef.h>//forEnableInterruptsmacro
13#include"derivative.h"//includeperipheraldeclarations

14#include"SciComm.h"//SCIComm.Support

15//******************************************************************
16voidmain(void)
17{byteLetter;

18//
19//>>>ALWAYSincludethefollowing2lines
20//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
21#defineCOP_Disable0x42
22SOPT1=COP_Disable;//SystemOptions1

23//
24SCI9600N8;//SetupSerialCommunicationsInter
25XmtRcvActivate;//..face:9600bps,Noparity,8bits

26//Prompt:
27for(Letter='A';Letter<='z';Letter++){
28putchar(Letter);
29}
30putchar('\r');//CarriageReturn(CR)
31putchar('\n');//LineFeed(LF)

32//************NOTE:************
33//ToSIMULATESCI*inputs*usePEMicroSCI1debuggercommand.
34//

262

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

35//ItwillbeinstructivetodisplaySCI1S1(statusregister),and
36//..seemostimportantflags,bits7,6,5:XMTRDY,XMTEMPTY,RCVRDY.
37//Whiledebugging,seehowreadingStatusANDwritingBUF,clears
38//..theRCVReadyflag.SeealsohowXMTStatuswork:RDY&EMPTY

39while(1){//OnlycharsinrangeA..zwillbe
40if((Letter=getchar())>='A'&&Letter<='z'){
41Letter++;//..returnedasNEXTchar:Letter++
42}
43putchar(Letter);//..Thosenotinrangewillecho
44}//Endwhile(1)//..WITHOUTanymodification:Letter

45}

COMENTARIOS a ["Labs-C\Lab3\SciComm\2echo1.c"]:
Esteprogramatampocoemplealasinterrupciones:estodoentradaysalidaprogramada;
poresonoapareceunCpuIntEn.

Se comienza enviando un aviso (Prompt) al otro terminal, para notificarle que el


programadeesteladoestlistoparatrabajar;aquenviamosunalneacompuestapor
lasletrasdela'A'ala'z',peroustedpuedeusaruntextocualquieracomo"Ready":

26//Prompt:
27for(Letter='A';Letter<='z';Letter++){
28putchar(Letter);
29}
30putchar('\r');//CarriageReturn(CR)
31putchar('\n');//LineFeed(LF)

Si se quieren simular *inputs* del SCI, hay un comando apropiado en el Debugger.


Resultainstructivo,adems,mostrarensupantallaelSCI1S1(statusregister)yver
lasbanderasmsimportantes,bits7,6y5:XMTRDY,XMTEMPTYyRCVRDY.Observetambin
cmo,laaccindeleerelStatusYescribirsobreBUF,BORRAelRCVReadyflag.Mire
tambincmotrabajaelXMTStatus,ambosbits:RDYyEMPTY.

39while(1){//OnlycharsinrangeA..zwillbe
40if((Letter=getchar())>='A'&&Letter<='z'){
41Letter++;//..returnedasNEXTchar:Letter++
42}
43putchar(Letter);//..Thosenotinrangewillecho
44}//Endwhile(1)//..WITHOUTanymodification:Letter

59) ECHO USANDO INTERRUPCIONES


["LabsC\Lab3\SciComm\3echoInt1.c"]
01//******************************************************************
02//Program3EchoInt1.c:TestSCIComm.Support
03//LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)D24J2012
04//S30N2013(C)C11D2013
05//..Same2Echo1.CprogrambutusingINTERRUPTSforXMT

263

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations
10#include"SciComm.h"//SCIComm.Support
11//==================================================================
12//GLOBALVARIABLES
13byteXmtNchars;//SoftFlagforMain:0NothingtoXmt
14byte*XmtPtr;//charpointerofnextdatatoXmt
15byteMessage[]="12345\n\r";//Shortmessage
16//byteMessage[]="Esteeselmensajedeprueba,"
17//"primeroentransmitirsealPCporinterrupciones\n\r"
18//******************************************************************
19voidmain(void)
20{byteLetter;
21//
22//>>>ALWAYSincludethefollowing2lines
23//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
24#defineCOP_Disable0x42
25SOPT1=COP_Disable;//SystemOptions1

26//
27SCI9600N8;//SetupSerialCommunicationsInter
28XmtRcvActivate;//..face:9600bps,Noparity,8bits

29//==================================================================
30//Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
31//Prompt:

32XmtPtr=Message;//InitXmtPtrwith'Message'address;
33XmtNchars=sizeof(Message);

34XmtIntEn;//XmtISRwillsendthemessageand
35//..clear'XmtNchars'whenfinished
36CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs
37//
38//XmtLoop:

39Wait(XmtNchars==0);//WaituntildoneORjustWaitForEver
40Wait(0);//..WaitForEver
41}

42//==================================================================
43interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
44{
45if(XmtNchars){//Seeifdone;ifnot:
46putchar(*XmtPtr++);//(NOTE:putcharclearsXMTRDY.bit)
47XmtNchars;//Adjustcharcounter
48}else{//IfXmtDone:
49XmtIntDsb;//..
50}
51}

264

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab3\SciComm\3echoInt-1.c"]:
VariablesGlobales,paraservisiblestantoenelprogramaprincipal:

XmtNchars,quemantieneelnmeroactualdecaracteresquefaltanportransmitirse;es
de tipo byte, por lo cual no pueden manejarse mensajes de ms de 255 letras; 0
significavaco.

*XmtPtr apuntador a caracteres, seala el siguiente dato que ser transmitido. byte
*XmtPtr

13byteXmtNchars;//SoftFlagforMain:0NothingtoXmt
14byte*XmtPtr;//charpointerofnextdatatoXmt

Siendoquelosapuntadorestienen16bits,porqunosehizoladefinicincomo:word
*XmtPtr
SIDUDATIENEQUEESTUDIARMUCHSIMOC(SINDUDA)

Luegovieneelmensajequesequieretransmitir;elsegundo,comentado,esunpocoms
largo,paraensayar:

15byteMessage[]="12345\n\r";//Shortmessage
16//byteMessage[]="Esteeselmensajedeprueba,"
17//"primeroentransmitirsealPCporinterrupciones\n\r"

La inicializacin estndar, ms la de las variables XmtPtr y XmtNchars. La tabla se


'encola'parasertransmitidadeunasolavez:

27SCI9600N8;//SetupSerialCommunicationsInter
28XmtRcvActivate;//..face:9600bps,Noparity,8bits
32XmtPtr=Message;//InitXmtPtrwith'Message'address;
33XmtNchars=sizeof(Message);
34XmtIntEn;//XmtISRwillsendthemessageand
35//..clear'XmtNchars'whenfinished

yNOOLVIDARhabilitarlasinterrupcionesGlobales,delCPU:

36CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs

Elciclodetransmisinesmuysimple:elprogramaespera(Wait)hastaqueelnmerode
caracteresseacero,loqueleindicalafinalizacindelatransmisindelmensaje,y
contina;comoesteejerciciollegahastaall,hacemosunasimulacindeunHALT:

38//XmtLoop:
39Wait(XmtNchars==0);//WaituntildoneORjustWaitForEver
40Wait(0);//..WaitForEver

La rutina de transmisin es muy simple; lo primero es la definicin de tipo


'interrupt', la identificacin de la posicin de la rutina en el Vector de
Interrupciones,'VectorNumber_Vsci1tx'(todosSMBOLOS,nomsNMEROS)definidosenel
correspondienteincludefile.Porltimo,elnombredelarutinadeinterrupciones,de
tipo'void':XmtISR

265

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

43interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/

Si an hay caracteres para transmitir, los enva con putchar (que realiza el ACK),
incrementaelapuntadordecaracteres,decrementaelnmerodesmbolosquefaltanpor
transmitirse,yRTI(AUNQUEXmtNcharshayaproducidoCERO)

45if(XmtNchars){//Seeifdone;ifnot:
46putchar(*XmtPtr++);//(NOTE:putcharclearsXMTRDY.bit)
47XmtNchars;//Adjustcharcounter

Sialmomentodeinterrumpirparatransmitir,seencuentraqueXmtNcharsvalecero,se
AUTOdeshabilitanlasinterrupcionesdetransmisinyseretornaconRTI:

48}else{//IfXmtDone:
49XmtIntDsb;//..
50}
51}

Estemecanismoenelcualel'Cliente'(main)haceunapeticinalarutinadeServicio
(XmtISR),activndolelasInterrupciones,ydondelaISRseAUTODESACTIVAalterminar
lo que le solicitaron, ES LA FORMA en que usted debe trabajar: MECANISMO Cliente
Servidor.

Ocurrequeconfrecuencia,porhacerundiseonomuypulcro,aparecenvariosClientes
(o lugares en su cdigo en donde se habilitan las interrupciones), O SE MEZCLAN
putcharsdesdeMAINylaISR:ESORARAVEZFUNCIONA.YelprogramadorNOVAASABER
PORQU!

NOLOHAGA

60) ECHO CON INTERRUPCIONES, ASCIZ STRINGS


El mecanismo anterior define los mensajes mediante una posicin de memoria en donde
comienzanlossmbolosalmacenados(unatabla)yunTamaoocantidaddeletrasquehan
demanipularse.Comopartedelaimplementacinsedefinendoselementosauxiliares,el
apuntadoralprximosmbolo,yelContadordeSmbolosquefaltanporprocesarse.As
sonlos"strings"enC++.

UnaaproximacinparecidacambiaelContadordeSmbolosporunTERMINADOR,queesun
smboloespecialqueindicaelfinaldelmensaje.EnC,los"strings"sedefinenas,y
el terminador es un byte NULO, con todos sus bits en CERO. Un nombre, anterior a la
existencia del lenguaje C, que designa esto mismo, es el de un texto de tipo ASCIZ
(cdigoASCIIterminadoenZERO)

Esteejemploessimilaralanterior,peromuestraelmanejodemensajesdeltipoASCIZ:

["LabsC\Lab3\SciComm\3EchoInt2Z.c"]
01//******************************************************************
02//Program3EchoInt2Z.c:TestSCIComm.Support
03//LuisG.UribeC.,M13M2007J16A09L08J09L18J2012(HCS08)D24J2012
04//M10D2013(C)
05//..Similarto2Echoint1.C,butusesASCIZ

266

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//ForEnableInterruptsmacro
09#include"derivative.h"//Includeperipheraldeclarations

10#include"SciComm.h"//SCIComm.Support

11//==================================================================
12//GLOBALVARIABLES

13byte*XmtPtr;//charpointerofnextdatatoXmt
14byte*Message="12345\n\r";//Shortmessage

15//byte*Message="Esteeselmensajedeprueba,"
16//"primeroentransmitirsealPCporinterrupciones\n\r"

17//******************************************************************
18voidmain(void)/*()*/
19{
20//
21//>>>ALWAYSincludethefollowing2lines
22//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
23#defineCOP_Disable0x42
24SOPT1=COP_Disable;//SystemOptions1

25//
26SCI9600N8;//SetupSerialCommunicationsInter
27XmtRcvActivate;//..face:9600bps,Noparity,8bits

28//==================================================================
29//Transmityourmessage:Enqueatoncefull'Message'TableforXmt:
30//Prompt:

31XmtPtr=Message;//InitXmtPtrwith'Message'address;
32XmtIntEn;//XmtISRwillsendthemessageand
33//..autodesable
34CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs

35//
36//XmtLoop:
37Wait(0);//..WaitForEver

38}

39//==================================================================
40interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
41{//NOTE:putcharclearsXMTRDY.bit.Veryclever...

42if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
43XmtIntDsb;
44}
45}

267

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab3\SciComm\3EchoInt-2Z.c"]:
ElMessagees"12345\n\r",ycomoesunStringdeC(porlascomillas),aunquenolo
vemos sabemos que est terminado por un ltimo smbolo, el '\0' o NUL byte. La
diferenciaconladefinicinanterioressutil,perofundamental.

14byte*Message="12345\n\r";//Shortmessage

Aqu se inicializa el pointer de transmisin con la direccin donde comienza el


mensaje,ysimplementesehabilitanlasinterrupciones,deltransmisor,ydelCPU.El
cdigonohacenadams,asquesesimulaunHALTalfinal:

31XmtPtr=Message;//InitXmtPtrwith'Message'address;
32XmtIntEn;//XmtISRwillsendthemessageand
33//..autodesable
34CpuIntEn;//<<<DON'TFORGET:GLOBALENABLEINTs
37Wait(0);//..WaitForEver

La rutina XmtISR es BIEN SIMPLE: Cada vez que hay una interrupcin, TRANSMITE la
prximaletraysistacoincideconelNULchar,seautodeshabilitaparainterrumpir:

40interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
41{//NOTE:putcharclearsXMTRDY.bit.Veryclever...
42if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
43XmtIntDsb;
44}
45}

61) COLAS DE DATOS


ElmanejodeColasesmuysimilaralqueyaestudiamosenASM:aqullosaqudeaqu!

Ahora, USTED TIENE QUE SABER C PARA ENTENDER ESTE CDIGO. Hasta las COMAS son
FUNDAMENTALESenelsiguientetexto:

["LabsC\Lab3\SciComm\Que.h"]
01#ifndefQUE_H_INCLUDED
02#defineQUE_H_INCLUDED
03//******************************************************************
04//QUE.HLuisG.UribeC,V20J2014:.gt.pt
05//18S1990D04S2011V29N21013
06//
07//SeveralDefinies
08
09#undefWait
10#defineWait(e)while(!(e))
11#undefCpuIntEn
12#defineCpuIntEn__asmCLI
13#undefCpuIntDsb
14#defineCpuIntDsb__asmSEI
15#undefEOF
16#defineEOF((word)1)

268

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

18//REMEMBER!!!:'byte'isUNSIGNEDchar;'word'isUNSIGNEDint
20/**/
21typedefstruct{
22byte*put;/*n(5)*/
23byte*get;/*(2)buf>++*/
24wordn;/*|(1)|>(4)get*/
25wordgt;/*(3)put>|s|*/
26wordpt;/*|i|*/
27byte*base;/*|z|*/
28byte*limit;/*|e|*/
29wordsize;/*++*/
30}QUE;
31
32/*Ejemplo:Sea'size'(1)de'buf'(2)iguala5.*
33*Lospointers'put'(3)y'get'(4)puedentenerlosvalores*
34*buf,buf+1,buf+2,buf+3,buf+4;*
35*esdecir,lospointersdebenpermanecerenelrango*
36*buf<=pointer<(buf+size),o,loqueeslomismo*
37*buf<=pointer<limit*
38**
39*'n'(5)puedevaler:*
40*0(vaco),1,2,3,4y5(lleno).Noteque'n'ES*
41*el>>>SEMAFORO<<<,eimponelassiguientesreglasdetrfico:*
42**
43*NO'deQue'cuandonsea<=0*
44*NO'enQue'cuandonsea>=size*
45**
46*Lassiguientesoperacionesestndefinidas:*
47*/
49#definedefineQue(in,n)byte_Q##in[n];QUEin
50
51#defineinitQue(in)in.base=in.put=in.get=_Q##in;\
52in.n=0;in.size=sizeof(_Q##in);\
53in.limit=in.base+in.size
54
55#defineenQue(in,c)(in.n>=in.size?EOF:\
56(in.pt=c,*in.put++=(byte)c,\
57in.put=in.put>=in.limit?\
58in.base:in.put,\
59in.n++,in.pt\
60)\
61)
62
63#definedeQue(in)(in.n<=0?EOF:\
64(in.gt=*in.get++,\
65in.get=in.get>=in.limit?\
66in.base:in.get,\
67in.n,in.gt\
68)\
69)
70
71#endif//QUE_H_INCLUDED

269

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab3\SciComm\Que.h"]:
Las primeras definiciones estn duplicadas en varios otros sitios pero NO arrojan
erroresporqueestntodasantecedidaspor#UNDEFs.

EnprimerlugarlaEstructuraquetienenmisQUEs,plasmadaenun'typedef':QUE.Enel
esquemaseindicanloselementosquelacomponen,ordenadosdel1al5.

Unacolatiene:
1. Untamaofsico,'size'
2. Unadireccindecomienzo,'buf'
3. Un apuntador al sitio EN el que almacenar (enQue) el prximo smbolo, 'put'; se
inicializaen'buf'.
4. UnapuntadoralsitioDESDEelqueextraer(deQue)lasiguienteletra,'get';se
inicializaen'buf'.
5. Y'n',MUYIMPORTANTE:indicacuntoscaractereshayenlacolaenunmomentodado.
EsteeselSEMFOROquerigeyordenalastransacciones;as:
'n'puedevaler0(vaco),1,2,...'size'(lleno)Lasreglassonlassiguientes:
NO'deQue'cuandonsea<=0NO'enQue'cuandonsea>=size
HaydosvariablestemporalesdetipoWord:'gt'y'pt';luegoveremossuuso,yporqu
sonWORDenvezdeBYTE.UnapuntadoralFINALdelatabla,'limit',noesencialpero
parafacilitarelcdigo,yunaposicinqueindicaeltamaodelacola(aqulahemos
definidocomoWORD,quepermitecolashastade64K,loqueesmucho...)

20/**/
21typedefstruct{
22byte*put;/*n(5)*/
23byte*get;/*(2)buf>++*/
24wordn;/*|(1)|>(4)get*/
25wordgt;/*(3)put>|s|*/
26wordpt;/*|i|*/
27byte*base;/*|z|*/
28byte*limit;/*|e|*/
29wordsize;/*++*/
30}QUE;

Lassiguientesoperacionesestndefinidas,igualqueensucontraparteenASM:

defineQue,initQue,enQueydeQue:

El defineQue requiere un NOMBRE de la Cola y un tamao. La definicin... tienen que


estudiarla.Sinolaentienden...TIENENQUEESTUDIARC

49#definedefineQue(in,n)byte_Q##in[n];QUEin

Primerosedefineunarreglo(vector);byte_Q##in[n];

Aquenovieronalgoas...ESTUDIENC.##eseloperadorcatenate:unedossmbolos.

270

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Elnombredelvectores:_Qseguido(CONCATENADO:##)conelnombrequeelusuariole
da a su cola, representada por el parmetro 'in', y ocupando un espacio en BYTES de
'n',parmetroquereemplazaaltamaoqueelusuariodeseadarlealaCola.

Acontinuacin,separadaporunpuntoycomadelaanterior,paraquequedeenlamisma
lnea(habanvistovariasinstruccionesdeC,enlamismalnea?)viene:QUEin,que
defineunavariableconelnombrequeelusuarioquiere,simbolizadoenlaMacroporel
parmetro'in',ydetypeQUE,segnladefinicin'typedef'anterior.

Ejemplo:Sielusuarioquieredefinirunacolallamada'ColaRead',de
'16'bytes,loexpresardelasiguienteforma:

defineQue(colaRead,16)

Elresultadoser,unarreglo:
byte_QcolaRead[16];

yunaestructurallamada'colaRead',detipoQUE.

MireelNOMBREdelarreglo:elsmbolo'_Q'concatenadoconelnombrequeseleest
dandoalacola:'colaRead'.

IMPORTANTE:

'defineQue'*TIENE*QUEEMPLEARSECOMOVARIABLE'GLOBAL',FUERADECUALQUIER{}:Fuera
demain(),ydecualquierfuncin.ComoenASM.

Despusdedefinirlacola,hayqueinicializarla.EstossehaceDENTRODEMAIN.Para
lacola'colaRead',lainvocacines:

initQue(colaRead);

51#defineinitQue(in)in.base=in.put=in.get=_Q##in;\
52in.n=0;in.size=sizeof(_Q##in);\
53in.limit=in.base+in.size

ImaginoquesabenCMOcontinuarelcdigodeunaMacroenvariaslneas:paraesose
empleael'\'.NotequelaLTIMAnololleva...

Talcomosedijoantes,seinicializanlosapuntadoresbase,putygetdelacolaen
consideracin(enelejemplo:colaRead.base,colaRead.putycolaRead.get).Elvalorque
toma es el del comienzo de VECTOR que ya se DEFINI: _Q##in, que en el ejemplo
correspondea:_QcolaRead.

Las inicializaciones continan: colaRead.n = 0; colaRead.size asume el TAMAO del


Vector,sizeof(_QcolaRead).

Sinosabecmoseusa'sizeof',ustedNOSABE"C"yTIENEQUEESTUDIARC,URGENTE.

Finalmente se inicializa la variable in.limit para apuntar a la ltima direccin del


Vector:

271

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

53in.limit=in.base+in.size

Esdecir:colaRead.limit=colaRead.base+colaRead.size

Laoperacinpara'encolar'unbyte...tomenALIENTO.MenosmalqueYOhagolalibrera
yusted,fundamentalmente,LAUSA(aunquesinolaENTIENDE,andabastanteMAL)

55#defineenQue(in,c)(in.n>=in.size?EOF:\
56(in.pt=c,*in.put++=(byte)c,\
57in.put=in.put>=in.limit?\
58in.base:in.put,\
59in.n++,in.pt\
60)\
61)

Primero,porqutienetantosparntesis?RecuerdenqueelusodeestaMacroes:
c=enQue(colaWrite,letra);

Entonces,QUESLOQUEDEVUELVELAMACRO?Normalmentedevuelve'c',elMISMOparmetro
queselepasparaencolar('letra'enelejemplo),pero,silacolaestLLENA,ypor
tantonosepuedeejecutarlafuncindeEncolar,sedevuelveelsmboloEOF(espero
quessepanloqueesEOF).Asqueelvalordeesaexpresin,es'c',sihayespacio
enlacola,oEOF,silacolaestllena.Cmoocurreeso?

VoyareescribirlaMacroparamejorarsulegilibilidad,alineandolosparntesisque
abren,conlosquecierran,yvoyaELIMINARloscontinuadores'\'delaMacro:

(in.n>=in.size?EOF:
(in.pt=c,*in.put++=(byte)c,
in.put=in.put>=in.limit?
in.base:in.put,
in.n++,in.pt
)
)

Ahora voy a dejar slo lo que tiene que ver con devolver 'c' o EOF. ELIMINO
temporalmente 4 lneas Internas de la Macro), y lo coloco en una lnea: ( in.n >=
in.size?EOF:(eliminado),in.n++,in.pt)

Primero,eloperadorTERNARIO:expC?expT:expF

SINOSABEQUESELOPERADORTERNARIO,USTEDNOSABEC.ESTUDIE!!!

'expC'esCUALQUIERexpresin;implicaasignaciones,Comparaciones,funciones...El'?'
PREGUNTAsi'expC'esVerdaderaoFalsa.Siesverdadera,eloperadorternarioasumeel
valor 'expT', si es falsa el valor es 'expF', siendo expT y expF, a su vez,
expresiones.Parasepararlasestelsmbolo':'Ennuestrocaso:

expC:in.n>=in.size
expT:EOF
expF:(eliminado),in.n++,in.pt

272

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Esdecir,sielnmerodecaracteresalmacenadosenlacola,esMAYOROIGUALaltamao
DEFINIDO,sedevuelveEOF.Hastaah,ok.

Pero,qudevuelve'expF'?Ques"in.n++,in.pt"?

EselCOMMAOPERATOR.NOSABEQUEES?TIENEQUEESTUDIARMUCHSIMOC.

El Comma Operator evala, de IZQUIERDA a DERECHA, todas las expresiones que estn
separadas por COMAS... Y RETORNA UN VALOR: EL DE LA *LTIMA* EXPRESIN, LA DE LA
*DERECHA*.

Enestecaso,expFejecuta(eliminado)primero,'in.n++'luegoy'in.pt'despus.

Imaginoquenolosaben,perounavariableESunaexpresin.Asque:

in.pt;

ES una SENTENCIA. (SI NO SABE LA DIFERENCIA ENTRE EXPRESIN Y SENTENCIA, "EXPRESSION


andSTATEMENT",ENINGLS,DESISTA!NOTIENELAMENORIDEADELLENGUAJEC)

UnexpressionyunstatementTIENENunvalor.Elvalorde:

in.pt;

esloqueestalmacenadoen'in.pt':eselVALORdelparmetro'c',quesealmacenen
in.ptenlalnea56:

56(in.pt=c,...

Entonces,'expF':"(eliminado),in.n++,in.pt",DEVUELVE'c'.

Asfuncionalaprimeraparte:Sinohayespacio,devuelveEOF,delocontrario,encola
laletraydevuelvesuvalor.

LaparteinternadelaMacro,queseejecutaslosihayespacio,seencargadeEncolar
elsmbolo:

...*in.put++=(byte)c,
in.put=in.put>=in.limit?
in.base:in.put,

Sealmacena'c',empleandoelpointer'put',queseautoincrementa.A'c'selehace
unCASTa(byte),porqueelusuariohapodidoenviaralgodemayorlongitud.

A continuacin (segnlo ordena el operadorCOMMA), seejecuta laexpresin que est


entrelosparntesisinternos(queNOsenecesitan:todoloqueestallesUNAsola
expresin;estnsloparamejorarlacomprensin).Repitoaqulaexpresininterna,
queesunaasignacinalapuntadorin.put,provenientedeunOPERADORTERNARIO:

in.put=in.put>=in.limit?in.base:in.put

273

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

Es decir, a in.put se le asigna un valor determinado as: si sobrepas el lmite,


in.limit,osiestapuntandoal,elvalorqueseleasignaesLABASE.Esteesel
puntoqueconvierteunVector,enunacolaCIRCULAR.Loquesignificaesque,luegode
operar el ltimo elemento del vector, el apuntador correspondiente APUNTA A LA BASE,
operacin conocida como WRAP AROUND. Si in.put no est en condicin de Wrap Around,
entoncesNOSELOMODIFICA;esdecir,suvalorfuturo,in.put,esigualasuvalorde
entrada,in.put.

ltimopunto,ylomsIMPORTANTE:ElSEMFORO:in.n,NOPUEDEestarenNINGUNAOTRA
posicindelcdigo.Enelmomentoenqueselomodifica,ahmismopuedeocurriruna
interrupcin para efectuar la operacin contraria (si est haciendo enQue, se querr
hacer un deQue). El semforo TIENE que garantizar que no importa DNDE ocurra la
interrupcin,TODOFUNCIONAALAPERFECCIN.Enelsitioendondeest,slofaltapor
devolverelvalorqueestguardadoenlavariabledeusuario'in.pt',porloquedeQue
NOalteraparanadaelestadodelacola,desdeelpuntodevistadelenQue.Observe
ms adelante lo mismo, en relacin a la Macro deQue. Para eso sirve la variable
temporalin.gtqueseusaall.

CLARO?

CtieneunasintaxisMUYcomprimida.Lossiguientessmbolos

simples:+*/%&|^!~#()_=[]{};:'",.<>?\
dobles:++**&&||##==<<>>

poseenunsignificado.(Algunostienenvarios,dependiendodelcontexto.Porejemplo,
las COMAS en las llamadas a Funciones, NO SON COMMA OPERATORS y, de hecho, su
EVALUACINesdeDERECHAAIZQUIERDA,alrevsdelOperadorComa)

SINOCONOCEELUSODEALGUNODEESOSSMBOLOS,USTEDNOSABEC,YTIENEQUEESTUDIAR
MUCHSIMO.

LamacrodeQueesparaserusadaas:c=deQue(colaRead);ydebeserahorafcilde
entender.

63#definedeQue(in)(in.n<=0?EOF:\
64(in.gt=*in.get++,\
65in.get=in.get>=in.limit?\
66in.base:in.get,\
67in.n,in.gt\
68)\
69)

Una librera GENRICA para el manejo de Colas de Datos, tendra que poder manipular
cualquiertipodevariables,incluyendolasdefinidasvaTypedefs.Peroesoestms
alldeloquepretendoensearenestetextodeARQUITECTURADELCOMPUTADOR.

62) COLAS DE DATOS: DEMOSTRACIN


Sehanmantenidolasmismasetiquetascont:yfull:,paraqueseveaelcomportamiento
equivalenteconsuequivalenteenASM:["Laboratorios\Lab3\SciComm\4quetst.asm"]

274

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

["LabsC\Lab3\SciComm\4quetst.c"]
01//******************************************************************
02//Program4QueTst.c:Test"Queue"Support(forSCI)
03//LuisGUribeCM13M2007C15A09L08J09S16J2012(HCS08)S30N2013"C"
04//See:4QueTstB.c(COMPACT)
05//Seeinthisprogram:TheuseofQue.H,defineQue,initQue,enQue
06//..anddeQue.YoumustNOTexceedthefreeRAMontheMCU...
07//
08//******************************************************************
09//IncludeFiles
10#include<hidef.h>//ForEnableInterruptsmacro
11#include"derivative.h"//Includeperipheraldeclarations

12#include"Que.h"//QUEUESupport
13//==================================================================
14//GLOBALVARIABLES.See'defQ'use...
15//defQ>>>"ALWAYS"mustbeGLOBAL<<<:Outofany'{}'

16defineQue(inQ,6);/*DEFINEQueues'inQ',6bytes&'outQ',*/
17defineQue(outQ,5);/*..5bytes.Choosethenamesyouwant...*/

18//******************************************************************
19voidmain(void)
20{bytec;
21wordcw;

22//
23//>>>ALWAYSincludethefollowing2lines
24//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
25#defineCOP_Disable0x42
26SOPT1=COP_Disable;//SystemOptions1

27//
28initQue(inQ);
29initQue(outQ);
30//
31cont:
32for(c='A';;c++){
33if(enQue(inQ,c)==EOF)//PutDebugger'sbreakpointhere
34break;//..toseecharsgoinginto'inQ'
35}
36full:
37while(1){
38cw=deQue(inQ);
39if(cw==EOF)
40break;
41if(enQue(outQ,cw)==EOF)//Willbreakherebecause...
42break;//..outQissmallerthaninQ
43}
44Wait(0);

45}

275

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

COMENTARIOS a ["Labs-C\Lab3\SciComm\4quetst.c"]:
El#include"Que.h"comocorresponde:

12#include"Que.h"//QUEUESupport

VARIABLESGLOBALES:ELdefQue,SIEMPREGLOBAL(comoenlalibreraenASM)

Paraelejemplosedefinandoscolas,inQde6bytes,youtQde5:
16defineQue(inQ,6);/*DEFINEQueues'inQ',6bytes&'outQ',*/
17defineQue(outQ,5);/*..5bytes.Choosethenamesyouwant...*/

Alcomienzodemain,ladefinicinde'c'.Enrealidadseusaunbytecyunwordcw,
comoveremosadelante.

19voidmain(void)
20{bytec;
21wordcw;

LaINICIALIZACINdelascolas:

28initQue(inQ);
29initQue(outQ);
Sehaceuncicloindefinido(forsinlmite:;;),quealmacenaletrascomenzandodesde
la'A'.Cuandolacolasellena,seterminaelfor(nosehacelacomparacinconel
tamao de la cola, para evidenciar el mecanismo que opera cuando la cola se llena).
Para la simulacin, est pendiente de colocar BREAKPOINTS en donde se indica en el
cdigo,paravisualizarloqueseestmanipulandoenlascolas:

32for(c='A';;c++){
33if(enQue(inQ,c)==EOF)//PutDebugger'sbreakpointhere
34break;//..toseecharsgoinginto'inQ'
35}

SinosabequeunbreakterminaunFOR,estMUYMALENC:ABANDONE!

AhoraqueselleninQ,sehaceuncicloindefinido,extrayendounoaunosuselementos
ytransfirindolosalaotracola.

EsexactamenteloqueharaunaRutinadeComunicaciones:EnlaISRdelRCV,seleeel
datorecibidoyseloalmacenaenlaColadeEntrada;mainencuentraquehaydatosen
esaCola,lossaca,losprocesasiesnecesarioylosalmacenaenlaColadesalida.A
lo mejor habilita las interrupciones de salida EN ALGN MOMENTO APROPIADO. Cuando la
ISRdeRCVtomaelcontrol,sacaelprximovalordelacoladesalidaylotransmite.

Enesteejemplo,elcicloterminarenlalnea42,porquelacoladesalidasellena
antesdequesevaceladeentrada,porlostamaosquedecidcolocarles.

37while(1){
38cw=deQue(inQ);
39if(cw==EOF)
40break;

276

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

41if(enQue(outQ,cw)==EOF)//Willbreakherebecause...
42break;//..outQissmallerthaninQ
43}
44Wait(0);

Para asignar el 'deQue' sobre una variable, SE NECESITA QUE LA VARIABLE SEA DE TIPO
WORD.Porqu?

Si usted estudi el getchar del 'C', tiene que poder saberlo. Si no, USTED SABE MUY
POCODEC.ESTUDIE!!!

EstaeslaraznporlacuallaMacroenQuehaceunCASTaBYTEdelvalorquesele
pasaparaencolar...

Revisesielcuerpodelwhilepuedeescribirseas:

if(enQue(outQ,deQue(inQ))==EOF)
break;

CMOFUNCIONARA?OPORQUNO?

TienequeanalizarcuandodeQuedevuelveEOF,cuandolohaceenQue,cuandonolohace
ningunoycuandolohacenlosdos.
63) CHAT POR INTERRUPCIONES, USANDO COLAS
El ltimo ejemplo es un CHAT por interrupciones, que muestra la interrelacin entre
todo: comunicaciones seriales, transmitiendo y recibiendo por interrupciones, con uso
decolas.Adems,seesquematizalaformadeprogramarseparandolomsquesepuedan,
PolticasyMecanismos,TALCOMOTIENEQUEHACERSESIEMPRE.

NooyhablarnuncadePoliticsandMechanisms?NoleensearonPROGRAMACINtampoco.

Enesteejercicioansepuedenocultarmsalgunasvariables,comokbhit;peronolo
hicepararesaltarlosparecidosconel'kbhit'queustedhadebidoestudiar.

["LabsC\Lab3\SciComm\6ChatInt.c"]
01//******************************************************************
02//Program6ChatInt.c:Send/Receivetextto/fromPC,FullInterrupt
03//LuisG.UribeC.,D15D2013

04#include"6ChatInt_.h"//includeperipheraldeclarations

05byte*Prompt="\a\r\n\n0_Envemeuntexto,porfavor<;)";

06defineQue(inQ,48);//DEFINEQue'inQ',48bytes

07//******************************************************************
08voidmain(void)/*()*/
09{/*ChatInt.c*/

277

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

10SysInit;//COP_Disable
11initQue(inQ);
12EnableIRQ;
13XmtRcvActivate;//EnableXmt&Rcv,onchipDEVICES;9600bps

14//==================================================================
15//TransmityourPrompt:Enqueatoncefull'Prompt'TableforXmt:

16SetupXmtBlk(Prompt);//TxtPtr;XmtControl=XMTMSG_S;XmtIntEn
17CpuIntEn;//<<<REMEMBER:GLOBALENABLEINTs
18RcvIntEn;//CommIntEn?{RCVSTATREG;RCVBUF;RcvIntEn;}
19Forever
20if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
21SetupXmtBlk(Prompt);
22kbhit=0;
23}
24Endforever

25Wait(0);

26}/*main()*/
27//==================================================================
28interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
29{
30kbhit=1;
31IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
32}//..Interrupt(RearmIRQInterrupts)

33//==================================================================
34interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
35{//NOTE:putcharclearsRCVRDY.bit.Veryclever...
36wordc;//MUSTbe'word'toholdbothCharsAndEOF(0xFFFF)

37switch(XmtControl){
38caseXMTMSG_S:
39if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
40XmtControl=XMTDEFAULT_S;//..(Zstrings:ASCIZ)
41}
42break;

43caseXMTDEFAULT_S:
44if((c=deQue(inQ))!=EOF){//Didsomethingarrive?
45putchar(c);//'C'Stringsendat'\0'
46}else{
47XmtIntDsb;
48}
49break;
50}
51}

52//==================================================================
53interruptVectorNumber_Vsci1rxvoidRcvISR(void)/*()*/

278

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

54{//NOTE:getcharclearsRCVRDY.bit.Veryclever...
55bytec;

56c=getchar();
57if(enQue(inQ,c)!=EOF){
58XmtIntEn;
59}
60}
["LabsC\Lab3\SciComm\6ChatInt_.h"]
01#ifndef_6CHATINT_H_INCLUDED
02#define_6CHATINT_H_INCLUDED
03//******************************************************************
04//6ChatInt_.h:Send/Receivetextto/fromPC,FullInterrupt
05//LuisG.UribeC.,D15D2013

06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations

10#include"SciComm.h"//SCIComm.Support
11#include"Que.h"//QueSupport
12#include"4InputPushButtons_.h"//Inputs4(0000b3b2b1b0)=PTA2,3;PTD2,3
13//==================================================================
14//GLOBALVARIABLES

15typedefenum{XMTDEFAULT_S,XMTMSG_S}XmtControls;

16XmtControlsXmtControl=XMTDEFAULT_S;//Maychangethistobits.

17byte*XmtPtr;//charpointerofnextdatatoXmt
18bytekbhit;

19//
20//>>>ALWAYSincludeSysInit
21//Cfr.02MC9S08QE128RM(ReferenceManual)U.pdf,pag101
22#defineCOP_Disable0x42
23#defineSysInitSOPT1=COP_Disable/*SystemOptions1*/

24//
25//EnableIRQpin
26#defineEnableIRQIRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;\
27IRQSC_IRQIE=1/*IRQpin,IntEn*/

28//
29#defineSetupXmtBlk(p)XmtPtr=(p);/*PointtoPrompt*/\
30XmtControl=XMTMSG_S;\
31XmtIntEn/*XmtISRwillsendthePrompt*/

32#endif//_6CHATINT_H_INCLUDED

["LabsC\Lab3\SciComm\4InputPushButtons_.h"]

279

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

01#ifndef_4INPUTPUSHBUTTONS_H_INCLUDED
02#define_4INPUTPUSHBUTTONS_H_INCLUDED
03//******************************************************************
04//4InputPushButtons_.h:Inputs4(0000b3b2b1b0)=PTA2,3;PTD2,3
05//LuisG.UribeC.,D15D2013

06//******************************************************************
07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations
10//==================================================================
11//DefinedFunctionality
12#defineSetup4PushBtnsPTAPE_PTAPE3=PTAPE_PTAPE2=PTDPE_PTDPE3\
13=PTDPE_PTDPE2=1/*Pullupsenable*/

14#defineget4Inputs()Inp3=PTAD_PTAD2;Inp2=PTAD_PTAD3;\
15Inp1=PTDD_PTDD2;Inp0=PTDD_PTDD3;\
16Inp4_7=~0;Inputs4=~Inputs4

17//==================================================================
18//GLOBALVARIABLES.IRQpinEnabledin"6ChatInt_.h"
19typedefunion{
20byteByte;
21struct{
22byteINPUTS40:1;//individualbitsMUSTbeUNSIGNED
23byteINPUTS41:1;
24byteINPUTS42:1;
25byteINPUTS43:1;
26bytespare:4;
27}Bits;
28}_INPUTS4;

29externvolatile_INPUTS4INPUTS4;
30#defineInputs4INPUTS4.Byte

31#defineInp0INPUTS4.Bits.INPUTS40
32#defineInp1INPUTS4.Bits.INPUTS41
33#defineInp2INPUTS4.Bits.INPUTS42
34#defineInp3INPUTS4.Bits.INPUTS43
35#defineInp4_7INPUTS4.Bits.spare

36#defineINP01U
37#defineINP12U
38#defineINP24U
39#defineINP38U

40#endif//_4INPUTPUSHBUTTONS_H_INCLUDED

COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt.c"]:
En el archivo "6ChatInt_.h" se definen cosas de bajo nivel, relacionadas con
perifricos,comoveremosabajo:

280

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

04#include"6ChatInt_.h"//includeperipheraldeclarations

ElmensajeconelquequeremosavisarlealusuariodelPCquenosenveuntexto:

05byte*Prompt="\a\r\n\n0_Envemeuntexto,porfavor<;)";

Sedefineunacola,inQ,de48posiciones:
06defineQue(inQ,48);//DEFINEQue'inQ',48bytes

08voidmain(void)/*()*/
09{/*ChatInt.c*/

Las lneas 10 a la 13 son auto explicativas con solo leerlas; dicen qu se har, NO
cmosehar(Politics;Mechanismsseenlater)

10SysInit;//COP_Disable
11initQue(inQ);
12EnableIRQ;
13XmtRcvActivate;//EnableXmt&Rcv,onchipDEVICES;9600bps

AhoraseTRANSMITEELPROMPT,queesdeltipoASCIZ,trasmitindolotododeunasola
vez,porinterrupciones:

15//TransmityourPrompt:Enqueatoncefull'Prompt'TableforXmt:
16SetupXmtBlk(Prompt);//TxtPtr;XmtControl=XMTMSG_S;XmtIntEn
17CpuIntEn;//<<<REMEMBER:GLOBALENABLEINTs

Sehabilitanlasinterrupcionesderecepcin,paraentraralcicloinfinito.kbhites
unavariablequeseactiva(1)porlaISRdelIRQ;esdecir,cadavezqueseoprimeel
botndeIRQ,setransmitedenuevoelPROMPT.ElECHOsemanejadirectamenteentrelas
ISRdeRCVyXMT:

18RcvIntEn;//CommIntEn?{RCVSTATREG;RCVBUF;RcvIntEn;}
19Forever
20if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
21SetupXmtBlk(Prompt);
22kbhit=0;
23}
24Endforever
26}/*main()*/

La IRQISR es muy simple: cargar el valor de ACTIVO para la variable kbhit, y el ACK
correspondientealIRQ:

28interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
29{
30kbhit=1;
31IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
32}//..Interrupt(RearmIRQInterrupts)

281

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

LaXmtISR:

34interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
35{//NOTE:putcharclearsRCVRDY.bit.Veryclever...
36wordc;//MUSTbe'word'toholdbothCharsAndEOF(0xFFFF)

Hace dos actividades diferentes: XMTMSG_S (el echo de lo recibido) y XMTDEFAULT_S


(transmisindelPROMPT:

ElcaseXMTMSG_S:esigualalltimoquevimos,cuandotransmitimosuntextodetipo
ASCIZ;alfinalsecambialavariabledeEstado,XmtControlasufuncindeECHO,que
eslaestndar:

37switch(XmtControl){
38caseXMTMSG_S:
39if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
40XmtControl=XMTDEFAULT_S;//..(Zstrings:ASCIZ)
41}
42break;

ElcaseXMTDEFAULT_Sestambincomoyahemosvisto:siloquesedesencola,cuandohay
una interrupcin paraTransmitir, no es EOF, quiere decir que s hay caracteres para
transmitirlealPC,yassehaceconputcharque,comoyalosabemos,haceeldebido
ACK al XMT. Si en la cola no hay nada para transmitir, se auto deshabilitan las
interrupcionesdelXMT:

43caseXMTDEFAULT_S:
44if((c=deQue(inQ))!=EOF){//Didsomethingarrive?
45putchar(c);//'C'Stringsendat'\0'
46}else{
47XmtIntDsb;
48}
49break;
50}
51}

LaRcvISResmuysencillatambin,empleandoestalibreradecomunicacionesseriales:

52//==================================================================
53interruptVectorNumber_Vsci1rxvoidRcvISR(void)/*()*/
54{//NOTE:getcharclearsRCVRDY.bit.Veryclever...
55bytec;

56c=getchar();
57if(enQue(inQ,c)!=EOF){
58XmtIntEn;
59}
60}

COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt_.h"]:
El6ChatInt_.hconstadeunapartedeinicializacin:

282

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

07//IncludeFiles
08#include<hidef.h>//forEnableInterruptsmacro
09#include"derivative.h"//includeperipheraldeclarations

10#include"SciComm.h"//SCIComm.Support
11#include"Que.h"//QueSupport
12#include"4InputPushButtons_.h"//Inputs4(0000b3b2b1b0)=PTA2,3;PTD2,3

LadefinicindelasVARIABLESGLOBALES:

15typedefenum{XMTDEFAULT_S,XMTMSG_S}XmtControls;
16XmtControlsXmtControl=XMTDEFAULT_S;//Maychangethistobits.
17byte*XmtPtr;//charpointerofnextdatatoXmt
18bytekbhit;

La definicin de la Macro que realiza la inicializacin del sistema Macro que usted
deberaUTILIZARSIEMPRE,deahoraenadelante)

20//>>>ALWAYSincludeSysInit
22#defineCOP_Disable0x42
23#defineSysInitSOPT1=COP_Disable/*SystemOptions1*/

SedefineunaMacroparahabilitarelIRQ;observequenecesitael'\'porquetienems
deunalnea

26#defineEnableIRQIRQSC=IRQSC_IRQPE_MASK|IRQSC_IRQACK_MASK;\
27IRQSC_IRQIE=1/*IRQpin,IntEn*/

SedefinelaMacroSetupXmtBlk,queinicializaytransmiteelPrompt.Recuerdequehay
una pequea mquina de estados, controlada por la variable XmtControl; aqu se
inicializaesaFSMconXMTMSG_S,quehacequelaXmtISRtransmitaelmensajeASCIZ:

29#defineSetupXmtBlk(p)XmtPtr=(p);/*PointtoPrompt*/\
30XmtControl=XMTMSG_S;\
31XmtIntEn/*XmtISRwillsendthePrompt*/

COMENTARIOS a ["Labs-C\Lab3\SciComm\4InputPushButtons_.h"]:
Definelassiguientesfuncionalidades:Setup4PushBtnsyget4Inputs().

Setup4PushBtns les activa todas las resistencias de Pull Up a los botones de entrada
(un1lasactivas).Nohayqueactivaresosterminalesparaentrada,porquedespusde
POR,todoslospinesdigitalesestnactivoscomoENTRADAS.

12#defineSetup4PushBtnsPTAPE_PTAPE3=PTAPE_PTAPE2=PTDPE_PTDPE3\
13=PTDPE_PTDPE2=1/*Pullupsenable*/

get4Inputs()LEElos4botones,unoencadabitdelavariabledefinidacomodetipo
_INPUTS4. Despus se colocan en valor inicial los 4 bits que no se usan (hay solo 4
botones)yporltimoSENIEGANLASENTRADA,tomndolasdelavariableyalmacenndolas

283

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

de nuevo all. Se niegan porque, en la forma como la gente de PE Micro conect los
botones,cadavezqueunodeellosseACTIVA,produceunCERO,locualpodraresultar
poconatural:

14#defineget4Inputs()Inp3=PTAD_PTAD2;Inp2=PTAD_PTAD3;\
15Inp1=PTDD_PTDD2;Inp0=PTDD_PTDD3;\
16Inp4_7=~0;Inputs4=~Inputs4

Seestableceunaestructuraconlos4bitsparalosbotones,yelrestosedefinecomo
'spare'.SecolocanenUNIONconunByte,parafacilitar,porejemplo,elnegarTODOS
losbitsdeungolpeInputs4=~Inputs4)

19typedefunion{
20byteByte;
21struct{
22byteINPUTS40:1;//individualbitsMUSTbeUNSIGNED
23byteINPUTS41:1;
24byteINPUTS42:1;
25byteINPUTS43:1;
26bytespare:4;
27}Bits;
28}_INPUTS4;

Se define la variable INPUTS4, de tipo _INPUTS4 (el typedef), volatile (para evitar
Optimizacin del compilador) y extern, para que sea visible desde el cdigo de los
demsarchivos:

29externvolatile_INPUTS4INPUTS4;
30#defineInputs4INPUTS4.Byte

NOSABENADADEEXTERN?UNION?NOSABEC.

Finalmente,parafacilitarelusodelosbitsdelavariableINPUTS4,detipo_INPUTS4
que,porejemplo,paradesignarelBit0requeriraescribir:INPUTS4.Bits.INPUTS40.

ConlasdefinicionescadabitesInp0,etc.Muchomssencillo

31#defineInp0INPUTS4.Bits.INPUTS40
32#defineInp1INPUTS4.Bits.INPUTS41
33#defineInp2INPUTS4.Bits.INPUTS42
34#defineInp3INPUTS4.Bits.INPUTS43
35#defineInp4_7INPUTS4.Bits.spare

64) BIG CHAT, INTERRUPCIONES, COLAS

Unverdaderochatenvamensajesdiferentesdeladoylado!Peroelsistemadebotones
del DEMOQE128 resulta algo inflexible para generar texto. Este ejercicio enva un
Prompt,igualqueelprogramaanterior,perolosmensajesnofluyensolamentedesdeel
PC,sinoquetocandocadaunodelos4botones,seenvanhastacuatromensajesalPC,
dndoleunaspectounpocomsrealistaalchat.

["LabsC\Lab3\SciComm\6ChatInt4.c"]

284

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

01//******************************************************************
02//Program6ChatInt4.c:Send/Receivetextto/fromPC,FullInterrupt
03//LuisG.UribeC.,L16D2013(4DEMOQE128textsources)

04#include"6ChatInt_.h"//includeperipheraldeclarations

05byte*Prompt="\a\r\n\n0_Envemeuntexto,porfavor<;)";
06byte*Prompts[4]={
07{"\a\r\n\n1_Meencantapoderhablarlehoy___"},
08{"\a\r\n\n2_Cmovatodo,finalizandoel13?"},
09{"\a\r\n\n3_Ledeseosuerteparaelao2014"},
10{"\a\r\n\n4_QuetengabuenanotaenArquiI!"},
11};

12defineQue(inQ,48);//DEFINEQue'inQ',48bytes

13//******************************************************************
14voidmain(void)/*()*/
15{/*ChatInt.c*/
16SysInit;//COP_Disable
17initQue(inQ);
18EnableIRQ;
19XmtRcvActivate;//EnableXmt&Rcv,onchipDEVICES;9600bps
20Setup4PushBtns;//Activate4DEMOQE128inputpushbuttons

21//==================================================================
22//TransmityourPrompt:Enqueatoncefull'Prompt'TableforXmt:
23SetupXmtBlk(Prompt);//TxtPtr;XmtControl=XMTMSG_S;XmtIntEn
24CpuIntEn;//<<<REMEMBER:GLOBALENABLEINTs
25RcvIntEn;//CommIntEn?{RCVSTATREG;RCVBUF;RcvIntEn;}

26Forever
27if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
28switch(Inputs4){//1:1;2:2;4:3;8:4
29case1:
30case2:
31break;

32case4:
33Inputs4=3;
34break;

35case8:
36Inputs4=4;
37break;

38default:
39Inputs4=15;
40break;
41}
42SetupXmtBlk(Inputs4==15?Prompt:Prompts[Inputs41]);
43kbhit=0;
44}
45Endforever

285

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

46Wait(0);
47}/*main()*/

48//==================================================================
49interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
50{
51get4Inputs();//LoadInputs4
52kbhit=1;
53IRQSC_IRQACK=1;//BSETIRQSC_IRQACK,IRQSC:ACKIRQ
54}//..Interrupt(RearmIRQInterrupts)

55//==================================================================
56interruptVectorNumber_Vsci1txvoidXmtISR(void)/*()*/
57{//NOTE:putcharclearsRCVRDY.bit.Veryclever...
58wordc;//MUSTbe'word'toholdbothCharsAndEOF(0xFFFF)

59switch(XmtControl){
60caseXMTMSG_S:
61if(!putchar(*XmtPtr++)){//'C'Stringsendat'\0'
62XmtControl=XMTDEFAULT_S;//..(Zstrings:ASCIZ)
63}
64break;

65caseXMTDEFAULT_S:
66if((c=deQue(inQ))!=EOF){//Didsomethingarrive?
67putchar(c);//'C'Stringsendat'\0'
68}else{
69XmtIntDsb;
70}
71break;
72}
73}

74//==================================================================
75interruptVectorNumber_Vsci1rxvoidRcvISR(void)/*()*/
76{//NOTE:getcharclearsRCVRDY.bit.Veryclever...
77bytec;

78c=getchar();
79if(enQue(inQ,c)!=EOF){
80XmtIntEn;
81}
82}

COMENTARIOS a ["Labs-C\Lab3\SciComm\6ChatInt-4.c"]:
Esteprogramaestanparecidoalanterior,yustedconocetantoaestasalturas,que
loscomentariossernmuybreves:

LadefinicindelPromptesidnticaalchatanterior;los4promptsestncolocadosen
unamatrizquecontiene4mensajes:

286

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

06byte*Prompts[4]={
07{"\a\r\n\n1_Meencantapoderhablarlehoy___"},
08{"\a\r\n\n2_Cmovatodo,finalizandoel13?"},
09{"\a\r\n\n3_Ledeseosuerteparaelao2014"},
10{"\a\r\n\n4_QuetengabuenanotaenArquiI!"},
11};

ImaginoqueconoceTODOSlossmbolos...Ques'\a'?
Contina todo igual, hasta enviar el Prompt. El ciclo infinito se diferencia del
anterior porque contiene un Switch con 4 Cases, uno para cada interruptor de la
tarjeta. kbhit funciona igual que antes, el programa principal lo coloca en 0, y la
IRQISRen1.

Observebienquealoprimircadainterruptorsegeneranlosnmeros1,2,4y8,pero
hemos codificado los Cases para que se generen los nmeros 0, 1, 2 y 3, que
correspondenalossubndicesqueidentificanlos4mensajesenelarreglo.Asquehay
que hay que relacionar los nmeros obtenidos con losdeseados, de la siguiente forma
(Obtenido:Generado)1:0;2:1;4:2;8:3

Pero ntese que el '0' NO CORRESPONDE a oprimir ningn botn; siempre se est
generando! As que la variable 'Inputs4', que representa los botones, tendr un Cero
SIEMPRE que no se est oprimiendo nada. Mala seleccin para el Switch, porque no
permitedistinguirentreNOseleccin,yseleccindelnmero0.

Por eso escog generar estos nmeros, en lugar de los indicados dos prrafos atrs"
(Obtenido:Generado) 1:1; 2:2; 4:3; 8:4; ahora s es fcil saber si se oprimi algn
interruptor; en caso contrario, la variable Inputs4 vale 0. Y, al usar Inputs4 como
ndice, se le resta un uno, para convertir estos valores intermedios, en los que en
realidaddeseamos.CualquiervalorNOdefinido(default)colocaun'15'enlavariable,
simulando que se oprimieron TODOS los interruptores. Si Inputs4 vale 15, seenva el
PROMPT;paralosotros4valoresposibles,selerestaununoaInputs4,yselousa
como ndice del Arreglo, para escoger uno de los mensajes, y transmitirlo empleando
'SetupXmtBlk', que como vimos antes, inicializa el sistema de transmisin y
efectivamentehacequesetransmitaelBloque,conelmensajedeseado.

26Forever
27if(kbhit){//LOCAL(DEMOQE128)IRQbuttondepressed?
28switch(Inputs4){//1:1;2:2;4:3;8:4
29case1:
30case2:
31break;

32case4:
33Inputs4=3;
34break;

35case8:
36Inputs4=4;
37break;

38default:
39Inputs4=15;
40break;

287

I N G . L U I S G . U R I B E C
COMPUTER ARCHITECTURE: THE MC9S08

41}
42SetupXmtBlk(Inputs4==15?Prompt:Prompts[Inputs41]);
43kbhit=0;
44}
45Endforever

LarutinaIRQISRescasiexactaaladelejercicioprevio;sediferenciaenqueseleen
yadecanlosinterruptores,usandolaMacroget4Inputs,yaanalizada.Elrestosigue
igual.

49interruptVectorNumber_VirqvoidIRQISR(void)/*()*/
50{
51get4Inputs();//LoadInputs4

Las dos rutinas finales, XmtISR y RcvISR son exactamente iguales a las delejercicio
anterior.
FIN DE LA OBRA

Pronto incluir ms ejercicios en Leguaje "C", como Manejo y Optimizacin de Tablas,


ImplementacindeFMSymuchosotrostemasinteresantes.

mailto:LUribe@usb.ve

288

S-ar putea să vă placă și