Author Topic: 8085 assembly question  (Read 7727 times)

0 Members and 1 Guest are viewing this topic.

Offline ChristofferBTopic starter

  • Frequent Contributor
  • **
  • Posts: 929
  • Country: dk
  • Chemistry phd student!
    • My channel:
8085 assembly question
« on: April 15, 2016, 02:46:54 pm »
Hi! So I'm in the midst of building a rack-mounted modular 8085 computer.
While I've done some assembly programming for the Z80, and a bit x86, there's still some things that aren't clear.

I want to make a small monitor program, like the turnkey altair 8800 had:
-Communicates with a terminal (or teletype) via serial
-has a few commands, like: examine memory, change memory, jump to address.
that's it.

How would you attack this task? I'm pretty green at assembly, one of the reasons I'm doing this project, but something like (very pseudocode):

-initialize UART
-display prompt (send ">" to uart)
-loop until character received (check uart flag for that)
-test if received character is equal to one of the reseved characters for examine, jump)
-if examine call examine subroutine, if jump call jump routine
examine/edit routine:
   - send "L?" to UART
   - wait for ascii byte to be received  (check uart flag for that)
   - let that be low byte of address, saved to some location in RAM

   - send "H?" to UART
   - wait for ascii byte to be received  (check uart flag for that)
   - let that be high byte of address, saved to some location +1 in RAM
 
   - send address HL, conv. to ascii to UART
   - send data at address HL, converted to ascii to UART
   - loop wait for UART input.
    if "space", increment address HL and print again
   - if a digit, save that, wait for the next, and change RAM in addr HL to new value
   - if any other key, go back to prompt

Jump routine is easier: receive 2 bytes, jmp to address and run from there.

This is grossly simplified, from an .asm point of view, just thought i'd shorten it to reasonable chunks.

Here's my main issue: Almost exactly this was achieved on the Altair turnkey monitor, in 256 bytes.

I can't see how this is doable without a binary-> ascii lookup table routine.
that'd take up half the 256 bytes.

Has anyone ever written a 8 bit monitor, or something similar? Most (x86) assembler info is either very high-level, or very low-level.

Here's the turnkey-prom monitor documentation:
http://bitsavers.trailing-edge.com/pdf/mits/8800b_Turnkey_PROM_Monitor_Aug77.pdf


Thanks in advance!

 

--Christoffer //IG:Chromatogiraffery
Check out my scientific instruments diy (GC, HPLC, NMR, etc) Channel: https://www.youtube.com/channel/UCZ8l6SdZuRuoSdze1dIpzAQ
 

Offline MrSlack

  • Frequent Contributor
  • **
  • Posts: 880
  • Country: gb
Re: 8085 assembly question
« Reply #1 on: April 15, 2016, 02:58:08 pm »
Converting binary ASCII to binary is easy without a LUT. I'm giving you it the other way round as it's more useful to think of it this way first. Pseudo code, assuming X is a byte and there are 8 binary ASCII digits.

X = 0

next: C = readchar()

If C == '0' X<<1

If C = '1' { X &= 1; X << 1; }

If not done goto next

To get it the other way it's pretty much the same in reverse. Shift, and, test, print 8 times depending on flags (remember the zero flag after a compare/test)

Clearly define all your routines and calling conventions I.e what registers are used where and when and you can get that in 256 bytes easy. 8085 has segments if I remember which is a bit of a dick and slightly more verbose.

If in doubt steal C's standard library - in assembly it's tiny :)
« Last Edit: April 15, 2016, 03:00:17 pm by MrSlack »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9891
  • Country: us
Re: 8085 assembly question
« Reply #2 on: April 15, 2016, 03:31:34 pm »
Great project!  A simple monitor was the first bit of code I wrote for any 8085 project and I did several.  Mine would fit in a 1kB EEPROM.

Here is a rather complete monitor:  https://github.com/jefftranter/8080/tree/master/asm/monitor

I would look through the code for ideas and possibly delete some of the stuff that doesn't apply.  Or, leave it alone...  It apparently takes more the 1kB because he places it 2k down from the end of memory which, in the listing, is just 24k.  I assume he enters the monitor with the console switches because the CPU will always start at 0x0000h.

What to do about that?  Well, the common way was to bank the RAM and the EPROM such that at reset, the EEPROM occupied address 0x0000h and RAM didn't respond to CE (chip enable).  The EPROM would have a jump instruction to the actual address in high memory for the next instruction which would immediately map the EPROM out of low memory and map the RAM in (just diddling around with the CE signals).

You really don't want to have to start the machine with toggle switches to 0xFC00 (assuming a 1k monitor) so banking is the way to get around it.

