w
Lesson 2
Before we continue with lesson 2 I would like to introduce a nifty little feature of most assemblers to you.
From now on I'm going to use an include file to initialize Sitcom.
|
;------------------------------------------------------------------------ ; ; INIT01.ASM ; ; Initialise experiments with the basic I/O board ; ;------------------------------------------------------------------------ .CR 8085 The processor we're using .CP 1,9600,N,8,1 SITCOM is connected to COM1 .TF COM1:,INT Send generated code to COM1 ;------------------------------------------------------------------------ ; ; Constants declarations ; ;------------------------------------------------------------------------ PORTA .EQ 000H Port A on the 8255 PORTB .EQ 001H Port B on the 8255 PORTC .EQ 002H Port C on the 8255 CONTROL .EQ 003H Control register of the 8255 ;------------------------------------------------------------------------ ; ; Initialize the 8255 ; ;------------------------------------------------------------------------ START MVI A,10001001B Select outputs for Ports A and B OUT CONTROL of the 8255, Port C are inputs |
Enter the program above in a separate file and call it INIT01.ASM.
From now on we can enter all the code of this program by adding just one single line to our programs using the .IN directive.
|
.IN INIT01 Initialize the assembler |
That is all we need to do from now on to get started with a new program. This serves some interesting purposes:
But remember: The processor never will know the difference between this approach, and the previous ones. The generated code will be exactly the same in both ways. It goes without saying that the INIT01.ASM should reside in the same directory as the main source file, otherwise you'll have to specify the include file's path too. |
Chasing LEDsLet's make a program that shows 2 LEDs chasing each other, from left to right. This is easy enough, and it only involves just one new instruction, which is called RRC.
Here is what the RRC instruction does:
It rotates all bits in the Accu from left (MSB) to right (LSB), hence the name Rotate Right.
Thus bit 7 is copied to bit 6, bit 6 is copied to bit 5, ...... bit 1 is copied to bit 0, and finally bit 0 is copied to bit 7 again.
At the same time bit 0 (the one that falls out of the byte) is copied to the Carry flag.
We'll discuss the Carry flag later in this lesson.
Here is the program that does the trick: |
;------------------------------------------------------------------------ ; ; LESSON2A.ASM ; ; Chasing LEDs ; ;------------------------------------------------------------------------ .IN INIT01 Initialize the assembler ;------------------------------------------------------------------------ ; ; Running around in circles ; ;------------------------------------------------------------------------ MVI A,11111110B Load the accumulator with bit pattern CHASE OUT PORTA Output the bit pattern to port A OUT PORTB Output the bit pattern to port B 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 RRC Rotate Accu right JMP CHASE Repeat for ever |
Now, if I tell you that the opposite instruction of RRC is called RLC (Rotate Left), you may figure out yourself how to make the LEDs run the other way. You may even add some more LEDs chasing each other by changing only one value in the program above. |
A lonely LEDSo, making the LEDs chase each other is easy enough. Making one LED wander from left to right past all 16 LEDs is a bit more difficult. Let me explain why:
|
;------------------------------------------------------------------------ ; ; LESSON2B.ASM ; ; A lonely light walking from left to right across all 16 LEDs ; ;------------------------------------------------------------------------ .IN INIT01 Initialize the assembler ;------------------------------------------------------------------------ RELOAD MVI D,01111111B Load pattern for port B (left half) MVI E,11111111B Load pattern for port A (right half) WALK 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 WALK Jump if it didn't fall out of port A JMP RELOAD Otherwise reload the bit patterns |
We start at label RELOAD, where we load the two initial patterns for ports B and A into the registers D and E. There are several ways to store intermediate results, but to avoid too many new things to happen in one program I decided to use two extra internal registers of the 8085. We are going to use the registers B and C again for our delay loop, so we can't use those. Registers D and E will serve our purpose well.
On the line with label WALK we see a new instruction.
The MOV instruction moves a value from one register to another.
In fact it doesn't move the value, it simply makes a copy of it in the other register.
The first register in the operand field is the destination register, while the second operand is the source register.
Then we see our familiar delay loop, creating a delay of about 125 milli seconds.
Before I'm going to explain the next 7 instructions I'm going to introduce the Carry flag to you.
We have seen, without knowing it, one of the flags in the flag register in action.
It was the Zero flag (have a glance at the software dashboard of lesson 1 if you forgot about the flag register).
The Zero flag will be set when the result of the previous math instruction was 0, and the Zero flag will be cleared if the result was not zero.
We used the instruction JNZ in the delay loops to test whether the Zero flag was set or not.
In this case we only jump if the Zero flag was NOT set.
BTW: The JZ instruction would jump if the Zero flag IS set, which means the result of the previous math instruction was 0.
And now for the instructions that actually make the LEDs walk.
First of all the Carry is set with the STC instruction (SeT Carry).
I will explain why in a moment.
It differs only a little with the RRC instruction.
The bit that falls out of the byte is only copied to the Carry flag, while the Carry flag is copied to bit 7.
As a matter fact with the RAR instruction the bits roll "through" the Carry, whereas the RRC instruction lets the bits roll inside the byte.
You may consider RAR to be a 9-bit roll, while RRC is an 8-bit roll.
Now the light can walk all across the LEDs of port A too.
But what if it falls out of port A eventually?
|
Experiment tip: |
Continue Lesson 2 - Moving up and down |
[Home] [Latest News] [Essentials] [Hardware] [The Build] [Programs] [Projects] [Downloads] | |||