Monday, December 10, 2012

Searle's Z80 SBC up!

During this winter evenings I've assembled a pure Searle's SBC.
Here is the foto.
It lacks CF card interface still.

It was not so hard - the only thing I had to test all the connections seven times.
I ran it on 2.7Mhz, while it starts on 7, but unstable (I blame the power lines).

Sharps are great processors, Zilogs and even U880 MME (1989, made in DDR) are cool too.
If you have a choice, start with Sharp.

My changes are minimal: I use one quater on one 7432 instead another, I have no soft reset button, extra led on power, reset pullup resistor on 4.7k or 10k and currently playing with resistor on INT leg. And yes, I used Soviet 1533 instead of 74ALS because I have them ;-)

Many thanks to Searle who consulted me via mail!


Зима на дворе, так что я тупо взял и собрал Searleов компутер.
Фотки тут . CFку я туда пока не присобачил.

Это оказалось весьма несложно, только надо все тестером протыкать до посинения, сейчас я гоняю это на 2.7Mhz, оно правда и на 7 заводится, но глючит, я думаю что проблемы с power.

Sharpы крассавы как процы, так что если будете паять - мучайте именно шарпея. У меня также есть родные Zigolи и аж U880 MME сделанный в 1989 году в ГДР .

Изменения в схеме - минимальны: вместо одной половинки 7432 я юзаю другую, на софт ресет забил, led на power, reset через резюк привесил, и чо-та у меня не так с подвешивающим резюком на INT ноге. И насувал туда 1533/555 вместо 74ALS.

Пообщался мыльцем с Searle, он крутой чувак и отвечал по делу.

Sunday, November 18, 2012

Today I've made Z80 to execute the first command. And used Atmega as Z80 debug processor ;-)

First, the idea: burn flash rom (described below) with the trivialest program one can image, install cpu,
install flash, feed the processor with a clock source from ATmega, and install ATmega
as data bus spy - write all the data bus to RS232.

It's easy.


Сегодня Z80 у меня выполнил первую осмысленную программу. И попользовал Atmega как Debug Processor. Надо этот термин запатентовать ;-)
Прожигаем флешку (рассказывал как), и суем туда наипростейшую программулину, суем Z80, сум флешку, кормим ее тиканьем от ATmegавой ноги, и пользуем саму AtMegу как сниффер шины данных.

First, burn flash (AT29C256) with the following :
C3 00 00 FF FF FF FF to the end of chip (JP 0 ; NOP; NOP; NOP ...)

Next, connect data bus from CPU to ROM and port B of the atmega.
Here are legs (Atmega, Z80, 29C256) in triplets:
(14,15,11)(15,15,12)(16,12,13)(17,8,15)
(18,7,16)(19,9,17)(9,10,18)(10,13,19).

Connect address bus from CPU to flash.
Flash: leg 1 - +5, 20 - gnd, 22 OE - to CPU's RD(leg 21);
Cpu: 21 - RD to flash 22 OE and to INT0 of Atmega (leg 4),
22 - WR to INT1 of Atmega (leg 5).
It means that if Z80 reads, it reads from ROM (and causes interrupt on ATmega to read
the data bus, filled by flash), and if it writes, it writes to ATmega by interrupting it on INT1
That also means that *no* address decoding is performed, and no IO/MEM decoding is
performed, too.
So if you do OUT 0x7F,A or LD (0x1488),A - no matter - you write to ATmega.

Burn atmega with the program (attached here somewhere aroud (UPD: at the end of this post!)) and lets try to read it.
It install 4 Interrupt vectors:
ISR(USART_RXC_vect) - doing nothing in this project, do not care.
ISR(TIMER1_COMPA_vect) - blinks led on PORTC 0 and provides clock to Z80
ISR (INT0_vect) - external interrupt, catches RD from Z80.
ISR (INT1_vect) - external interrupt, catches WR from Z80 (I do not care about it, BTW)

But lets start from main().
DDRC = _BV(PC0) ; // Enabling output for LED on leg 23 of atmega
TIMSK = _BV(OCIE1A); // Timer stuff
TCCR1B = _BV(CS12) // 256 prescale
| _BV(WGM12); // CTC mode, TOP = OCR1A
// OCR1A = 825; // count up to TOP 1hz with 8 meg system clock BLINK FAST
OCR1A = 25; // count up to TOP 1hz with 8 meg system clock BLINK FAST
//Install timer of atmega to blink. I do not remember where I got this code - but it works.
/* Com port settings */
USART_Init(MYUBRR);
UCSRB |= (1 << RXCIE); // enable UDRempty intr.

