6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 4:36 pm

All times are UTC




Post new topic Reply to topic  [ 163 posts ]  Go to page 1, 2, 3, 4, 5 ... 11  Next
Author Message
PostPosted: Sun Sep 20, 2020 3:39 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Elsewhere there have been some thread-drifty discussions about the relative strengths and weaknesses of the 8-bit CPUs of the mid-70s. The 8080 and 6800 were launched in 1974, the 6502 arrived in 1975, and the Z80 arrived in 1976. The 6809 arrived in 1978. There are a few others, and I welcome discussions for them as well, as long as they came from the 1970s. This excludes children of the 1980s, like the 65c02/802, the 6309, the 8051, the AVRs, and the 68HC stuff, but includes lesser-known processors like the 1802 and Z8, among others.

What experiences and insights can you share regarding these 8-bitters, regarding performance, code density and ease of composing assembly language programs? I'll start with a few personal experiences that may be a bit subjective, but which I can at least attempt to defend as impartial:

1) Microsoft Level II BASIC with 32-bit floats on the TRS-80 Model 1 with a 1.77 MHz Z80 was notably slower than Applesoft BASIC with 40-bit floats on the 1.0 MHz 6502 Apple ][+, although Level II admittedly had some generic features not present in Applesoft (like ELSE and USING).

2) VTL-2 on the 6800 comes in at slightly under 768 bytes for the entire IDE binary, and the comparably-equipped 6502 version is at least 200 bytes larger. At equivalent clock speeds the 6502 version executes notably more quickly than the 6800, however (this may be partly due to the fact that I am better at optimizing 6502 code than 6800 code).

3) Composing 6502 assembly code gives me a warm cozy feeling. It just fits really well into my creative processes. 6800 and 6809, not as much. 8080 and Z80 assembly languages give me a headache after a short time.

4) In the hands of an expert, I am of the opinion that the Z80 has the best machine code density of the bunch, but I can't back that up with much in the way of credible evidence.

I consider myself to be a decent 6800 programmer and a very good 6502 programmer. The others, well ... I can at least recognize and follow their source code, but that's about all I'm willing to boast.

Focusing only on the 8-bitters of the 1970s, what experiences can you share? There will obviously be a forum bias here, but I know I'm not the only multi-lingual participant, and I'm interested in the opinions of others, especially any objective evidence you can provide (subjective evidence is okay too).

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 5:39 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
barrym95838 wrote:
Focusing only on the 8-bitters of the 1970s, what experiences can you share? There will obviously be a forum bias here, but I know I'm not the only multi-lingual participant, and I'm interested in the opinions of others, especially any objective evidence you can provide (subjective evidence is okay too).

Do microcontrollers count?

I started using PIC16 microcontrollers in 1996 for work.  (Although they're Microchip's thing now, PIC16 got its start in 1975 I believe, at General Instrument.)  I used it because they could be programmed on the workbench, they were available in so many versions, from lots of stocking distributors, the development software was free, and some variations even have complete onboard fixed-frequency clock oscillators.  The processor portion is the only thing about them that's terrible for me having come from 65xx land.  I have a post showing how much more efficient the 6502 is at various things at viewtopic.php?p=4997#p4997 .

