nedoPC-280 (два процессора 8080A-1)

Публичный форум для http://www.nedopc.org/nedopc

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

nedoPC-280 (два процессора 8080A-1)

Post by Shaos »

По итогам обсуждения Галаксии у меня родился план собственного компьютера на двух 8080, активно участвующих в генерации видеосигнала. Решил начать с NTSC, растактовки которого можно посмотреть тут. Вот тоже самое, но все задержки пересчитаны на 2.5-мегагерцовый пиксельклок:

Code: Select all

Lines 0...199:
    ____^^^^^^^^^^^^^^^^^^^^__
|__|
 12  21     120 (screen)    6

Lines 200...224:
    __________________________
|__|
 12           147

Lines 225,226,227:
 __
|  |__________________________
 12           147

Lines 229...261:
    __________________________
|__|
 12           147
Прерывания идут с частотой 15.7 кГц (это 2.5МГц / 159) - в обработчике счётчик строк считает в какой мы строке и генерит строчный синхроимпульс длительностью 12 тактов (синхроимпульс инвертирован для строк с номерами 225,226,227) далее после 21 такта начинаем брать байты через MOV A,M; INX H (до 10 раз на каждый процессор - в зависимости от длины выводимой строки), которые некая схема копирует в сдвиговый регистр либо напрямую (для графического режима) либо через ПЗУ знакогенератора (для текстового). Вобщем как-то так...
Last edited by Shaos on 09 Sep 2012 12:30, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

b2m wrote:Ещё вариант: можно сделать, чтобы чтение из видео-памяти автоматически записывало данные в сдвиговый регистр. Тогда достаточно MOV A,M / INX H (12 тактов) При 2.5Мгц получим ровно 10 символов :)
вот примерно так в первом приближении может выглядеть обработчик строчного прерывания в случае текстового экрана NTSC (пока ограничимся 16 текстовыми строчками):

Code: Select all

port_pid EQU #FFFF ; port to get processor identifier (0,1)
port_video EQU #FFFE ; port to write video out (bit 0 of P1 for sync and bits 0,1,2 of P2 for Y)
port_vdata EQU #FFFD ; port to say that we have data out (bit 0)
start_addr EQU #C000 ; info about line number 0
end_addr EQU #C106 ; next address after 251st line info
end_addr_hi EQU #C1
end_addr_lo EQU #06
video_addr_hi EQU #80

saved_addr DW start_addr

INTERRUPT:
  ; prepare (127 for processor 0, 133 for processor 1)
  PUSH PSW ; 11
  PUSH H ; 11
  LHLD saved_addr ; 16 - saved address of current line info to HL
  LDA port_pid ; 13 - read processor identifier
  RRC ; 4 - shift right to get processor identifier in flag C
  JC INTER_P1 ; 10 - go if processor 1
  ; stay if processor 0 (62)
  MOV A,M ; 7 - read current line info
  ANI #F0 ; 7 - mask for video mem
  JZ INTER_FINISH ; 10 - finish if zero (it means no video data in this line)
  MOV A,L ; 5 - L is coordinate Y or the current line, so A=L
  STA  port_video ; 13 - output character Y (lowest 3 bits of it)
  MOV A,A ; 5 - pause
  MOV A,A ; 5 - pause
  JMP INTER_GO ; 10 - go to videodata if not zero
INTER_P1: 
  ; processor 1 will do sync generation (68)
  MOV A,M ; 7 - read current line info
  STA port_video ; 13 - output bit 0 of line info as sync
  RRC ; 4 - shift right to prepare next sync output
  STA port_video ; 13 - output bit 1 of line info as sync
  MOV A,M ; 7 - read current line info
  ANI #F0 ; 7 - mask for video mem
  JZ INTER_FINISH ; 10 - finish if zero (it means no video data in this line)
  ADI 8 ; 7 - add 8 to form lower part of the address of videomem for processor 1

INTER_GO:
  ; videodata output (43+12*W-5+27 = 65+12*W)
  PUSH H ; 11 - save HL
  ; form videomem address
  MOV L,A ; 5
  MVI H,vide_addr_hi ; 7
  MVI A,1 ; 7 - A=1
  STA port_vdata ; 13 - inform hardware that we have videodata to show
  ; generate video output
  MOV A,M ; 7
  INX H ; 5
  ....
  MOV A,M ; 7
  INX H ; 5
  MOV A,M ; 7
  XRA A ; 4 - clean A
  STA port_vdata ; 13 - inform hardware that videodata is ended
  POP H ; 10 - restore HL