/* Setting IRQ0 handling - read data bus on read */
DDRD &= ~(1 << DDD2); // Declare INT0/PortD 2 as input
PORTD |= (1 << PORTD2); // turn On the Pull-up
MCUCR &= ~(1 << ISC00); // Tell the interrupts to cause on falling edge only
MCUCR |= (1 << ISC01);
GICR |= (1 << INT0); // Turns on INT0
/* Setting IRQ1 handling - read data bus on write */
DDRD &= ~(1 << DDD3); // Clear the PD3 pin
PORTD |= (1 << PORTD3); // turn On the Pull-up
MCUCR &= ~(1 << ISC10); // Oh no, falling edge only
MCUCR |= (1 << ISC11);
GICR |= (1 << INT1); // Turns on INT0
DDRB = 0b00000000; // Configure as input for data bus
static unsigned PROGMEM char b[] = "\n\r**SP: RESETTED**\n\r";
USART_PUTS_my(b);
while(1) {}

And after all we get:
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
That's means the Z80 CPU is working! (if not - short the reset pin on Z80)
And, more, that means we assembled the computer.

Note: it's a very slow computer. It runs around ~10hz, saying because ATmega has to send several bytes over a serial link (4800 baud in this example) while Z80 executes ONE command.
UPD: the code



Шьем флешку (AT29C256) следущим:
C3 00 00 FF FF FF FF to the end of chip (JP 0 ; NOP; NOP; NOP ...)
Распаиваем data bus - триплеты ног (Atmega,Z80,29C256)
(14,15,11)(15,15,12)(16,12,13)(17,8,15)
(18,7,16)(19,9,17)(9,10,18)(10,13,19).

Распаиваем адресную шину от Z80 до флешки.
Далее:
Флешка: нога 1 - +5, 20 - gnd, 22 OE - на CPU's RD(нога 21);
Cpu: 21 - RD к флешкиной 22 OE и на INT0 Atmegи (нога 4),
22 - WR на INT1 Atmegи (нога 5).

Понятно из этого что если проц что-то читает - то из флешки (и дергает ATmegу за INT0, которая радостно читает в этот момент данные которые родила фешка), а если пишет - то вообще безусловно попадает в ATMegа, дергая ее за INT1.

Заливаем а ATMegу программулину (где-то тут надо ее залить (UPD: залил, в конце!)) и давайте читать программулю.
Она устанавливает 4 вектора прерываний:
ISR(USART_RXC_vect) - это щаз нам пох
ISR(TIMER1_COMPA_vect) - моргает ledом на PORTC 0 и клочит Z80на CLK (нога 6)
ISR (INT0_vect) - внешнее перывание, ловит RD от Z80.
ISR (INT1_vect) - внешнее перывание, ловит WR от Z80

Давате почитаем от main()
DDRC = _BV(PC0) ; // Нога 23 - это LED моргалка и клоки для Z80
TIMSK = _BV(OCIE1A); // Timer stuff
TCCR1B = _BV(CS12) // 256 prescale
| _BV(WGM12); // CTC mode, TOP = OCR1A
// OCR1A = 825; // count up to TOP 1hz with 8 meg system clock BLINK FAST
OCR1A = 25; // count up to TOP 1hz with 8 meg system clock BLINK FAST
// Это инициализация таймера. Спер откуда-то, работает.

/* Это ком порт - сеттинги */
USART_Init(MYUBRR);
UCSRB |= (1 << RXCIE); // enable UDRempty intr.

/* Натравливаем INT0 на падение уровня на ноге INT0 */
DDRD &= ~(1 << DDD2); // Declare INT0/PortD 2 as input
PORTD |= (1 << PORTD2); // turn On the Pull-up
MCUCR &= ~(1 << ISC00); // Tell the interrupts to cause on falling edge only
MCUCR |= (1 << ISC01);
GICR |= (1 << INT0); // Turns on INT0
/* То же самое про INT1 */
DDRD &= ~(1 << DDD3); // Clear the PD3 pin
PORTD |= (1 << PORTD3); // turn On the Pull-up
MCUCR &= ~(1 << ISC10); // Oh no, falling edge only
MCUCR |= (1 << ISC11);
GICR |= (1 << INT1); // Turns on INT0
DDRB = 0b00000000; //Объявлем регистр B - вводом, и все его 8 бит будут тырить наш Data Bus

static unsigned PROGMEM char b[] = "\n\r**SP: RESETTED**\n\r";
USART_PUTS_my(b);
while(1) {}

Должны увидеть
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3
READS: 00
READS: 00
READS: C3

Это значит что проц работает - читает комманду JP 0000. (а если нет - то коротните reset на ноге 26 у Z80)
А так же это значит что мы собрали компьютер ;-)

Кстати, заметим, что при этом достаточно тормозной (герц 10). Например потому что atmega должна перекинуть пару байт по rs232 на скорости 4800.

UPD: the code

Saturday, November 17, 2012

Running Z80 in no-nothing mode

Well, it's time to run Z80 in do-nothing mode.
The great news (oh, well, maybe for someone that's really news) that NOP operator in Z80 is exactly FF [UPDATE: FF IS RST38!] since at least Intel i8080 times (4040? 4004? I do not know.).
It means that if we put FF on data bus via pull-up resistors- the CPU will execute NOP, then take the following address, execute NOP, etc, blinking LED on the address bus.
[UPD: It's all wrong. It will execute RST 38, but will blink, yeah. That's because it refreshes memory]
And here is idea.
What I changed:
1) they use 8 resistors from +5 to data bus. Actually, I used one - one side to +5, the other to shorded data bus.
2) they used some weird chip as clock source (what's this? 555 clone? to lazy to find it out), but I used... You know - ATmega8!

The photos: 1, 2

Continued under cut


Ну чо, самая тема запустить Z80 который будет делать нихуя. (кстати это - мое любимое занятие).
Для некоторых может и новость - но это для кого как - что команда Нихуя - NOP - еще со времен как миниум i8080 имеет код FF, за что большое спасибо компании Intel. [UPD: А аффтор-то лошок! FF - это RST 38] То есть если повесить легкий плюс на весь data bus - CPU будет перебирать адресной шиной. Куда я повесил светодиод.
[UPD: Боже, какой я кретин. Но моргать адресными шинами все равно будет - потому что будет рефрешить память]
Основная идея - тут
Разница:
1) у них 8 резюков, я на них сэкономил - повесил один от +5 на всю шину данных, ее замкнул нахуй
2) хрен поймет что у них там за чип в качестве тактового генератора, я, естественно, взял Atmega8.

А теперь - СИСЬКИ! фотки: 1, 2

I assume you have Atmega8 or smth like that on your's breadboard.
On the photo that's a 28 pin chip. It has 2 leds near it, one on leg 23 (PC0 port) via 1kohm resistor to +5, the other is just gnd-to-power via resistor, too.
It has resistor on reset leg 1 to +5. 10kohm, I suppose.
The white/grey cable is (usbasp) programmer. It connect via 10 pin standard connector to MOSI/RESET/SCK/MISO and provides power.
On my board you also see MAX232 (ADM232L) actually, surrounded by capacitors, not used while blinking Z80 bus, but connected to a standard atmega's legs 2/RXD & leg 3/TXD leading to DB9 RS232 socket, and yellow led - connected to address line (leg 30) of the Z80 via transistor.
The scheme of transistor: Z80 leg30 -[resistor 1kohm] - base of pnp transisor. Transistor emitter on gnd, collector to led, the other leg of led on +5.

You can also see an empty 28 pin socket and two red resistors with smth wht looks like a transistor. 20 pin socket will be used for flash ROM later, and the transistor is not a transistor at all but ds18s20 temperature sensor. I just made an thermometer on atmega8, if you are interested - it's here, but not going ds18s20 in Z80 project in the nearest future.

Z80 is connected the following way: leg 11 power, leg 29 gnd, data bus - 7-8-9-10-12-13-14 shorted and via the resistor (10k?) to +5 - YOU *MUST* INSTALL THE RESISTOR, leg 6 to atmega8's leg 23, +5 on 24,16,17,25, leg 30 as described.

The firmware of atmega follows, but it's very simple firmware.


Ну atmega8 у вас на макетке распаяна конечно, у меня это 28 ногий чип. Там 2 светодиода рядом, один на 23 ноге (порт PC0) через килоомный резистор на +5, второй - просто земля-резюк-led-+5.
На ноге 1 (reset) на +5 висит резистор. Наверное 10k.
Серобелый кабель это программатор avrки (usbasp). Там 10 пиновый коннектор на MOSI/RESET/SCK/MISO и с него идет +5 и gnd.
Также на плате у меня видно MAX232 (на самом деле ADM232L, но не ссуть), окруженная кондерами, но в данный момент нас это не интересует. Ну там ноги 2 и 3 atmega8 идут на MAX232, к нему прихерачен ком-порт, а дальше торчит желтый светодиод, который влючен так: Z80 нога30 -[резюк 1kohm] - база 3107. Его эмиттер на земле, коллектор-LED-+5.

Ну там еще кровать на 28 пин неюзанная пока и 2 красных резюка с чем-то похожим на транзюк, хотя это нифига не транзюк, а ds18s20 температурный сенсор. Я его в обозримом будущем в Z80 сувать не собирался, я просто собирал на atmega термометр - получилось такое, кстати.

Z80 соединен так: нога 11 +5, 29 - земля, датабас вся закорочена, нахуй, как я и обещал, от нее торчит резюк (тоже наверное 10k) на +5 и ОН ПРАВДА НУЖЕН БЕЗ НЕГО НИЧЕГО РАБОТАТЬ НЕ БУДЕТ, 6 нога на atmegaвскую 23, +5 на 24,16,17,25,про 30ую я уже сказал.

Фирмваря под atmega, но как бы это совсем простенько.

/*
File: main.c
Version: 1.0.0
Date: May. 12, 2006

AVR Tutorial #1 - Toggle and LED on PC0

Schematic available at http://www.micahcarrick.com.

****************************************************************************
Copyright (C) 2006 Micah Carrick

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#define F_CPU 1000000UL /* 1 MHz Internal Oscillator */

#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>

/* function for long delay */
void delay_ms(uint16_t ms) {
while ( ms )
{
_delay_ms(1);
ms--;
}
}

int main (void)
{
/* PC0 is digital output */
DDRC = _BV (PC0);

/* loop forever */
while (1)
{
/* clear PC0 on PORTC (digital high) and delay for 1 Second */
PORTC &= ~_BV(PC0);
delay_ms(200);
PORTC |= _BV(PC0);
delay_ms(200);
}
}

Tuesday, November 13, 2012

A pair words on AVR

As I've told, I'm going to use AVR whereever it's possible - and use them just like an instrument like an solderer or multimeter. So I have to say pair words about it - nothing interesting, there are a lot of really good tutorials on the net around, I just want to show my setup in case someone will follow me.


А сейчас - пару слов об AVRках. Я собрался их сувать куда только смогу и вообще юзать как инструмент - как пяльник или тестер. Туториалов в сети просто до японой матери, поэтому я только покажу свой сетап который дальше я буду юзать в хвост и в гриву.

Compiler: sure, avg-gcc + avr-libc.
Chip: Atmega8.
Me: a newbie in avrs.
Programmer: initially I've soldered FBPRG for use with avreal and it worked fine, but then I've ordered USBasp from here and quite happy with avrdude. I made a "standart" MAX232A RS232 interface, and it works fine on 2400 with internal 1MHz. Also I have a led on PC0. That's the basic setup.

When setting your's first avr, first solder power and a socket for programmer, and then try to program it with anything. It should work. Next, install LED via resistor (~510 ohm) and blink it. Next, attach MAX232A.
In my setup it found that only one half of MAX232A works properly, and this is very strange for me, I've tried different chips from different manufacturers (MAX232, MAX232A, Analog Devices), different capacitors (1μF for MAX232 and 0.1μF for MAX232A), so try it. And do not forget to disable hardware handshake, all the RTS/CTS/DTR/DSR and all.


Компилятор: естественно, avr-gcc + avr-libc.
Chip: Atmega8.
Я: лошок в avrах.
Изначально я спаял FBPRG и юзал его с avreal (и тащем-то это круто и все такое), а по ходу дела заказал на алиэкспрессе USBasp у этого косорылого товарища , который весьма себе товарищ и я теперь весьма рад с этого USBasp. Прицепил туда через MAX232A RS232, и на 2400 он весьма себе работает от внутреннего 1MHz тактового генератора. Ну, там, светодиод в PC0. Ну вобщем все так.