For a product I developed in 1993, the National COP800 was a line of microcontrollers I considered.  (Unfortunately I don't have an introduction date for you.)  I don't remember anything about them anymore.  The reason we did not use them was that National basically told us we were too little for them to be interested in selling to us or working with us.  For that project, I landed on a 68HC11 variant, but then found out the auto industry had them all locked up on allocation, meaning they claimed every one that was to be made some time into the future and we wouldn't be able to get any.  Remember this was before microcontrollers were ubiquitous.  Development software was never free, and further complicating things was that the microcontrollers were usually mask-programmed, making it pretty much impossible for a small, low-budget company to bring a product to market with them.  After much investigation of the "possibilities" (which mostly turned out to be non-possibilities), I ended up going back to a 65c02, '22, RAM, EPROM, 74HC00 for glue, and a 93c06 serial EEPROM, as shown in the second-to-last picture of my address-decoding 6502 primer page at http://wilsonminesco.com/6502primer/addr_decoding.html .  It took a little more room than the 'HC11, but the price was approximately a wash, and I was able to get going developing quickly with knowledge and tools I already had.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 11:50 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Nice idea for a thread, thanks for starting it!

I'd like to make a plea that we all avoid any emotive language or dismissive comments. It should be enough to be positive about the aspects of one machine without needing to use creative adjectives about another.

For myself, I've little to offer: I very briefly used a 6800 trainer system as part of a course, and having already understood the 6502 pretty well, the machine felt oddly different.

Measuring the actual size or speed of code, where equal expertise has gone in, seems like a good test to me: it's getting the equal expertise that's quite difficult. (And the speed needs to be calibrated to RAM speed, not to clock speed!)


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 3:29 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I've heard that the Z80 was particularly awkward to code for, due to a rather non-orthogonal instruction set, but I don't have direct experience of doing so. What I do know is that the Z80 handled the DRAM access cycle itself, rather than delegating this to external hardware, and that's why it performed fewer memory accesses per second than its clock speed would suggest. This had obvious implications for system design, particularly in terms of complicating the implementation of DMA-based video scanout (compared to a typical 6502/6845 system which could just insert that into Phi1).

The "easy" method of implementing video scanout on the Z80 would effectively halt the CPU during the entire display-active time, so the CPU could only execute useful instructions during the blanking intervals (both horizontal and vertical). This was a major performance impediment to several low-cost micros such as the ZX81, which was not incurred by even the cheaper 1MHz 6502 systems. I'm not even sure how the problem was avoided on the ZX Spectrum series; I do know that MSX systems had a separate video memory which did not sit directly on the CPU bus, so the Z80 only had to be paused for DRAM refresh cycles.


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 4:06 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
The Z80-powered TRS80 Model I had a 64x16 monochrome display that was memory-mapped and quite stable. I don't think the implementation of the display degraded perfomance in a measurable way, but I was just a 13-year-old kid when I was a user, and didn't have any detailed engineering knowledge.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 5:17 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
According to the TRS-80 Technical Manual, it has a separate video RAM whose address lines are muxed between the CPU and the CRTC. So the CPU doesn't need to be halted for display scanout.


Attachments:
Screen Shot 2020-09-20 at 8.14.52 pm.png
Screen Shot 2020-09-20 at 8.14.52 pm.png [ 222 KiB | Viewed 5141 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 5:34 pm 
Offline

Joined: Sat Jul 09, 2016 6:01 pm
Posts: 180
What an interesting topic!
I have had two projects for 8-bit processors of the 70s: for the 6502, 8080, 8085, Z80, 6809:
1) https://litwr2.github.io/pi-spigot-benc ... hmark.html
2) http://litwr2.atspace.eu/xlife/retro/xlife8.html
IMHO it is rather difficult to make fast code for the Z80, you have to struggle with optimal register distribution, you have to use stack whatever it is possible, you have to use of IX and IY registers very carefully, ... The Z80 has many rather semi-registers, BCDEHL, and only one true register A. The B, C, D, E, H, L are rather slightly faster equivalent of the 6502 zero page memory than real registers. The IX and IY are really slow and not much usable. IMHO the 8085 with its hidden instructions could successfully compete the Z80. So it is still a mystery why Intel artificially degraded the 8085. I have several hypotheses about this - https://litwr.livejournal.com/2918.html
It is rather common to regard that the Z80 is about 2.5 times slower than the 6502 for the same frequency. However if we count memory speed we get that the Z80 is about 20% faster than the 6502. They are rather average numbers, for some tasks the Z80 can overtake the 6502 at the same frequency.
I have done not much programming for the 6809. IMHO it has too much a kind of Moto's oddity, like the crazy byte order, the second stack, etc - https://litwr.livejournal.com/1396.html - however it is a powerful processor, generally slightly faster than the 6502 at the same frequency.
Maybe it is interesting to notice about the well known Amstrad PCW and CPC. I did some job on them in the late 80s. They just round all the Z80 ticks to 4 tick bounds, so all instructions are executed during 4, 8, 12, ... cycles. It somehow helps to use video and CPU together, make split screen effects, etc. I know there were other computers (even the 8080 based) which used the same method. The mostly cheap video were provided on the https://en.wikipedia.org/wiki/Galaksija_(computer) where the Z80 was a CPU and a video-controller simultaneously!

_________________
my blog about processors


Last edited by litwr on Sun Sep 20, 2020 6:11 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 5:42 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
It's certainly interesting to consider system aspects: not just code density and performance per memory access, but how easy it is to serve a floppy drive, or to have more than 64k of RAM, or serve a frame buffer from main memory, or use fewer chips to make a system, and so on. (There's power consumption too, although I don't think that got much of a look in in the 70s. Having a single power rail was surely a win.)


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 6:22 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I think NMOS and 74LS were considered adequately power efficient at the time, in that a modest power supply and no external heatsink were normally required. There were a few custom chips (ULAs) made to support microcomputer peripheral functions that were not so efficient.

Of course, high-speed CMOS technology moved the bar quite considerably when it arrived, but that wasn't really until well into the 1980s. Until then, battery-powered computing either relied on "slow CMOS" or simply installing a lot of battery capacity.


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 20, 2020 7:53 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8505
Location: Midwestern USA
Chromatix wrote:
There were a few custom chips (ULAs) made to support microcomputer peripheral functions that were not so efficient.

Case in point was Commodore's 8563 video display controller, which ran on the warm side, a characteristic not helped by it being enclosed in a Faraday cage. The 8568 version shipped in the C-128D was a little less power-hungry, but was definitely not a candidate for battery-powered machines as well.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 21, 2020 2:06 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
You should add RCA's 1802 to the list. It came out in 1974, and was used in the Popular Electronics Elf articles, as well as kit computers like the Netronics Elf II. Being a CMOS processor it was power efficient, and had a built-in I/O and DMA controller. So it found a niche in applications that demanded that (like going to Jupiter).

But compared to any other eight bit the clock cycle efficiency was low, and its instruction set is just plain weird. How weird? There's no JSR or RTS because there's no stack. Short branches are absolute within a page, not PC relative. Any register can be the PC or index register which makes reading code confusing. There's also the skip and long skip instructions, which dedicated programmers swear are useful, but I found annoying.

So how do you do subroutine calls? You load the destination into a register, and use the SEP instruction to make it the PC. You return using the SEP instruction to set it back to the original PC register. To call more than one level deep you need to save the return PC in memory, and restore it to do an RTS.

Interrupts are also confusing without a stack, and I never figured them out.

The built-in DMA is actually kind of neat, so kudos for that.

tl;dr The 1802 is a Turing Tarpit, but there's a lot of affection for it because of the Elf.


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 21, 2020 5:26 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
Perhaps we could make a rough estimate of relative code density by comparing implementations of fig-FORTH? I see 1802, 6502, 6800, 6809, and 8080 (no Z80 unfortunately). The versions probably aren't quite identical in features, but should be close enough to at least get some initial data points.

I started to download the corresponding .lst files right before posting this, but ran into some difficulties ... not sure if the problem is at my end or the other end ... I'll try again later and update this post.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 21, 2020 5:28 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
My list from most to least experience:

x86
6800 and 6809
8080 and Z80
6502
AVR
68000
9900
SX52 (PIC16)
MSP430
IBM 370
ARM
1802
PIC24
H8/300 (Mindstorms RCX)

Are there any significant platforms I have not programmed in assembly language? Sure...

PDP-10, PDP-11 and VAX
PowerPC
MIPS
Sparc
Alpha
Propeller
Z8000
8051


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 21, 2020 5:29 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
Today's challenge is to subtract a signed byte from a constant yielding a two-byte number.

W0 := 258 - S1;

First, a straightforward translation for the 6800. The sign extension of the byte in the variable is done first so that the carry flag from subtracting the low bytes is not lost.

Code:
 0029 86 01           [2] 00043          ldaa   #1
 002B C6 7F           [2] 00044          ldab   #$7F      ; Thanks Mike B!
 002D D1 16           [3] 00045          cmpb   S1
 002F C2 7F           [2] 00046          sbcb   #$7F
 0031 10              [2] 00047          sba
 0032 C6 02           [2] 00048          ldab   #2
 0034 D0 16           [3] 00049          subb   S1
 0036 82 00           [2] 00050          sbca   #0


That does not look too bad. Adding the negative of a number is the same as subtracting it so try that...

Code:
 0029 86 7F           [2] 00043          ldaa   #$7F      ; Thanks Mike B!
 002B 91 16           [3] 00044          cmpa   S1
 002D 82 7F           [2] 00045          sbca   #$7F
 002F 40              [2] 00046          nega
 0030 8B 01           [2] 00047          adda   #1
 0032 C6 02           [2] 00048          ldab   #2
 0034 D0 16           [3] 00049          subb   S1
 0036 82 00           [2] 00050          sbca   #0


Did we gain anything? No, but look at it some more.

