8085 SOD Light a LED Assembly Language Code Question

Thread Starter

keiichicom

Joined Apr 26, 2022
38
Hi,

When I load this code into ROM and execute it on my 8085 based computer, it works fine. The LED connected to the SOD (serial output) lights and goes out:

SOD BLINK A LED:
START:
   MVI A,C0 ; light the LED
   SIM
 
MVI B,FF ; load the delay count into the B register

DELAY:  
       DCR B
       JNZ DELAY
       MVI A,40 ; turn off the LED and Halt
       SIM
       HLT
If I replace the HLT command with a JMP START command, the LED stays lit continuously instead of blinking. Is this an issue of the delay not being long enough? The clock of the 8085 is from a 6MHz quartz crystal. The 8085 divides the clock freq. by 2 so the clock output is 3MHz.

I even also tried two delays in a row and tried different articles with a delay count less than this (the articles claim that the LED blinks) but the LED still stays lit continuously.

Thanks in Advance
 
Last edited:

MrChips

Joined Oct 2, 2009
27,695
Yes. The delay times are two short.
You need delay times longer than 20ms which you cannot achieve with multiple delays in a row.
You need nested delays, i.e. one delay loop inside another delay loop.

You can do some rough ballpark estimates.
Assuming one loop takes 4μs, 256 loops will take about 1ms.
If you do this in an outer loop 256 times, it would give you a delay of about 250ms which you would be able to observe.

Having accomplished this, you can then work backwards.
Use a stopwatch and measure the time it takes to run 10 flashes. Now see if you can calculate the execution time of one loop.
 

JohnInTX

Joined Jun 26, 2012
4,709
Here are some delay routines from an old 8085 project. It used a 3.939 MHz crystal (.508uS cycle time) so you will have to adjust the DELAY routine accordingly to make the times work out as labeled. Note how one low level delay is 'multiplied' by calling it from the various loops.
8085 Delays:
; For 3.937 MHz XTAL, .508us Tcyc.  Cycle times in [].  MSEC = MILLISECONDS
***********
          ;                 ACCUMULATOR SETTINGS: 1 MSEC= 75, 2 MSEC= 151, 3 MSEC= 226.
DELAY     DCR     A                      [4] TIME= [(USEC)/.508)-7]/26
          NOP                        
          NOP
          NOP
          JNZ     DELAY                  [10] JMP, [7] FALL THRU.
          RET                            [10]
          ;
***********
          ;
QSEC      MVI     D,255                  DELAY 1/4 SEC.
          JMP     MSEC
          ;
***********
          ;
SEC       MVI     A,1                    DELAY 1 SEC.
SECS      RLC                            DELAY A'S SECONDS.
          RLC
          MOV     B,A
SECLOP    MVI     D,255
          CALL    MSEC
          DCR     B
          JNZ     SECLOP
          RET                            RET Z
          ;
***********
          ;
MILSEC    MVI     D,1                    DELAY 1 MILLISECOND
          ;
MSEC      MVI     A,75                   [7] DELAY D'S MSECS APPROX.
          CALL    DELAY                  [18]
          DCR     D                      [4]
          JNZ     MSEC                   [10] LOOP, [7] FALL THRU.
          RET                            [10]
          ;
If you have a timer chip it would be better to make an interrupt driven delay subsystem rather than the long-duration blocking code shown here but it will get you started as well as eventually provide an eventual lesson on why blocking delays are generally a bad idea. Suitable parts would include the 8155 and 8253.
If you don't have it, here's the complete MCS-85 Family User's Manual with descriptions of all of that.
Good luck!
 

Attachments

Last edited:

Thread Starter

keiichicom

Joined Apr 26, 2022
38
Thanks MrChips and John, I had done something similar and tested it in a simulator.

8085 Blink an LED connected to the 8085 SOD Pin:
// Blink the LED connected to the 8085 SOD pin
START:

   MVI A,C0 // turn on the LED
   SIM
   MVI B,FF     // for ~ 1 sec total delay in delay1
   CALL DELAY1; // do a ~1 second delay
   MVI A,40 // turn off the LED
   SIM
   JMP START // Loop