These days, you can buy a 32kx8 RAM chip (maybe even a 64kx8) so I imagine you will build your own memory setup.  Just work through the banking issue.  It's pretty simple.  You don't even need an IO port.  You can use part of the address and the RD signal to change the banking flip-flop when a high address is first read.  The flip-flop is reset at startup and set when the first high address instruction is read.  It stays set forever (until the board is reset).

If you implement something like CP/M 2.2 then you have to do a similar thing to get the first JMP COLDSTART to work.  Then, instead of a monitor, you place the BIOS code in high RAM.

 

Offline ChristofferBTopic starter

  • Frequent Contributor
  • **
  • Posts: 929
  • Country: dk
  • Chemistry phd student!
    • My channel:
Re: 8085 assembly question
« Reply #3 on: April 15, 2016, 04:06:43 pm »
Quote
X = 0

next: C = readchar()

If C == '0' X<<1

If C = '1' { X &= 1; X << 1; }

If not done goto next

So in a byte, for every zero element, you do nothing, and for every one element, you AND the element with 1? I'll have to try that in BASIC to visualize it, but great to know there's a mathematical way of doing it! thanks a bunch!
The 8085 is not segmented, that's the 8086/8088 and newer. One of my reasons for choosing the 8085.

Quote
Great project!  A simple monitor was the first bit of code I wrote for any 8085 project and I did several.  Mine would fit in a 1kB EEPROM.

Here is a rather complete monitor:  https://github.com/jefftranter/8080/tree/master/asm/monitor

Great! I'll dig through that and use what I can!
I'm planning on a rather small memory at first, 4K ram/8K rom, but then expandable to the full 64K.

Banking might be a good idea, or just edit the jumps and memory transfers to get around it? If you don't NEED to start ram at 0000H (CP/M does need that.)

--Christoffer //IG:Chromatogiraffery
Check out my scientific instruments diy (GC, HPLC, NMR, etc) Channel: https://www.youtube.com/channel/UCZ8l6SdZuRuoSdze1dIpzAQ
 

Offline obiwanjacobi

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: 8085 assembly question
« Reply #4 on: April 15, 2016, 04:21:24 pm »
I am currently writing one in C but I am planning on doing one in Z80 assembly as well.
My system has a Z80 as a CPU but it also has a PSoC-5 as a System Controller. There is no ROM so at startup the system controller resets the Z80 until it is released by a command (over serial). This monitor in C is inside the PSoC.

I have chosen to wait for a new-line before I dispatch the command. The received bytes are stored in a ring buffer until the new line is received. Then a command parser will parse the first characters until a space is encountered. That string is searched in a lookup table and converted into a command Id. There is a command structure that gets filled with the text and the command id and dispatched to specific command handler functions (switch). Each function can optionally parse additional parameters from the received characters and perform some sort of operation. There is access to the console for generating output.

I have commands to manipulate the RAM (DMA), fill, read and write. Memory-write allows you to send a file (as binary) and that will be put into the RAM at the specified address.
I also have some commands to change the clock frequency for the Z80 that are managed by the system controller. And finally a command to take the Z80 out of reset and let it run.

Another way of organizing this could be to build a state machine that reads one character at a time from the serial input and go to the next state on each recognized character. At one point a complete operation is spelled out and additional states can be added for its parameters. Care must be taken with optional parameters. This could probably be very short code but might not be so clear to read (back)...
Arduino Template Library | Zalt Z80 Computer
Wrong code should not compile!
 

Offline ChristofferBTopic starter

  • Frequent Contributor
  • **
  • Posts: 929
  • Country: dk
  • Chemistry phd student!
    • My channel:
Re: 8085 assembly question
« Reply #5 on: April 15, 2016, 04:27:53 pm »
Sounds like a cool project!

Quote
Another way of organizing this could be to build a state machine that reads one character at a time from the serial input and go to the next state on each recognized character. At one point a complete operation is spelled out and additional states can be added for its parameters. Care must be taken with optional parameters. This could probably be very short code but might not be so clear to read (back)...

See that's what I thought, but I'd hoped there might exist a more straightforward/easily-readable method.

--Christoffer //IG:Chromatogiraffery
Check out my scientific instruments diy (GC, HPLC, NMR, etc) Channel: https://www.youtube.com/channel/UCZ8l6SdZuRuoSdze1dIpzAQ
 

Offline MrSlack

  • Frequent Contributor
  • **
  • Posts: 880
  • Country: gb
