This is a example problem in my book. Assuming pin 5 of port 4 is connected to an amplifier that drives a loudspeaker, the solution is given as,
The frequency of middle C is $$f=261.63\ \text{Hz}$$
So, the time period is,
$$T=\frac1{f}=3822\ \mu s$$
The program to produce a square wave with that period is,
LOOP1: OUT 4H ;Send bit to speaker
MVI C,86H ;Set count to 134
LOOP2: DCR C ;Count down
JNZ LOOP2 ;Test count
CMA ;Reset bit 5
NOP ;Fine tune
NOP ;Fine tune
JMP LOOP1 ;Go for next half cycle
The number of T states is given as, OUT(10), MVI(7), DCR(4), JNZ(10 if true, else 7), CMA(4), NOP(4), JMP(10).
With a clock frequency of 1 MHz, LOOP2(for half cycles) runs for 1912 microseconds, which is close enough. LOOP1 should run again sending the complement of what was previously in bit 5 of port 4. But I think it doesn't.
When LOOP2 ends, the accumulator has 00H left over from C register. CMA changes the accumulator to FFH. NOP and JMP don't change the accumulator. So then the LOOP1 iterates for the next half cycle, OUT sents accumulator contents to port 4, i.e, FFH whose bit 5 is 1, everytime. So there is not a square wave, it's just a high signal. Then how does it produce a middle C?
Best Answer
DCR C
decrements the C register and sets flags; it does not affect the accumulator (aka A register). The only instruction in this sequence which affects the accumulator is theCMA
. Thus on each pass throughLOOP1
, the accumulator will be complemented - bit 5 high on one cycle and low on the next.Many sources including the 8085 datasheet describe the 8080/8085 ALU as operating directly on the accumulator, but this is an oversimplification. As described in this Ken Shirriff article, the ALU has two temporary registers:
For the
DCR
instructions, the ACT holds a constant, the TMP receives the current contents of the operand register, and anADD
operation is performed; forDCR C
, the accumulator remains untouched:There is only a single set of flags in the 8080;
DCR
affects the Zero, Sign, Parity, and Aux-carry flags.