INTER_FINISH:
  ; finishing interrupt handler (73 for lines 0..255, 88 for lines 256..260, 98 for line 261)
  INX H ; 5 - increment address of line info and compare it to end_addr
  MOV A,H ; 5
  CPI end_addr_hi ; 7
  JNZ INTER_END ; 10
  MOV A,L ; 5
  JNZ INTER_END ; 10
  LXI H,start_addr ; 10 - go to the start
INTER_END:
  ; happy ending (46)
  SHLD saved_addr ; 16 - save line info address for the next step
  POP H ; 10
  POP PSW ; 10
  RET ; 10
Как видим уже получилось многовато - начало обработчика прерывания займёт 127/133 тактов в зависимости от процессора (получаем 6-тактовый сдвиг для второго), далее 65+12*W чтобы заслать буквы и от 73 (для первых 256 строк) до 98 тактов, чтобы завершить прерывание. Строчный синхроимпульс будет послан через 85 тактов после начала прерывания и будет иметь длительность 17 тактов. Буквы начнут засылаться через 68 тактов после окончания синхроимпульса (170 тактов после начала прерывания) - т.е. при частоте 2.5 МГц мы уже не влезаем в строку. Предположим что мы ограничимся 16-символьной строкой, тогда W будет равно 8 - в этом случае для вывода букв потребуется 65+12*8=161 такт и общая длительность обработчика прерывания составит в этом случае 133+161+73=367 тактов, что с учётом 11 тактов на RST составит 378 тактов, которые надо утолкать в 64 микросекунды, что возможно только если один такт процессора будет короче 169 нс что ориентировочно составляет 6 МГц...

P.S. Веб-сайт http://www.cpu-zone.com/8080.htm говорит, что существуют следующие разновидности 8080 процессора: 8080A 2.0MHz, 8080A-1 3.125MHz, 8080A-2 2.67MHz, 8080B 4.0MHz. То есть теоретически можно найти 8080B и попытаться разогнать их до 6 МГц либо добавить кое-какую аппаратную подмогу для вычислений, на кототрые в начале обработчика прерывания тратится уйма времени, и уложится в 3-4 МГц...

P.P.S. На ебее есть 8080A-1 3.125 МГц! Купил у 2 разных источников - американского и китайского...
Я тут за главного - если что шлите мыло на me собака shaos точка net
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Post by b2m »

Shaos wrote:вот примерно так в первом приближении может выглядеть обработчик строчного прерывания в случае текстового экрана NTSC
А ты не забыл, что прерывание начинает исполняться не немедленно, а только по завершении команды, которая как мы знаем от 4 до 18 тактов. Т.е. изображение будет дёргаться влево-вправо, в зависимости от того, на какой команде возникло прерывание.

Я вижу только одно решение проблемы: чтение из видеопамяти должно тормозиться сигналом ready до конца строчного СИ. Только в этом случае мы получим ровный левый край.

Кстати, у нас не так много времени на обратный ход по строке, и лучше переждать это время, а не возвращаться к прерванной программе. Таким образом, лучше прерывание сделать по концу кадрового СИ (или уже там, где изображение должно начинаться), и выводить весь экран. Только после этого завершать прерывание.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Ещё один вариант кода для вывода символа на разогнанном процессоре без помощи внешнего железа по отлову байтов на шине, как в предыдущем случае:

Code: Select all

  MOV A,M ; 7
  STA vport ; 13
  INX H ; 5
  INX H ; 5
Тут пользуемся тем, что первый проц выводит чётные байты, а второй - нечётные. Всего 30 тактов, разнесённых по процам на 15 тактов - в каждые 15 тактов будет выводиться одна полоска символа - по 2 такта на точку (7 точек) плюс 1 такт пробел между символами - в таком случае при 5 МГц получим 16 символов в строке...

Или вот так (на основе моего первого предложение в оригинальном посте):

Code: Select all

LXI H, video-mem ; address of current line
if(processor==1) INX H ; make odd for processor 1
LXI D, video-out ; address instead of port
; 24 ticks to send byte
MOV A,M ; 7
STAX D ; 7
INX H ; 5
INX H ; 5
; 24 ticks to send another byte
MOV A,M ; 7
STAX D ; 7
INX H ; 5
INX H ; 5
.... ; etc 
12 тактов на символ - 2 такта на пиксел 6-пиксельных символов - 20 символов в строке при 5 МГц (и 16 при 4 МГц)