Re: 8085 assembly question
« Reply #6 on: April 15, 2016, 04:34:03 pm »
Look at FORTH and its execution model as well. That is tiny enough to embed an interpreter in that 256 bytes with possibly enough compressed threaded code to be an interpreter for a monitor.
 
The following users thanked this post: newbrain

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1684
  • Country: us
Re: 8085 assembly question
« Reply #7 on: April 15, 2016, 04:35:41 pm »
Hi! So I'm in the midst of building a rack-mounted modular 8085 computer.
While I've done some assembly programming for the Z80, and a bit x86, there's still some things that aren't clear.

As I'm sure you're aware, the 8085 instruction set is a subset of the Z80 set. The Z80 mnemonics are different, and it has bit manipulation, block move, and byte search instructions, and IX/IY index registers the 8085 doesn't have, but otherwise if you've done Z80 assembly programming you shouldn't find it hard to adapt to the 8085.
Complexity is the number-one enemy of high-quality code.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4205
  • Country: us
Re: 8085 assembly question
« Reply #8 on: April 15, 2016, 04:38:14 pm »
Quote
I can't see how this is doable without a binary-> ascii lookup table routine.
that'd take up half the 256 bytes.
There were some clever code snippets on 8080/etc for converting ascii->number->ascii using the BCD math instructions (AAA and etc)
This turns up after a brief search:
Quote
Code: [Select]
    add  a,90h
    daa
    adc  a,40h
    daa
It ends converting the lower 4 bits of A register into the ASCII values '0', '1', ... '9', 'A', 'B', ..., 'F'.  In other words, a binary to hexadecimal converter.
 

Offline obiwanjacobi

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: 8085 assembly question
« Reply #9 on: April 15, 2016, 05:05:06 pm »
See end of the page, starts at main_loop

http://www.vaxman.de/projects/tiny_z80/

Arduino Template Library | Zalt Z80 Computer
Wrong code should not compile!
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4205
  • Country: us
Re: 8085 assembly question
« Reply #10 on: April 15, 2016, 05:39:46 pm »
BTW, I'd recommend reading in an entire line of text (with editing) rather than having immediate response to each character.
Quote
e xxxx
d xxxx hh hh hh ...
j xxxx
I don't think that the editing will end up using much more space than your intermediate prompts...
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9891
  • Country: us
Re: 8085 assembly question
« Reply #11 on: April 16, 2016, 01:49:32 am »
Quote
X = 0

next: C = readchar()

If C == '0' X<<1

If C = '1' { X &= 1; X << 1; }

If not done goto next

So in a byte, for every zero element, you do nothing, and for every one element, you AND the element with 1? I'll have to try that in BASIC to visualize it, but great to know there's a mathematical way of doing it! thanks a bunch!
The 8085 is not segmented, that's the 8086/8088 and newer. One of my reasons for choosing the 8085.

Quote
Great project!  A simple monitor was the first bit of code I wrote for any 8085 project and I did several.  Mine would fit in a 1kB EEPROM.

Here is a rather complete monitor:  https://github.com/jefftranter/8080/tree/master/asm/monitor

Great! I'll dig through that and use what I can!
I'm planning on a rather small memory at first, 4K ram/8K rom, but then expandable to the full 64K.

Banking might be a good idea, or just edit the jumps and memory transfers to get around it? If you don't NEED to start ram at 0000H (CP/M does need that.)

Sure, you can put a small bit of EPROM at 0x0000 as long as you don't plan to run CP/M.  There's no reason not too.
Once you start messing around with the memory address, it's pretty easy to map whatever you want wherever you want to put it.  Some 8080 projects had multiple 64k banks with a common 1 or 2k at the top.  I haven't done that myself but I could see putting CP/M BIOS up high in shared RAM and banking several user pages in lower memory.  It just never came up.

A few years back, I bought a Zilog eZ180 board and I built a daughter card that holds a compact flash device and a couple of FTDI serial->USB chips.  CP/M rips when it runs at 50 MHz!  I implemented 16 drives of 8 MB each.  That's a TON of disk space for CP/M kinds of things!
 

Offline Rasz

  • Super Contributor
  • ***
  • Posts: 2616
  • Country: 00
    • My random blog.
Re: 8085 assembly question
« Reply #12 on: April 16, 2016, 01:58:10 am »
Who logs in to gdm? Not I, said the duck.
My fireplace is on fire, but in all the wrong places.
 

Online ebastler

  • Super Contributor
  • ***
  • Posts: 6526
  • Country: de
Re: 8085 assembly question
« Reply #13 on: April 16, 2016, 04:37:33 am »
BTW, I'd recommend reading in an entire line of text (with editing) rather than having immediate response to each character.
I don't think that the editing will end up using much more space than your intermediate prompts...