DELAY1:

   DCR B
   MVI C,D6    // for ~ 1ms delay in delay2
   CALL DELAY2
   MVI C,D6
   CALL DELAY2
   MVI C,D6
   CALL DELAY2
   MVI C,D6
   CALL DELAY2
   JNZ DELAY1
   RET

DELAY2:

    DCR C
    JNZ DELAY2
    RET
I think I have another issue. If I leave the 8085's TRAP interrupt floading, the led lights and goes off randomly (presumably, from random interrupts) but If I connect the TRAP pin with a 4.7k resistor in series to ground, I still get a continuous lit LED and not a blinking one. I do have timer chips and i/o port chips which I will eventually use and a UART chip, but for now I want to test the SOD port, since I want to eventually bit bang it for a serial monitor in order to do something simple for now. Thanks, I have downloaded the manual.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,709
IIRC, the 8085 has LSTTL compatible inputs. That means that you need a load to sink .4ma at .8V max to pull a '0'. 4700 ohms won't do that. Check and see what the '0' voltage on TRAP is to ensure you are safely below the VIL threshold. If you aren't using TRAP yet, I'd strap it to ground. If you do use TRAP you have to have a service routine located at 24h. At the very least, put a NOP + RETURN instruction there. My guess is that TRAP is close to the '1' threshold and you are getting spurious, non-maskable interrupts that cause your code to go to 24h with no service routine to handle it. KABOOM o_O

The circuitry driving TRAP needs to be stable and issue a clean interrupt signal. Since TRAP is non-maskable, a TRAP interrupt service can be interrupted again and again before the service routine completes if there is noise on the TRAP input. That will cause problems. I originally used TRAP to early-sense power failures but sometimes the power disconnect was so ratty that it TRAPPED multiple times and crashed the code. I eventually used one of the RST inputs and disabled that interrupt upon entry to ensure the thing got to the end of the power fail routines.

Let us know what you are thinking about the monitor. I may have an old monitor/debug module that uses SID/SOD and UART too.

If you want to roll your own UART, use the accumulator to hold the character to be transmitted. Start with ASCII 'U' (55h- alternates 0-1 on SOD) then you can measure your bit times directly with a scope and tune your delays. After that, use that TX routine as a model for the RX routine. The bit time settings should be very close. Finally, hook them together and make an echo routine to test it all up. You can show the RX bit sample points by toggling a signal on SOD when you sample the bit. The edge transitions on SOD should be in the center of each of the bits of 'U' that SID is reading bit for bit. Once you have the RX timings down, replace the SOD output code with NOPs or whatever uses the same amount of time. Once you can TX and RX at your desired baud rate your troubles are over!
That's how it was done way back when.

Good luck!
 
Last edited:

Thread Starter

keiichicom

Joined Apr 26, 2022
38
Hi John,

Thanks for all the serial monitor advice it will be needed. I have tried the circuit with trap tied to ground, but the same behaviour was observed, I can't see to get the LED to blink continuously. Measuring SOD output with a scope does not give any oscillations just a constant voltage. However, I have wrote code to have the SOD LED blink once and turn off and this works fine. I have also put a service routine for the trap when I did use it, but strangely, it didn't execute when I use the trap push button, using Saundby's MAG-85 Interrupts tutorial: MAG-85 Construction: Adding a Hardware Interrupt (saundby.com) .

p.s. I will give up soon and just use a 8251 USART instead. I have spent way to much time on SID/SOD serial communications to no avail.
 

JohnInTX

Joined Jun 26, 2012
4,709
I will give up soon and just use a 8251 USART instead.
Good idea.

Keep in mind that as a rule, simulators don't identify hardware issues very well, or at all. If code is working on the sim but not on the hardware it is a good idea to resolve that issue before continuing. It only gets more involved. Be sure you have an adequate power supply that is well decoupled close to the 8085 chip. Be sure your RESET/ signal is clean and long enough to fully reset the chip. The 8085 will run erratically without that.

Be SURE that the voltage swings on SOD are solid logic levels and not overloaded by the LED. I don't recall specifically about SOD but some of the peripheral devices in the MCS85 family suffered read-modify-write issues.

If you want, post the current code and a schematic and we can look at it further.

Have fun!
 

Thread Starter

keiichicom

Joined Apr 26, 2022
38
Thanks, And here is my "messy" schematic, using 8085AH-2 cpu: I have checked that the reset function is working properly and I have a good stable 5v power supply. In the articles I have seen nobody seems to use a transistor to drive the LED from the SOD pin (they do from 8255 output port, however). diagram errors/omissions: 74573 pin 11 is connected to 8085 ale pin 30. 74573 pin 1 is connected to ground. Current CODE is same as what I posted above.
24012023105159.jpg
 
Last edited:

MrChips

Joined Oct 2, 2009
27,695
In general, I find that it is important to resolve simple problems because it will come back to haunt you.

It usually means that you are overlooking something that is trivial but vitally important.
 

JohnInTX

Joined Jun 26, 2012
4,709
There is no RAM. Where is the stack?
I should have caught it before but you need RAM and you must initialize the stack pointer to that RAM before you can use CALL or interrupts. An 8155 would be a suitable choice and provide I/O and a timer, too.
I would use a driver on the LED or at least turn it around to sink current.
 
Last edited:

Thread Starter

keiichicom

Joined Apr 26, 2022
38
There is no RAM. Where is the stack?
I should have caught it before but you need RAM and you must initialize the stack pointer to that RAM before you can use CALL or interrupts. An 8155 would be a suitable choice and provide I/O and a timer, too.
I would use a driver on the LED or at least turn it around to sink current.
Hi John,

For now , I naively thought that I could just put a program at 0000h and run it from rom.
Then I will first try to change my program to not use CALL.

I see what you mean, the stack pointer needs to keep track of the memory addresses to return to. For simplicity, Next, I will just replace the rom with a always powered on 62256 32k x 8 ram for my testing. They are 100% pin compatible with the 28c256 and you can even load programs onto them with the same arduino circuit and code(minus the disable software data protection code) as for the 28c256 32k x 8 rom (I have tested this and it works):) ).

I will turn the led around and connect the +ve end with a current limiting resistor to 5v if that is what you mean.

Thanks.
 
Last edited:

Thread Starter

keiichicom

Joined Apr 26, 2022
38
I am still using a 28c256 rom with the led turned around and code with no CALLS and I had checked the code in the Jubin Mitra's Simulator and it works fine. In the real circuit I got the same results but the led is brighter and doing a reset sometimes makes the led flicker and then go solid. At this point I will start from scratch and go step by step again and probably this time have both rom and ram. No oscillations on SOD pin when checked with scope but address pins, data pins and clock output all show oscillations like they should.

Code:
// Blink the LED connected to the 8085 SOD pin

START:       MVI A,40    // turn on the LED (sod to -ve lead this time)
       SIM
       MVI B,FF    // for ~ 1 sec total delay

DELAY1:       MVI C,D6    // for ~ 1ms delay in delay1
       DCR C
       JNZ DELAY1

DELAY2:       MVI C,D6    // for ~ 1ms delay in delay2
       DCR C
       JNZ DELAY2

DELAY3:       MVI C,D6    // for ~ 1ms delay in delay3
       DCR C
       JNZ DELAY3

DELAY4:       MVI C,D6    // for ~ 1ms delay in delay4
       DCR C
       JNZ DELAY4
       DCR B
       JNZ DELAY1
       MVI A,C0    // turn off the LED (sod to -ve lead this time)
       SIM
       JMP START
 
Last edited:

Thread Starter

keiichicom

Joined Apr 26, 2022
38
Hi Mr. Chips, no its like this: the 4 C register countdowns get done B register value times, so the C register loops are nested within the B register loop. I tested this in the simulator with smaller counts and it worked. Anyways, I will be starting from scratch and will be doing something different.
 
Top