P.S. При разнесённых чётных и нечётных последовательностей тоже можно что-то такое соорудить:

Code: Select all

  MOV A,M ; 7
  OUT vport ; 10
  INX H ; 5
Всего 22 такта - по 11 тактов на символ - по 2 такта на точку (5 точек) плюс 1 такт на промежуток - в этом случае при 5 МГц в строку влезет до 22 символов.

P.P.S. Ещё один вариант - задавать коды символов прямо в обработчике прерывания, тогда обработчик строкового прерывания не будет отдавать управление пока не нарисует весь видимый кадр:

Code: Select all

  MVI A,code0 ; 7
  STA vport ; 13
  MVI A,code2 ; 7
  STA vport ; 13
  MVI A,code4 ; 7
  STA vport ; 13
  ...
Тут имеем 10 тактов на символ (20 тактов разнесённых по процам на 10 тактов) - 24 символа в строке при 5 МГц (и почти 20 при 4 МГц)

P.P.P.S. А вот тоже самое если держать адрес видеопорта в DE:

Code: Select all

  MVI A,code0 ; 7
  STAX D ; 7
  MVI A,code2 ; 7
  STAX D ; 7
  MVI A,code4 ; 7
  STAX D ; 7
  ...
Получается 7 тактов на символ - 34 символов в строке при 5 МГц и почти 28 при 4 МГц ( можно ограничиться скажем 24 x 18 )

Вот ещё проще:

Code: Select all

  MVI M,code0 ; 10
  MVI M,code2 ; 10
  MVI M,code4 ; 10
  ...
Но цифры не очень удобные - 5 тактов на символ...
Last edited by Shaos on 09 Sep 2012 15:28, edited 8 times in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

b2m wrote:
Shaos wrote:вот примерно так в первом приближении может выглядеть обработчик строчного прерывания в случае текстового экрана NTSC
А ты не забыл, что прерывание начинает исполняться не немедленно, а только по завершении команды, которая как мы знаем от 4 до 18 тактов. Т.е. изображение будет дёргаться влево-вправо, в зависимости от того, на какой команде возникло прерывание.
Да - не очень хорошо получается...
b2m wrote: Я вижу только одно решение проблемы: чтение из видеопамяти должно тормозиться сигналом ready до конца строчного СИ. Только в этом случае мы получим ровный левый край.
Можно синхронизировать процы в момент обращения к адресу где будет находится порядковый номер проца - прерывание будет взводить триггер и первый проц, который обратится по этому адресу, встанет по READY, взведя второй триггер - оба триггера будут сбрасываться вторым процом, который обратится по этому же адресу. Кстати номер проца можно не формировать железно - кто обратится к этому адресу раньше, тот и первый ;)
b2m wrote: Кстати, у нас не так много времени на обратный ход по строке, и лучше переждать это время, а не возвращаться к прерванной программе. Таким образом, лучше прерывание сделать по концу кадрового СИ (или уже там, где изображение должно начинаться), и выводить весь экран. Только после этого завершать прерывание.
Ну тогда придётся аппаратно генерировать строчные синхроимпульсы, а хотелось всё затолкать в проц...
Я тут за главного - если что шлите мыло на me собака shaos точка net
b2m
Devil
Posts: 907
Joined: 26 May 2003 06:57

Post by b2m »

Shaos wrote:Ну тогда придётся аппаратно генерировать строчные синхроимпульсы, а хотелось всё затолкать в проц...
Строчные СИ нужно генерировать почти постоянно, при таком подходе процессор больше ничего не успеет сделать. Да и для генерации прерывания по кадру или по строке всё равно придётся делать счётчик. Хотя, можно использовать ВИ53 :)

Я вижу это так: при помощи одного канала ВИ53 можно отмерять время по кадру (начало КСИ, конец КСИ, начало изображения), а другие два канала будут генерить строчные СИ (начало и конец СИ). Изображение за одно прерывание генерить не для одной строки, а для всего кадра.

Я ещё подумал, что может быть вместо двух процессоров проще сделать два банка памяти и два сдвиговых регистра, объединённых в один 16-битный сдвиговый?
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Задача сделать компьютер с видеовыходом и минимальной внешней обвязкой :)

Понятно что строчные надо генерить постоянно, но для тех строк где нету данных обработчик очень не надолго брал бы управление - только чтобы синхроимпульс организовать, но если оно гулять будет 4-18 тактов, то наверное строки придётся считать аппаратно...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16693
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Ну не побрезгуйте схемотехникой Галактики. Там механизм, похожий на описанный b2m,
довольно несложно реализован...
iLavr
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: nedoPC-280 (два процессора 8080A-1)

Post by Shaos »

А вот ещё мыслей (почти что через 4 года):

Code: Select all

  MVI A,code0 ; 7
  OUT vport ; 10
  MVI A,code2 ; 7
  OUT vport ; 10
  MVI A,code4 ; 7
  OUT vport ; 10
т.е. 17 тактов на символ от одного проца - совсем криво выходит

А что если код символа не посылать в порт, а сам адрес порта будет являться кодом символа? :o

Code: Select all

  OUT code0 ; 10
  OUT code1 ; 10
  OUT code2 ; 10
По идее можно и IN т.к. посылаемый-принимаемый байт значения не имеет (но можно сделать чтобы имел)

А в чём фишка по сравнению с притянутыми нопами? А в том, что процессор сам решает что и в каком порядке выплёвывать на экран :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16693
Joined: 21 Oct 2009 08:08
Location: Россия

Re: nedoPC-280 (два процессора 8080A-1)

Post by Lavr »

Shaos wrote:А вот ещё мыслей (почти что через 4 года):
А что если код символа не посылать в порт, а сам адрес порта будет являться кодом символа? :o

Code: Select all

  OUT code0 ; 10
  OUT code1 ; 10
  OUT code2 ; 10
По идее можно и IN т.к. посылаемый-принимаемый байт значения не имеет (но можно сделать чтобы имел)

А в чём фишка по сравнению с нопами? А в том, что процессор сам решает что и в каком порядке выплёвывать на экран :)
Ну, во-первых, что и в каком порядке "выплёвывать" на экран решает всё же стандарт развертки...
А фишка по сравнению с нопами в том, что IN и OUT - двухбайтные команды, а число тактов - 10 супротив
4-х у NOP, значит и вынос в регистр сдвига будет медленнее, а значит и число точек - меньше...

То ли Shaos торопился куда-то, то ли мудрости не приобрел за "почти что через 4 года"... 8)
iLavr
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: nedoPC-280 (два процессора 8080A-1)

Post by Shaos »

Стандарт развёртки требует лишь поставить синхроимпульсы по нужным отступам - и всё...

Короче размышляем дальше - если решаем идти по пути VGA (см. http://martin.hinner.info/vga/timing.html), то строки должны идти с частотой 31778 Гц, с которой будут дёргаться прерывания - чтобы строчки не разъезжались (на отмеченные выше 4...18 тактов), надо процы и синхроимпулс синхронизировать - потом подумаю как. А сейчас считаем - 3.125 МГц это 312500 выплюнутых байтов с каждого проца в секунду или 9.8 байта в строку или 8 видимых - совсем не густо, но если вспомнить, что у нас проца 2, то получается уже 16 символов в строке, что по идее уже терпимо, но неинтересно...

P.S. А не поставить ли 10 процов, разнесённых на 1 такт? Тогда будет 80 символов в строке...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16693
Joined: 21 Oct 2009 08:08
Location: Россия

Re: nedoPC-280 (два процессора 8080A-1)

Post by Lavr »

Shaos wrote:Стандарт развёртки требует лишь поставить синхроимпульсы по нужным отступам - и всё...
Не... что-то ты плохо 4 года размышлял... :wink: Еще стандарт любит, чтобы длительности синхроимпульсов
не слишком отличались от стандартных...

А люди вон еще про "привязку уровня черного" откопали траблу, что даже для меня ново! :o
Хотя я и смотрел довольно давно, к чему приводит отсутствие этой привязки...
iLavr
User avatar
Shaos
Admin
Posts: 24095
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: nedoPC-280 (два процессора 8080A-1)

Post by Shaos »

Lavr wrote:
Shaos wrote:Стандарт развёртки требует лишь поставить синхроимпульсы по нужным отступам - и всё...
Не... что-то ты плохо 4 года размышлял... :wink: Еще стандарт любит, чтобы длительности синхроимпульсов
не слишком отличались от стандартных...
Угу - и это тоже (отступы я имел ввиду и по фронтам, и по спадам)
Я тут за главного - если что шлите мыло на me собака shaos точка net