The sign extension of a negative number is $FF and 0 for a positive number. Negating that, we should get 0 for a positive number and 1 for a negative one. There is an easy way to get there.

Code:
 0029 86 7F           [2] 00043          ldaa   #$7F      ; Thanks Mike B!
 002B 91 16           [3] 00044          cmpa   S1
 002D 89 81           [2] 00045          adca   #$81
 002F 8B 01           [2] 00046          adda   #1
 0031 C6 02           [2] 00047          ldab   #2
 0033 D0 16           [3] 00048          subb   S1
 0035 82 00           [2] 00049          sbca   #0


Surely something can be done about those consecutive adds.

Code:
                          00031 * W0 := 258 - S1;
                          00032
                          00033 *   *  0 := v W0 -> 1
                          00034 *   *  1 L r 2
                          00035
                          00036 *      *  2 L c 258 -> 3
                          00037 *      *  3 - v S1
                          00038
                          00039
                          00040 *  1 L r 2
                          00041 *  2 L c 258 -> 3
                          00042 *  3 - v S1
 0029 86 7F           [2] 00043          ldaa   #$7F      ; Thanks Mike B!
 002B 91 16           [3] 00044          cmpa   S1
 002D 89 82           [2] 00045          adca   #130
 002F C6 02           [2] 00046          ldab   #2
 0031 D0 16           [3] 00047          subb   S1
 0033 82 00           [2] 00048          sbca   #0
                          00049 *  0 := v W0 -> 1
 0035 97 0D           [4] 00050          staa   W0
 0037 D7 0E           [4] 00051          stab   W0+1


Now do it on the 6502.

Code:
 0029 A9 7F           [2] 00043          lda    #$7F      ; Thanks Mike B!
 002B C5 16           [3] 00044          cmp    S1
 002D E9 7F           [2] 00045          sbc    #$7F
 002F 49 FF           [2] 00046          eor    #$FF
 0031 18              [2] 00047          clc
 0032 69 02           [2] 00048          adc    #2
 0034 A8              [2] 00049          tay
 0035 38              [2] 00050          sec
 0036 A9 02           [2] 00051          lda    #2
 0038 E5 16           [3] 00052          sbc    S1
 003A AA              [2] 00053          tax
 003B 98              [2] 00054          tya
 003C E9 00           [2] 00055          sbc    #0


Wow! That is ugly.

Because the carry flag following the comparison is opposite most other processors, an addition does not get us there. Resort to a branch.

Code:
                          00031 ; W0 := 258 - S1;
                          00032
                          00033 ;   ;  0 := v W0 -> 1
                          00034 ;   ;  1 L r 2
                          00035
                          00036 ;      ;  2 L c 258 -> 3
                          00037 ;      ;  3 - v S1
                          00038
                          00039
                          00040 ;  1 L r 2
                          00041 ;  2 L c 258 -> 3
                          00042 ;  3 - v S1
 0029 A0 01           [2] 00043          ldy    #1
 002B 24 16           [3] 00044          bit    S1
 002D 10 01 (0030)  [2/3] 00045          bpl    2f
 002F C8              [2] 00046          iny
 0030                     00047 2:
 0030 38              [2] 00048          sec
 0031 A9 02           [2] 00049          lda    #2
 0033 E5 16           [3] 00050          sbc    S1
 0035 AA              [2] 00051          tax
 0036 98              [2] 00052          tya
 0037 E9 00           [2] 00053          sbc    #0
                          00054 ;  0 := v W0 -> 1
 0039 86 0D           [3] 00055          stx    W0
 003B 85 0E           [3] 00056          sta    W0+1


Top
 Profile  
Reply with quote  
PostPosted: Mon Sep 21, 2020 8:10 am 
Offline

Joined: Sat Jul 09, 2016 6:01 pm
Posts: 180
Maybe it is worth to note that it is very easy to convert various assemblers to the 6502 assembler. For instance, let's look at https://litwr2.github.io/8080-8085-z80- ... -6502.html - this table shows a plain way to covert the Z80 code to the 6502. The reverse conversion is rather a very difficult task.
As for code density my experience shows that it is very a complicated matter. It seems that the Z80 has a better code density than the 6502 but in practice it is almost difficult to notice. I doubt that there are absolutely identical programs for different processors. Different ports always have some peculiarities.

_________________
my blog about processors


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 163 posts ]  Go to page 1, 2, 3, 4, 5 ... 11  Next

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: