[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

F-Report



Here is a copy of the file I gave Joyce on the nice glowing orange
disk.  This is mostly just sent here for Cindy's benefit.

There are no changes (ie. absolutely none, nada, zero changes) between
here and what I gave you (Joyce) on the disk.

The phrase "modus operandi" should be changed to, say, "mode of
operation", or some-such.  One of the reports in Malone's office used
the same phrase "modus operandi" in almost exactly the same place and
almost exactly the same way.  I feel so non-original.


[Beginning of file: no further content to email]

Notes to Joyce:

Things you may be tempted to change but about which before you change, you
should consider that you don't have my consent:
	- the word "priorized" to "prioritized"
	- the phrase "modus operandi"
	- any short sentence into a longer sentence
	- the removal of more than one or two repeated nouns
	- the words "skeleton" and "skeletal" to any
	  inferior choice of words.  There are superior choices, but I
	  haven't thought of them.  Changes to inferior choices do not
	  have my consent.
	- Feel free to edit the "Suggestions" section, but
	  please try to avoid changing its content.  Malone loves
	  ridiculously impossible improvements: he wanted a certain
	  millibot group to use parallel processing 6502s and he
	  wanted pancake groups to build a continuous feed pancake
	  maker that operated from raw ingredients (ie. not a pancake
	  mix).  Besides, I don't believe that the suggested
	  improvements are too far out, anyways.

	- In general, I haven't had a chance to read either
	  your stuff or Cindy's stuff.  I don't know what level of
	  overlap exists.  I know that some of this stuff is probably
	  too wordy  or overlaps other stuff (depending on Cindy)
	- and I proof-read my own stuff while I was very
	  much tired and not too awake
	- Therefore:
		You otherwise have a very broad editorial license

This doesn't include the acceptance of criteria section.  I
only just saw the description of that section on the aer2000
webpage.  It'll take me a little while to dig-up quantitive
numbers for some things, so I'll email that section to you
later (soon).

Any questions, phone (anytime), or drop an email with the
phrase URGENT in the subject.  I will be setting my email to be collected
once every 20 minutes or so.

I'll notify you by email as soon as I've placed a tif image
file into the shared directory.  I need to clear-out a
little diskspace first.  Should be done soon.

Division of the Problem

	Correct subdivision of a problem is always an essential
element of any team's solution to the problem.  For Zeta's
development, three separate subsystems were identified and a
team member was assigned to each.  The subsystems were named the
electro-mechanical subsystem, the interface subsystem, and
the intelligence subsystem.
	The electro-mechanical subsystem comprises the physical skeleton
of Zeta.  The team member assigned to this subsystem was responsible
for Zeta's physical functions and for ensuring that all circuit boards
and wiring would be securely attached to Zeta and protected from damage.
	The interface subsystem includes all of Zeta's
electronic components, with the exception of her computer
board.  The team member assigned to this subsystem was
responsible for building IR sensors to let Zeta "see" her
opponents, building opto-encoders to let Zeta modulate her
speed, and building any circuitry necessary to control the
motors and to control the IR sensors.  (XXX It sounds a
little strange to talk about "controlling sensors".  I'm
referring, of course, to the relay switch board here, but I
can't really think of a better phrase at the moment.)
	The intelligence subsystem is the computer board
used by Zeta and all of the code used to run the computer.
The team member assigned to this subsystem was
responsible for processing all sensor input and providing
any necessary control signals to the interface subsystem.
	Choosing these subdivisions of the problem allowed
each team member to begin work on their subsystem
immediately without being forced to wait for the completion
of other subsystems.  Team members only needed to specialize
in fields related to their subsystem and were not forced to
learn about, for example, gear ratios or opamps, unless their
subsystem required that knowledge.  These two points were
important for maximizing development speed.

Integration

	The order of Zeta's integration proceeded in the
same order that her individual components were finished.  If
a problem with a given component was found during
integration, then fixing that component was priorized over
the completion of other components.  This modus operandi
allowed integration to proceed as quickly as possible.
	Integration of Zeta began with the motors and the
motor control circuit.  The schematic for the first motor
control circuit is shown in figure X.X (XXX).  This circuit
was found to have a large voltage drop between the voltage
source for the motors and the actual motors.  The voltage
drop was considered to be unacceptably large and the circuit
was replaced with the one shown in figure X.X (XXX).  (XXX
can we quantify this voltage drop?)
	The motors were then tested with the circuit while using pulse
width modulation (PWM) (XXX - symbols & abbreviations, expand first
occurrence) control.  Duty cycles of the PWM were varied and qualitatively
compared using the motor.c test program found in the appendix (XXX).
The motors were found to reset the computer too often; this problem was
solved by increasing the size of the two large capacitors over the motor
leads.  It was also found that the Zener diodes used to prevent large
voltage spikes from the motors were often damaged.  This was originally
thought to be due to accidentally connecting the motor leads incorrectly.
After further study, it was found that the voltage spikes from the motors
under PWM were simply too large for the Zener diodes and the problem
was solved by using larger Zener diodes.  A further problem where the computer
was reset due to a large spark inside the relay switches of the circuit
in figure X.X (XXX) was solved by ensuring the motors were completely
turned off before toggling the relay.
(XXX last sentence doesn't flow well)
	The drive system as a whole---motors, pulleys, and
computer---were then tested on the skeleton of Zeta to
ensure that they could provide sufficient power for
locomotion.  At this time the system was deemed
satisfactory.  Much later as Zeta's weight increased, it
became obvious that they could not provide sufficient power.
Different combinations of pulleys, both plastic and metal,
and belts, both rubber and metal-spring, were tried.  No
solution not requiring major reconstruction of Zeta's
skeletal base was ever found.
	The opto-encoders used by the computer to control the speed
of the wheels were integrated next.  The main Qubit program with
the bumper and IR sensor sections disabled was used for testing.
It was found to be difficult to control the speed of the unloaded
wheels.  More complex control algorithms, similar to fuzzy logic
(XXX reference to website??) were tried without success.  It was
eventually realized that although it was very difficult to control
wheelspeed when no load was applied to a wheel, only a simple
faster/slower algorithm was necessary to control wheelspeed
when real inertia was supplied to a wheel.
	Integration continued with the bumper sensors.  It was
found that the switches used for the bumper sensors were
difficult to attach to the robot for physical reasons.
Once the switches were replaced, and the bumper code in
Qubit enabled, the bumpers functioned correctly.
	The IR sensors were the last component to be integrated.
Noise that had not been noticeable when output was to an LED
(light-emitting-diode - XXX acronym, expand first
occurrence, add to section on abbreviations)
became much more noticeable when output was to the computer.
This noise was eventually eliminated through the careful use
of only new 9V batteries --- batteries providing less than
9.5V were discarded immediately.  The find_tau.c program (see
appendix XXX) was used to determine how much time the amp/filter
circuit required to reset itself when its input was changed
from one sensor to the next.  The initial reset time of 100ms
to 200ms was considered to be too long and the time was
decreased to a consistent 18ms by changing the resistor labeled
XXX in the circuit XXX.  The find_tau.c program was also found
to be useful for diagnosing general sensor problems: if a
given sensor took longer than 18ms to reset, it was usually
due to a bad battery.  This is how the 9.5V threshold was
chosen.  When the IR sensors were used by the Qubit program
with the motors running, rather than just test code with the
motors turned off, it was found that noise generated by the
motors caused the sensors to return false positives.  This
was solved by turning the motors off and testing the sensors
once every 3.5 seconds.
	After the IR sensors were working correctly,
integration was complete.  Unfortunately Zeta still suffered
from locomotion problems that plagued her at different times
during integration.  This problem was not succesfully
solved.


Suggestions for Improvements

	Some projects reach the point where further
improvement is neither possible nor even desirable.  Other
projects can be continually improved, if the time and effort
is found.  Tag robots belong to the latter category.
	There is considerable room for improvement in each
of the three subsystems.  The IR sensors should be made less
susceptible to motor noise, the computer should track the
location of walls and avoid running into them, and the drive
system should provide more torque to the drive wheels.
	Less incremental and more radical improvements to
Zeta are also possible.  The rules of the tag competition
state that dropped objects are permitted.  There is
tremendous untapped potential for tag robot improvement in
this area.
	Dropped objects can be used to emit IR (XXX - acronym -
infra-red, expand first instance and add to abbreviations
section) designed to interfere with the opposing robot.  Zeta
would need to be able to distinguish the dropped decoy emittor
from the emittor mounted on top of the opposing robot.  This
could be done by adding another level of modulation to the
decoy emittor.  At the upper level of complexity, multiple dropped
decoys could be remotely controlled by Zeta via radio
signals.  The decoys could be turned on and off in such a
manner that not only would the opposing robot be confused,
but it would actually be lead along a string of beacons to a
location chosen by Zeta, thus preventing the opposing robot
from tagging or evading Zeta due to random movement caused
by its confusion.
	One of Zeta's opposing robots used ultra-sonic
sensors instead of IR sensors.  The above scheme would not
interfere with ultra-sonic sensors.  However, the ultrasonic
sensors are only effective if nobody else is using them.  By
mouting Zeta with a ultrasonic emittor that emits fast-paced
chirps, the robot using ultrasonic sensors would be
completely confused.
	If Zeta is improved to interfere with the sensors of
opposing robots, it must be assumed that opposing robots will
be similarly improved.  It is difficult to neutralize an
opposing robot if that opposing robot is also using dropped
decoys as just described.  Ideally Zeta would be outfitted with a secondary
sensor system of some sort.  Unfortunately, ultrasound is very
easy to interfere with, and there are very few other possible
sensor systems.  The next best alternative is to make use of
dropped sensors to provide additional sets of "eyes" for Zeta.
Each of the dropped sensors would have an intentionally short
range.  They would use radio communication to report information
back to Zeta.  Zeta would track the location of each detected
IR signal.  When the opposing robot is in persue mode, it will
be forced to change its location to find Zeta and this will
distinguish it from decoys dropped by the opposition.  If the
opposing robot is in evade mode, it does not need to change
its location.  Zeta would have a more difficult time distinguishing
the opposition robot's dropped beacons from the real opposition
robot in this case.
	The next stage of developement would be to use
dropped objects that are mobile.  When in evade mode, Zeta
could back herself into a corner and drop objects that would
form themselves into a wall protecting her.
	The first challenge that would be faced in
implementing any of these suggestions would be finding a mechanical
mechanism for dropping objects.  As the
improvements become more advanced, the complexity shifts
towards electronic circuitry and then towards the computer
algorithms.  These suggestions would, however, turn Zeta
into a very formidable tag player.

[XXX I don't think my verb tenses are all quite consistent
in the above couple of paragraphs].


Standard Operating Procedure

	The procedure for operating the robot was developed during
integration and is a reaction to common problems.  The steps
reccomended by the Zeta development team to power-on Zeta are listed
in table XXX and the power-off steps are listed in table XXX.  If
in step IV, the "Qubit" eprom is chosen, no special tools are
necessary to power-on Zeta unless the operator attempts to
trouble-shoot problems.  If the "monitor" eprom is chosen, a computer
capable of hosting the 6502 monitor will be needed.


Table XXX:  The power on sequence.

[XXX In many cases these could (should) be shortened
drastically to a single sentence or so, plus an all-important
reference that says "See diagram XXXX"]

[XXX The format used here is Roman Numeral for a step number
that must be taken, and Arabic numerals for steps to be
taken if a problem occurs in the associated Roman Numeral
step.  I would like to see this in a two-column table
format, Roman-numeral text in the left column, and then
Arabic-numeral text in the right column.  No numerals should
be necessary once it is in tabular form.  It's important
that Malone be able to skip reading the longer stuff (namely
the trouble-shooting part) and read just the step-by-step
instructions.]

[XXX Most of this could be removed, and in fact, all of the
trouble-shooting portion could be removed.  It may actually
be better to limit this to a simple "Plug in batteries and
turn the On/Off switch on" statement.  I'm not sure.]

[XXX I think that we should remove the parts that explain
how to operate the robot using the monitor eprom.  I've left
them in for the moment, since it's easier to remove them
than it is to rewrite them, but I tend to think that they
should be removed].


I.  Ensure that all power supplies are disconnected.

II.  Check that both wheels turn smoothly and do not contact
the opto-encoders (see diagram XXXXXXXX).

    If the wheels do not turn smoothly past the opto-encoders,

	1.  It may be necessary to adjust the position of
the opto-encoders on their velcro pads.

	2.  It may be necessary to realign the drive wheel.
Remove the wheel and carefully remount the wheel tightening
each nut correctly.

III.  Connect the computer power supply.  See diagram XXX.

IV.  Examine the computer to ensure that either the eprom
labelled "monitor" or the eprom labelled "Qubit" is being
used, as desired.  If the "monitor" eprom is being used, a computer
capable of running the host console program as well as
compiled copies of the binaries will be needed.

[XXX The above paragraph is an example of why I think we
should really remove from here any information that explains
how to use the monitor eprom.  It makes the whole section
longer and more unwieldy.  The more I think about it, the
more I am in favour of removing steps that explain how to
use the "monitor" eprom.]

    a) If the "Qubit" computer eprom is being used, then turn
the "On/Off" switch to the "On" position.  Within 5 seconds,
the computer should make audible beeping sounds.

    b) If the "Monitor" computer eprom is being used,
connect the computer to a host console and check that the
monitor frequency is present.

    If the computer does not appear operational, 

	1.  Check current flow from the computer power supply.  If there
is no current, then the power supply connections have become
damaged.

	2.  Check that the computer eprom is correctly
inserted.

	3.  Check that computer voltage supply is 8V or
better.

V.  Connect the battery clips labelled "impact sensors" (XXX - actually,
I think it was labelled "touch sensors") and "motors" to the identically
labelled battery packs.  See diagram XXX.

VI.  If the eprom labelled "monitor" is being used, observe
Port B on VIA #2 (address 0x8000) with the console program.
Press each of the touch sensors in succession and check compare
with the pinout in diagram XXX.

If the eprom labelled "Qubit" is being used, check that for
each impact sensor, a distinct buzzing sound is produced
when the sensor is pressed.
Check that this distinct sound is not produced when no
sensor is pressed (that is, check that no sensor is stuck
on).

	1.  If the impact sensors do not turn on, check
their power supply.

	2.  If several (but not all) impact sensors are
always turned on, check that the wires connecting to the
impact switches have not come loose.

VII.  If the eprom labelled "monitor" is being used,
observe Port A on VIA #1 (address 0xa001) with the console
program.  Turn the left and right wheels and check that bits
#7 and #6, respectively, change as the wheels are turned.

If the eprom labelled "Qubit" is being used, it will be
easier to infer the presence of damaged
opto-encoders from Zeta's movement at a later step.

    If an opto-encoder does not operate correctly,

	1.  Check that power is being delivered to the
connector marked "power" on the opto-encoder circuit board
(see diagram XXX).

	2.  Check that the connector marked "comp" on the
opto-encoder circuit board is connected to the yellow wire
labelled either "Right opto-encoder" or "Left opto-encoder"
(XXX - actually, they were numbered #1 and #2).  Follow this
wire until it connects to the db9 labelled "Drive System"
(XXX - actually, these wires were so tangled it was mostly
impossible to follow them).

	3.  Check that the plastic case on the opto-switch
has not been pulled or mangled by the encoder wheel.  If
necessary, press the plastic case back into its position: it
should click into place.

VIII.  Connect 9V batteries to each of the IR sensors.
Connect the IR battery clips labelled +12V and -12V.
Connect the battery in the beacon.

If the eprom labelled "Qubit" is being used, the sequence of
beeps emitted by the computer should change when the beacon
is exposed to the sensors.

If the eprom labelled "monitor" is being used, run the find_tau.c
program.  Download the "data" array from find_tau and compare with
table XXX.  Also write the value 0x01 to address 0x8001 and observe
bit #4 at address 0xa000 to ensure that it is low normally and high
when the beacon is exposed to sensor #1.

	1.  If a sensor's reset time is too low but is not
zero, the sensors are probably not connected correctly.
Major robot disassembly is required.

	2.  If sensor reset time for sensor #1 is zero,
rerun the find_tau program.

	3.  If a sensor's reset time is zero, the "amp/filter"
circuit board may not functioning correctly.  Check that all labelled
connectors are attached to correspondingly labelled wires.

	4.  If a sensor's reset time is too high, change the
battery supplying the questionable sensor with a battery
supplying 9.5V or better.

IX.  If using the "monitor" eprom, upload and run the Qubit program.

X.  Ensure the "On/Off" switch is set to "Off" and that the
"Persue/Evade" switch is set to the desired position.

XI.  Connect one of the large SLA (XXX - acronym, expand
first instance, add to acronyms section) batteries as in
diagram XXX.

XII.  Set the "On/Off" switch to "On".

    If only one of two motors turn on,

	1.  Try replacing relay switches on the motor
control circuit (see diagram XXX).

	2.  Check that opto-encoders are functioning
correctly.

    If only one of the two drive wheels turns,

	3.  Check that the stationary wheel has a correctly
attached and that a pulley is firmly attached to the motor
shaft.

    If neither motor turns on,

	4.  If the "monitor" eprom is being used, disconnect the
motor battery and check that the Qubit program was correctly uploaded.

	5.  With the motor battery disconnected and Qubit
running, check the resistance between the two motor battery
leads connected to the motor control circuit.  The
resistance should be about 2.5 Ohms.

XIII.  Zeta should now be operational and should follow or
evade the beacon (XXX - Um...  I'm not really sure what to
say here...).


Table XXX: The power off sequence

I.  Set the "On/Off" switch to the "off" position.  If Zeta
is going to be powered-on after a short period of time, this
is the only step necessary.  If she is going to be
powered-off for an extended period, the following step is
also needed.

II.  Disconnect all batteries in the following order (see
Diagram XXX XXX This diagram is pretty important):

	1.  Motor power supply battery
	2.  Battery pack labelled "motors"
	3.  Battery pack labelled "relays"
	4.  Battery packs labelled "IR sensors - +12V" and
	    "IR sensors - -12V"
	5.  Eight 9V batteries powering the IR sensors
	6.  Battery packs labelled "relays" and "impact sensors"
	7.  Battery pack labelled "computer"


Table XXX

Sample Copy of Correct value in "data" array for find_tau.c

hexadecimal
address
relative
to start
of "data"
array		hexadecimal byte values at each address

00000000	cc 01 00 01 cc 00 00 00  12 cc 02 00 02 cc 00 00
00000010  	00 12 cc 04 00 04 cc 00  00 00 21 cc 08 00 08 cc
00000020  	00 00 00 12 cc 10 00 10  cc 00 00 00 12 cc 20 00
00000030  	20 cc 00 00 00 12 cc 40  00 40 cc 00 00 00 12 cc
00000040  	80 00 80 cc 00 00 00 11 

The "data" array in find_tau shows the reset time of the
amp/filter circuit for each sensor.  The reset time for a
given sensor can be found from the "data" array using the
following table:

sensor #	relative address at which the reset time is stored
1		0x08
2		0x11
3		0x1a
4		0x23
5		0x2c
6		0x35
7		0x3e
8		0x47

The reset times for sensors #1, 2, 4, 5, 6, 7, and 8 should
be between 0x11 and 0x13 milliseconds.  The reset time for
sensor #3 should be between 0x19 and 0x21 milliseconds.



Intelligence Subsystem

Assessment of the Problem

	A tag robot can be made to function at the simplest
level of moving towards a beacon or moving away from a beacon
--- persue and evade, respectively.  However, as any human
who has ever played tag knows, choosing the optimal path in
which to run, in both the persue and evade cases, is an
extraordinarily complex problem.  The requirements for the
intelligence subsystem were that it be able to control the
motors and read that sensors, Zeta's feet and eyes, but also
that it be imbued with the minimal intelligence to persue
and evade a beacon, and almost as importantly, the ability
to have this intelligence expanded and improved in future
versions or prototypes.
	







For the appendix:

XXX This source code should be pretty-printed using
enscript.  If I forget to include PostScript versions of
this stuff that are pretty-printed, please PLEASE remind me,
since plain-text code looks pretty ugly.  If you can't print
PostScript on your computer, you should have no trouble
finding a print shop that will print PostScript for you,
since PostScript is (used to be) fairly standard for that
kind of stuff.

XXX Okay, the files motor.c.ps and find_tau.c.ps should be
included on the disk I'm giving you, now...

XXX Note that all computer programs can be found in their
full RCS glory and history on Tim's labdisk, or, better, at
http://people.FreeBSD.org/~hoek/aer201/comp/whatever.

XXX appendix entry #1

XXX Also found at http://people.FreeBSD.org/~hoek/aer201/comp/test/motor.c
XXX but with full RCS history.  Should be referenced or
    mentioned, if possible.

The motor.c test program:

/*
 * motor.c
 *
 * Routine to output PWM with different duty cycles and periods.  Useful,
 * for example, to send test pulses to motors.
 *
 * Input PA0 high for shorter delay
 *           low for longer delay
 * Input PA1 high -- change on cycle
 *           low  -- change off cycle
 * Input PA2 and PA3 simultaneously low to cause a change (either up or
 *  down, according to PA0) in the delays.  After one change of delay,
 *  both PA2 and PA3 must be brought high again before another change of
 *  delay can occur.
 *
 * Output PA7 to motor on/off switch.
 *
 * t.vanderhoek, 2000
 *
 */

#include <aer6502.h>

void
main (void)
{
	static char n1 = 10;  /* Desired on cycle length */
	static char f1 = 40;  /* Desired off cycle length */
	static char acceptinput = 1;
	static char c1, c2;

	VIA1_DDRA = 0x80;

	while (1) {
		for (c1=0; c1 < f1; c1++)
			for (c2=0; c2 < 50; ++c2) 
				; /* do nothing */

		/* Turn motor on */
		BITON (Port1A, 7);

		for (c1=0; c1 < n1; c1++)
			for (c2=0; c2 < 50; ++c2)
				; /* do nothing */

		/* Turn motor off */
		BITOFF (Port1A, 7);

		/* Check input bits */
		if (acceptinput && !BITVAL (Port1A, 2) && !BITVAL (Port1A, 3)) {
			if (BITVAL (Port1A, 0)) {
				/* Shorten delay */
				if (BITVAL (Port1A, 1)) {
					/* Shorten on cycle */
					if (n1 != 0)
						n1 -= 10;
				} else {
					/* Shorten off cycle */
					if (f1 != 0)
						f1 -= 10;
				}
			} else {
				/* Lengthen delay */
				if (BITVAL (Port1A, 1)) {
					/* Lengthen on cycle */
					if (n1 != 250)
						n1 += 10;
				} else {
					/* Lengthen off cycle */
					if (f1 != 250)
						f1 += 10;
				}
			}
			acceptinput = 0;
		} else {
			if (BITVAL (Port1A, 2) && BITVAL (Port1A, 3))
				acceptinput = 1;
		}
	}
}




XXX appendix entry #2


XXX Also found at http://people.FreeBSD.org/~hoek/aer201/comp/test/find_tau.c
XXX but with full RCS history.  Should be referenced or
    mentioned, if possible.

The find_tau.c test program,

/*
 * find_tau.c
 *
 * Measure the time required for the sensor circuit to properly reset.
 */

#include <aer6502.h>

void handle(void);

char data[72];
int index;

unsigned int mscount;

char n, i, j, ms;

void
main (void)
{
	VIA2_DDRA = 0xff;
	VIA1_DDRB |= 0x20;

	irq_handler = handle;

        VIA1_ACR &= 0x3f;
        VIA1_ACR |= 0x40;

	/* interrupts 1ms apart */
        VIA1_T1L_L = 0xe8;
        VIA1_T1C_H = 0x03;

        VIA1_IER = 0xc0;

	asm("cli");

	while (index < sizeof(data)) {
		for (n=1; n; n <<= 1) {
			/*
			 * The following pattern signifies the current
			 * sensor number, where the ?? is replaced by
			 * the byte being sent to the relay board.
			 *
			 * 0xcc 0x?? 0x00 0x?? 0xcc
			 *
			 * Use of this pattern is a relic of an older revision.
			 */
			data[index] = 0xcc;
			++index;
			data[index] = n;
			++index;
			data[index] = 0x00;
			++index;
			data[index] = n;
			++index;
			data[index] = 0xcc;
			++index;

			/* Empty space --- a relic from an older revision */
			index += 2;

			Port2A = n;

			mscount = 0;
			do {
				ms = 0;
				while (!ms) ;
				if (! (Port1B & 0x10)) {
					goto bbreak;
				}
				++mscount;
				if (mscount == 1000) {
					goto bbreak;
				}
			} while (1) ;
bbreak:
			data[index] = mscount >> 8;
			++index;
			data[index] = (char) mscount;
			++index;
		}
	}

	asm("cli");

	/*
	 * Make the buzzer buzz, thus signifying to the user that the
	 * program has finished.
	 */
        while (1) {
                for (i = 0; i < 75; ++i) ;
                Port1B ^= 0x20;
        }
}

/*
 * Interrupt handler
 */
void
handle (void)
{
	asm("inc _ms");
	asm("lda #$40");
	asm("sta _VIA1_IFR");
}



-- 
Signature withheld by request of author.