Будучи лошком в avrках я рекомендую таким же лошкам делать так: распаять питание и разьем под программатор и сразу же попытаться зашить любую ересь. Там мало где можно ошибиться, так что должно прошиться. Потом прицепить светодиод какой-нибудь простенький через резюк (ну, 510 ом) и поморгать им. Тоже вроде ничего сложного. А потом прицепить MAX232A.
А вот тут меня ждала засада. Половина MAX232A почему-то работала, а вторая - нет. Чипы менял на MAX232 и Analog Devices, кондеры с 1μF для MAX232 и 0.1μF для MAX232A, ничего не понял, но методом Перетыка все работает, да и хер.
А, и не забудьте в терминалке вырубить все RTS/CTS/DSR/DTR.

flashrom.org and At29C256

I've managed to burn AT29C256 (widely used, and used in Searle's computer) on Realtec/RTL 8139 nic with flashrom.org's software with the following patch (under cut). AT29C256 is unknown chip for it, that's strange. I'll tell a bit later about it, how - just make a reminder to myself (and possibly others). The only note - I have 3 nics, and was able to write only the first 256 bytes on the first nic. The second one worked ok.

UPDATED at 121125


Тут мне надо было прошить AT29C256 (которая вааще везде нужна в таких делах - а так же используется в схеме у схеме от Searle, )- и делал я это на Realtek/RTL 8139 тулзой от flashrom.org .
Оно такого чипа не знает, пришлось налабать патчик. У меня Realtecов три штуки, в первой прошилось почему-то только 256 байт, а вот вторая завелась. Об этом всем - позже, а пока - патч.
Обновлено 121125

flashchips.h , after
#define ATMEL_AT29C512 0x5D
add
#define ATMEL_AT29C256 0xDC

flashchips.c

{
.vendor = "Atmel",
.name = "AT29C256",
.bustype = BUS_PARALLEL,
.manufacture_id = ATMEL_ID,
.model_id = ATMEL_AT29C256,
.total_size = 32,
.page_size = 64, /*It should*/
.feature_bits = FEATURE_LONG_RESET,
.tested = TEST_OK_PREW,
.probe = probe_jedec,
.probe_timing = 10000, /* 10mS, Enter=Exec */
.block_erasers =
{
{
.eraseblocks = { {32 * 1024, 1} },
.block_erase = erase_chip_block_jedec,
}
},
.write = write_jedec,
.read = read_memmapped,
.voltage = {4500, 5500},
},


UPDATE:
The strange thing is that it burns *some* images, but does not burn others with the following:
Erasing and writing flash chip... Trying erase function 0... 0x000000-0x007fff:EWVERIFY FAILED at 0x00000000! Expected=0xf3, Read=0x00, failed byte count from 0x00000000-0x0000003f: 0x13
retrying.
VERIFY FAILED at 0x00000000! Expected=0xf3, Read=0x00, failed byte count from 0x00000000-0x0000003f: 0x13
retrying.
Currently I do not understand whats going on

Monday, November 12, 2012

The Aim // Цели

I am going to implement a modern Z80 computer.

The other aim is to learn soldering and gaining practical microelectronics skills

That's how I see it:

The real Z80 chip. Serial only, no video. No floppies or HDD - only flash (CF or MMC). Using avr where it's possible. CP/M.

Plan maximum:
USB hub. TCP via slip or ENC28J60. Optional terminal on avr and LCD.

My limitations:
Only DIP. No EPROM programmer. I'd like to use single-side handmade PCB's

References:
http://searle.hostei.com/grant/ - is not exactly what I want, but very cool.



Почесав седые муди я таки решил забабахать нормальный чоткий современный копм на настоящем проце типа такого:

Реальный Z80.  Только ком-порт. Если у вас нет ком порта - то вы лох! Никаких флоппов и винтов, только CF или MMC. Сувать avrки куда только можно.  Засунуть туда CP/M.

План максимум:
USB hub. TCP через slip или ENC28J60. Может залабаю терминал на avrке и LCDшке.

Ограничения:
Только DIPы и никаких 27xx и РФок - у меня нет программатора и возиться с ним я не хочу. Односторонние (не двух) платы с соплями.

Ссылки:
http://searle.hostei.com/grant/ - тут сидит очень крутой чувак который схерачил почти то что я хочу.


А, ну еще: по ходу я хочу научиться паять и сделать что-то руками, а то я пиздец какой теоретик на попиздить, а рученки кривые. Опять же, хочется похвастаться чем-нибудь.