Another clear vote for reading an entire line first (with at least simple "backspace" editing). Interpret the line once it has been terminated by the "return" key. Much more user-friendly because it allows you to correct the occasional typo!
 

Offline ChristofferBTopic starter

  • Frequent Contributor
  • **
  • Posts: 929
  • Country: dk
  • Chemistry phd student!
    • My channel:
Re: 8085 assembly question
« Reply #14 on: April 16, 2016, 12:55:42 pm »
Handling an entire line of text seems smarter in most respects, That's the plan, then.
But doesn't that make the recognition of commands more difficult? you'd still need to match them character for character.
But again, if I make every command one letter, it won't be a problem.

--Christoffer //IG:Chromatogiraffery
Check out my scientific instruments diy (GC, HPLC, NMR, etc) Channel: https://www.youtube.com/channel/UCZ8l6SdZuRuoSdze1dIpzAQ
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4205
  • Country: us
Re: 8085 assembly question
« Reply #15 on: April 17, 2016, 12:52:13 am »
Quote
doesn't that make the recognition of commands more difficult? you'd still need to match them character for character.
Nah.  For equal commands, it means fetching a character from a buffer, vs fetching it from a uart.  Equal complexity.

Quote
I want to make a small monitor program, like the turnkey altair 8800 had:
  :
Here's my main issue: Almost exactly this was achieved on the Altair turnkey monitor, in 256 bytes.
I don't think it's realistic to expect to be able to write a 256byte monitor without a lot of experience.

http://www.autometer.de/unix4fun/z80pack/ftp/altair/turnmon.prn  (heh.  Octal like a 8080 should be!)
 

Offline ChristofferBTopic starter

  • Frequent Contributor
  • **
  • Posts: 929
  • Country: dk
  • Chemistry phd student!
    • My channel:
Re: 8085 assembly question
« Reply #16 on: April 17, 2016, 01:53:44 pm »
I don't think so either. It doesn't matter too much, sizewise. I'm not limited to 1702 eproms, thank god.

Actually, I've begun modifying the altair 8800 turnkey monitor. It seems that the ascii to actual value becomes easier with octal, too. It's also a good base to add more commands to - and the 8080 code runs fine on a 8085.
If I can edit the memory ranges, IO ports etc. I should even be able to run most altair software, like 4/8K basic and altair dos.

I've also decided to make an actual turnkey card for my computer, featuring both a serial port and a 8K eprom (so much for my quest for a small program, but I have a giant stock of 2764's).
Here's the schematic, if anyone's interested:

edit: added updates schematic

« Last Edit: April 20, 2016, 04:41:37 pm by ChristofferB »
--Christoffer //IG:Chromatogiraffery
Check out my scientific instruments diy (GC, HPLC, NMR, etc) Channel: https://www.youtube.com/channel/UCZ8l6SdZuRuoSdze1dIpzAQ
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1721
  • Country: se
Re: 8085 assembly question
« Reply #17 on: April 18, 2016, 07:00:47 pm »
Look at FORTH and its execution model as well. That is tiny enough to embed an interpreter in that 256 bytes with possibly enough compressed threaded code to be an interpreter for a monitor.

Yes :-+
Go Forth!
I also wrote quite many monitors for 6502, 68HC11  and the like (still have a 6809 that I'll sooner or later build a board for(th)...), but then I discovered the simpleness and beauty of this underdog language.
An ANS forth can be written in a very limited space, and if you use one of the classic implementations (direct or indirect threaded) you can write only the very core routines in assembler and most of the rest directly in forth (when it's working, you can optimize...).
The language is easy to learn (especially if you had a real HP as first calculator ;)) blazing fast for an interpreted, interactive, one, and powerful enough to write real programs.
At the same time it's very close to metal and easily replaces a monitor.
There's still plenty of resources on the net, including the standard and many implementation to learn from (but don't look at gforth to start, it's definitely good but quite complex).

Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9891
  • Country: us
Re: 8085 assembly question
« Reply #18 on: April 18, 2016, 09:08:18 pm »
Look at FORTH and its execution model as well. That is tiny enough to embed an interpreter in that 256 bytes with possibly enough compressed threaded code to be an interpreter for a monitor.

Yes :-+
Go Forth!
I also wrote quite many monitors for 6502, 68HC11  and the like (still have a 6809 that I'll sooner or later build a board for(th)...), but then I discovered the simpleness and beauty of this underdog language.


MANY years ago (probably around '80), I was writing code to hang hard drives on just about anything.  One day I visited the controller manufacturer and they showed me their test setup.  It was all built around Forth because the bottom up design of the code allowed them to easily write any kind of high level test they wanted based on that lower level code that was already known to work.  I thought it was a pretty clever solution!
 

Offline MrSlack

  • Frequent Contributor
  • **
  • Posts: 880
  • Country: gb
Re: 8085 assembly question
« Reply #19 on: April 19, 2016, 08:27:51 am »
There is a canned 8085 FORTH here: http://www.strangegizmo.com/products/mforth/source/

Worth a read. Let me know if you have any questions: I've built a couple of SBCs and FORTHs in the dark ages on Z80 and 68k.

Also worth reading "The Computer Journal" which is a publication issued from 1983-1998 about small usually homebrew computers: https://archive.org/details/the-computer-journal

The canonical series of articles on FORTH implementation on small systems and how they all work is here too: http://www.bradrodriguez.com/papers/ (see Moving Forth series)
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4205
  • Country: us
Re: 8085 assembly question
« Reply #20 on: April 19, 2016, 09:57:01 am »
Quote
The canonical series of articles on FORTH implementation on small systems and how they all work is here too: http://www.bradrodriguez.com/papers/ (see Moving Forth series)
Quote
You can expect the usual 16-bit Forth kernel (see below) to occupy about 8K bytes of program space. For a full kernel that can compile Forth definitions, you should allow a minimum of 1K byte of RAM.
That's a little depressing :-(  Since we started out talking about 256byte monitors...
(Most Forth implementations are likely to include a much more complete set of Forth words than are truly necessary for either a pure monitor, or a forth implementation that can compile the rest of the needed words.  http://amforth.sourceforge.net/ is nicely broken into little pieces, and looks like it will run in as little as 2k (on Atmel AVR8), but ... I find the documentation especially confusing :-( )
 

Offline MrSlack

  • Frequent Contributor
  • **
  • Posts: 880
  • Country: gb
Re: 8085 assembly question
« Reply #21 on: April 19, 2016, 10:11:58 am »
512 bytes is enough :)

Your monitor wouldn't have a FORTH compiler built in, just the runtime as a chunk of DW's at the end. You don't need much RAM for that. Probably 256 bytes. The core FORTH assembly can be crammed in under 256 bytes on Z80.  It's basically NEXT, a few small assembly routines for IO, configuring the SIO, stack manipulation and arithmetic. You can then of course decide to either use this to bootstrap more FORTH words or use it to run something else which is the marvelous thing about FORTH: extensibility.

A few months down the line: hey guys, it's running a full object system.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4205
  • Country: us
Re: 8085 assembly question
« Reply #22 on: April 19, 2016, 10:39:40 am »
Quote
Your monitor wouldn't have a FORTH compiler built in
   :
You can then of course decide to either use this to bootstrap more FORTH words
You have to have enough to interpret/compile new words (I'd call that a compiler, but that's probably not quite right), or you can't do the easy "bootstrap more words."  (I guess you could add them as a binary blob, but that would be cheating.)  And of course it would be helpful if you already had enough of the standard words that you didn't have to define them first...  I don't think 512bytes would be enough.

It is unfortunate (?) that microcontrollers and microcomputers have opposite memory dynamics.  Microcontrollers have lots of Flash/ROM but not much RAM, so the tendency is to put a "big" Forth in ROM.  The 8080 in the OP probably has "lots" of RAM but less flash, making the "add words as you need them" option more attractive.  ("amforth" actually burns new words in flash, but I don't think it makes any efforts to optimize that for the limited write-cycles that are allowed.)
 

Offline MrSlack

  • Frequent Contributor
  • **
  • Posts: 880
  • Country: gb
Re: 8085 assembly question
« Reply #23 on: April 19, 2016, 10:49:36 am »
You don't need the compiler or interpreter side of things to run FORTH code. That's entirely optional believe it or not. You can use assembly macros to just call the native functions using direct threading. That's how you bootstrap a FORTH:

Code: [Select]
sqr:   dw dup   ; points to stack dup
       dw times ; points to stack times
       jmp next ; call NEXT

SQR in 16 bit direct threaded tends to land at about 9 bytes. Not bad.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4205
  • Country: us
Re: 8085 assembly question
« Reply #24 on: April 19, 2016, 11:00:04 am »
Yes, I understand that.  But didn't you imply that the 512byte forth was going to be able to add words to itself?  Or were you just proposing that additional words be added to the source (via assembly macros, as you say), reassembled, and reloaded (into ever bigger PROM)as time went on?  (until it reached the point where it COULD add words to itself...)

Does Forth normally include a way to add binary blobs to the dictionary?  I didn't think so, but I don't see why it would be impossible, either.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf