![]() |
||||
![]() |
||||
Making the light walk up and downRemember that sophisticated car that could talk back in the eighties? You must have seen it, because it is still re-run on several TV stations all over the world. Its name was KITT, and it had some very high-tech red lights scanning up and down in its bonnet. Well, it seemed high-tech at the time. I bet we can make something similar ourselves with nothing more than Sitcom and its standard I/O board. Half of the program is already made, because we can make the light walk from left to right. If you have conducted the experiment at the bottom of the previous page you can even make it walk from right to left. All we have to do now is to combine these two versions of the program into one version that repeats the two sequences over and over. |
|
;------------------------------------------------------------------------
;
; LESSON2C.ASM
;
; Walking up and down
;
;------------------------------------------------------------------------
.IN INIT01 Initialize the assembler
;------------------------------------------------------------------------
RELOAD LXI D,0111111111111111B Load both pattern in one go
WALKR MOV A,E Output the bit pattern to port A
OUT PORTA
MOV A,D Output the bit pattern to port B
OUT PORTB
MVI B,50 Load outer loop counter
DELAY1 MVI C,250 Load inner loop counter
DELAY2 NOP Begin of inner loop
NOP
NOP
NOP
DCR C Decrement inner loop counter
JNZ DELAY2 Repeat until loop counter = 0
DCR B Decrement outer loop counter
JNZ DELAY1 Repeat until loop counter = 0
STC Set the carry
MOV A,D Rotate pattern for port B first
RAR
MOV D,A
MOV A,E Then rotate pattern for port A
RAR
MOV E,A
JC WALKR Jump if it didn't fall out of port A
LXI D,1111111111111110B Load new pattern for both ports
WALKL MOV A,E Output the bit pattern to port A
OUT PORTA
MOV A,D Output the bit pattern to port B
OUT PORTB
MVI B,50 Load outer loop counter
DELAY3 MVI C,250 Load inner loop counter
DELAY4 NOP Begin of inner loop
NOP
NOP
NOP
DCR C Decrement inner loop counter
JNZ DELAY4 Repeat until loop counter = 0
DCR B Decrement outer loop counter
JNZ DELAY3 Repeat until loop counter = 0
STC Set the carry
MOV A,E Rotate pattern for port A first
RAL
MOV E,A
MOV A,D Then rotate pattern for port B
RAL
MOV D,A
JC WALKL Jump if it didn't fall out of port B
JMP RELOAD Otherwise reload the bit patterns
|
||
|
There's nothing much to tell about this program that you haven't already seen. Basically it is a right roll program and a left roll program concatenated to each other, with some minor alterations at the junction and outer edges.
I have introduced one new instruction in this program, LXI.
In fact LXI is the 16-bit version of MVI, and loads 2 registers with an immediate value at the same time.
Hence one LXI instruction replaces the two MVI instructions of the previous program.
Needless to say that the operand has to be 16-bit too.
If you look very carefully there is a small error in this program (don't look at the program, look at the behaviour of the LEDs).
Do you notice that the time the left most and right most LEDs are on is twice the time of the other LEDs.
Try to find out why by studying the program carefully.
|
|
It's not the real thing yet!
Although this program appears to work in a similar way as the real Kitt scanner, it is still not the real thing.
I remember that with the real Kitt scanner a total of 3 LEDs were on at the same time, walking up and down.
At each corner the direction is reversed if only one LED is left on.
|
|
;------------------------------------------------------------------------
;
; LESSON2D.ASM
;
; A Kitt scanner
;
;------------------------------------------------------------------------
.IN INIT01 Initialize the assembler
;------------------------------------------------------------------------
MVI D,00011111B Initialize pattern
MVI E,11111111B
MOV H,E
MOV L,E
WALKR MOV A,E Output the bit pattern to port A
OUT PORTA
MOV A,D Output the bit pattern to port B
OUT PORTB
MVI B,50 Load outer loop counter
DELAY1 MVI C,250 Load inner loop counter
DELAY2 NOP Begin of inner loop
NOP
NOP
NOP
DCR C Decrement inner loop counter
JNZ DELAY2 Repeat until loop counter = 0
DCR B Decrement outer loop counter
JNZ DELAY1 Repeat until loop counter = 0
MOV A,L See if we have to change direction
ANI 01000000B
JZ GOLEFT We must if b6 is a 0!
GORIGHT STC Set the carry
MOV A,H Rotate entire pattern, including
RAR the extra carry byte
MOV H,A
MOV A,D
RAR
MOV D,A
MOV A,E
RAR
MOV E,A
MOV A,L
RAR
MOV L,A
JMP WALKR Always jump back to WALKR
;------------------------------------------------------------------------
WALKL MOV A,E Output the bit pattern to port A
OUT PORTA
MOV A,D Output the bit pattern to port B
OUT PORTB
MVI B,50 Load outer loop counter
DELAY3 MVI C,250 Load inner loop counter
DELAY4 NOP Begin of inner loop
NOP
NOP
NOP
DCR C Decrement inner loop counter
JNZ DELAY4 Repeat until loop counter = 0
DCR B Decrement outer loop counter
JNZ DELAY3 Repeat until loop counter = 0
MOV A,H See if we have to change direction
ANI 000000010B
JZ GORIGHT We must if b1 is a 0!
GOLEFT STC Set the carry
MOV A,L Rotate entire pattern, including
RAL the extra carry byte
MOV L,A
MOV A,E
RAL
MOV E,A
MOV A,D
RAL
MOV D,A
MOV A,H
RAL
MOV H,A
JMP WALKL Always jump back to WALKL
|
||
|
Most of this program is a direct copy of the lesson2c.asm program, so I will restrict myself to the differences. The first difference is during initialization, where two extra bytes are initialized (in registers H and L). These two bytes will function as a multi-bit Carry. In fact each byte can hold the bits that roll out of the left and right edges of the visible part of the shift operation.
Just after the first double delay loop we find a completely changed Roll Right sequence of instructions.
First of all the right most (hidden) byte of the roll registers is copied to the Accu, where a new instruction does something with it.
This new instruction ANI will AND the value of the Accu immediately with the value following as operand.
OK, suppose we didn't change direction yet, so we are now just behind the JZ GOLEFT instruction. What comes next looks very familiar, but instead of rolling just 2 registers we now have to roll all 4. The two extra registers are the ones holding the hidden bits at either side of the light bar. After rolling all 4 bytes we can jump back to WALKR. We don't have to check if we have to change direction, because we already did. The part of the program below the division line hides no more secrets, and does basically the same for the opposite direction. |
|
|
Experiment tip: |
|
| Continue with Lesson 3 - Subroutines | |
| [Home] [Latest News] [Essentials] [Hardware] [The Build] [Programs] [Projects] [Downloads] | |||