Image Map Image Map
Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: IMSAI 8080 programming (I need help!)

  1. #1

    Default IMSAI 8080 programming (I need help!)

    I'm trying to make a simple program that loops through all of the output ports on my imsai 8080 so I can figure out which port my serial connection is located at. My question is how do I use a register to tell the out command which port I want to output to. This is an example of what I want:

    MVI B, 00
    MVI A, 55

    OUT //use B register for port # eg. B is at 00 at the beginning so output to port 00

    INR B
    JMP 00

    So what instruction should I use? Thanks for the help.

    -Oliver

  2. #2
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,464
    Blog Entries
    20

    Default

    It's a peculiarity (some would say a "deficiency") that the 8080 does not feature indirect I/O port addressing. There is a single port output instruction - OUT xx, where xx is the port number; it's encoded as D3 xx.

    Were I to write your program, it might look like this:

    Code:
        XRA  A
        LXI H,PORTNO
        MOV  M,A             ; Set initial port to 0
        MVI  A,55H           ; assuming that's what you want to output
    AGAIN:
        OUT  0
    PORTNO EQU AGAIN+1
         INR M                 ; bump the port number
         JNZ   AGAIN       ; go for the next pass until the port wraps back to 0
        ...
    This "peculiarity" comes back to bite the programmer when said programmer is trying to write a ROM monitor or other code where the I/O port numbers aren't known in advance. It's impossible to do this without executing code from RAM (i.e., create the appropriate IN or OUT instruction stored in RAM)

  3. #3

    Default

    The port 0FFH is usually the lights on the front panel ( upper left ). It seems that the lights are inverted ( BrainFade ). Light is 0 and not is 1 ??
    Easy enough to test. Out a 55 in A and write it to port 0FFH.
    So now we have a way to see a value we wrote without using a scope or halting the processor.
    Now, as Chuck noted, you can not write to a port sequential ports without using self modifying code ( at least with a 8080, the Z80 has a way ).
    If you've booted to some BIOS, there is almost always a know location we can write to that place is the stack. This assumes that that code initialized the stack pointer.
    We can move our push our self modifying code to the stack. We can see where the stack is pointed to by copying the stack pointer to a some register or we could pop our code back off the stack and modify it before pushing it back. Either way, we can then have a safe place to write our self modifying code ( mostly, I'll explain later ).
    Now, even from EPROM, we have a place to write our self modifying code ( mostly ).
    Now we can make a loop that will write to each port address and display that address. If we don't have a scope, we can use a volt meter but we'll need to add a delay so we can react to the delay and read the meter with the 0FFH port.
    Another possible ways is that your only looking at the address comparitor and don't have a port that you can observe. We can then make a tight loop there we do a number of say 10 port outputs in a row before we do check the tight loop and then say 100 of these loops before we check the time loop. It might make seen to adjust these time loops to be our 1 second delay ( problem left to the OP ).
    What if we don't have a volt meter. Hopefully we have a junk box with a LED and an appropriate resistor. We can put them, in series, from +5V, to the output of the comparitor ( being aware that there may be some tiny glitch
    as the data bit are making changes ). To know what a real hit looks like we can use the 0FFH comparitor of the front panel, as a reference.
    Now to the 'mostly' part. Some people don't like cluttering up memory space with ROM. Especially ROM or EPROM that is only use once at boot time. It would be nicer if we could remove it from the memory map and have RAM there for our larger BASIC program. We'd like to turn that piece off to recover that space, as RAM. A clever way to do that is to have a flop that when written to at a particular port disables or even can re-enable that ROM. If you stumble onto one of these locations, it can do unpredictable things. ( most sytems don't use this type of stuff but you never know ). Another possible problem is that some ports can cause DMA, like from a disk drive, and accidentally over write your program ( I have such a IMSAI setup. In fact I have no system ROM, on reset it DMAs the first sector into memory. After reset, I just start at RAM address 0 and it loads CP/M with my 100% RAM address. ).
    These are all potential I gotchas but unlikely. Still if you are stepping your program through the port and some thing kills it, you may have such a problem.

  4. #4
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,464
    Blog Entries
    20

    Default

    The problem is that with the "push" method, you still have to have SP pointing to an area of usable RAM. If you don't have RAM or you don't know where it is, you're out of luck.

  5. #5

    Default

    Well, you can write a routine that simulates the Z-80's "OUT (C), A" instruction on a RAM-less system, but you'd have to use almost 800 bytes of ROM, which is kind of ridiculous. Here's a 781-byte version. (It trashes the flags, B, HL, and SP, so all of your program state better fit in A, C, and DE.)

    Code:
    OUT_C_A:
        LXI SP, RETADDR
        LXI H, OUTS
        MVI B, 0
        DAD B
        DAD B
        DAD B
        PCHL
    RETADDR:
        DW CONTINUE
    OUTS:
        OUT 0
        RET
        OUT 1
        RET
        OUT 2
        RET
        ...
        OUT 253
        RET
        OUT 254
        RET
        OUT 255
    CONTINUE:
    -Alan

  6. #6
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,464
    Blog Entries
    20

    Default

    Well, I suppose that could be an option, but at 3*256 bytes, in 1974, that was a lot of memory (2708 was 1KB); a 1702 was only 256 bytes, so the code wouldn't fit in one.

    Some RAM is usually very desirable for implementing things such as multi-level subroutine calls. One thing I've always wondered about is why a JEDEC-pinout EPROM+RAM IC was never made, as far as I'm aware. It might have to be a multi-die chip, but that's no big deal even for 1974.
    Last edited by Chuck(G); July 11th, 2019 at 09:51 PM.

  7. #7

    Default

    It sounds like you're trying to figure out a single machine. What hardware is serving the serial output? Or is this a general problem for a monitor you are writing (as I think Chuck and Dwight are considering)?

    A program might not work if the hardware is something like the IMSAI SIO-2, since the Intel 8251's require reset, mode, and command bytes to initialize. Other cards, like the PTCO 3P+S, can be hard-wired and the port determined by inspection.

  8. #8
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,464
    Blog Entries
    20

    Default

    I have, in times past, winnowed down the list of ports by doing INs on all addresses and listing the ports that seem to be attached to something. Depending on your machine, unconnected ports might give some definite value such as 00 or FF.

  9. #9

    Default

    Thank you all for responding. My Imsai does have a z80 processor in it. I didn't realize it had another output instruction. I took a look in the z80 manual on how to use it and I can now find my serial port address.

  10. #10
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,464
    Blog Entries
    20

    Default

    Oh well, it was an interesting exercise...

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •