nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 13:09



Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Геометрия экрана "Специалист" 
Author Message
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
HardWareMan wrote:
а уже потом натянуто на сетку частот видеосигнала (получилось 2МГц на процессоре заместо 1,7МГц в РКшке).

А в "Орионе" - 2.5МГц и тоже натянуто на ту же сетку частот и тот же арбитр... :wink:
Как же так по-разному получилось? При фактически идентичной схемотехнике?

_________________
iLavr


01 Oct 2013 10:16
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
HardWareMan wrote:
есть следующее мнение: 8МГц Специалиста выбраны именно из-за достижения простоты синхрогенератора, т.к. частота кратна частоте строк в степени двойки. А вот 10МГц Ориона уже появились, по моему мнению, для исправления аспекта, чтобы получить полноценные 4:3. Ну и бордюр в те времена был полезен ибо не каждый мог подстроить размер растра телевизора.

Вот я подчеркнутую мысль и высказал, собственно говоря:
Lavr wrote:
за основу взята схема прозрачной регенерации ДОЗУ, частоты которой были выбраны
так, чтобы хорошо попадать в строчную и кадровую развертки.

Если посмотреть расчет - то в параметры стандарта там всё очень четко уложено,
чего не скажешь об "Орионе".

И про какие "исправления аспекта" можно говорить, когда у "Ориона" экран заужен
при тех же изначальных 384х256?

Ну и вопрос я свой адресовал-таки нашему авторитетному источнику - PNP - чтобы
услышать, как оно было на сАмом деле...
А то мы много тут чего предполагали, а он нас покритиковал чутка...

Так что - просто хотелось бы узнать правду от человека, близкого к первоисточнику.

_________________
iLavr


02 Oct 2013 05:12
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
HardWareMan wrote:
У меня на телевизоре, настроенном на обычный видеосигнал, у Специалиста круг был немного растянут по горизонтали, в то время как у Ориона нет.

А у меня на зелёном венгерском мониторе "Орион" круг был просто идеальным!
Огорчу тебя также тем, что круг выходил совершенно правильным кругом на печать
моим любимым принтером тех времен - УВВПЧ.
То есть имел место полный "ВизВиг"...

Так что это у тебя с телевизором что-то не тоё было...

_________________
iLavr


02 Oct 2013 15:43
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
HardWareMan wrote:
Это я тебя огорчу. 384х256 в самом деле соотношение 4:3.
В результате огорчился не он, а я, поскольку не могу никак подобрать систему, в которой 384 поделённое на 256 будет равно 4/3 ... :cry:

В известных мне системах почему то 384/256==3/2 .. Странно.
Может в разных школах разные математики ? :roll:

А правду говорят, что в СССР была СЕКАМ и из 625 строк полного кадра видимыми должны были быть 525 ? А в полукадре соответственно 262.5 строк видимых ?
А то может и справочники разные..
Вот который я читал, в том про черезстрочную кадровую развёртку 50Гц~~20мс-полукадр, 25Гц~~40мс-полный кадр и строчную частоту 15625Гц что то написано, а в каком другом справочнике может всё и по другому.. :-?


02 Oct 2013 21:52
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
HardWareMan wrote:
Хаха, точно. Я никогда не делил эти цифры...
Ну вот я опять огорчился. :cry:
У нас в начальной ( и средней ) школе вообще никогда не делили цифры. Делили только числа.( ибо "цифра есть значок, употребляемый для записи чисел", а "число есть абстрактная форма записи некоего реального количества". - согласно определению из учебника.. )
HardWareMan wrote:
... Если 256 умножить на 1.3, то получаем ~332 точки ...
А вот если умножить не на 1.3, а на дробь (4/3) то получится 256*(4/3)==341.(3) ( для организации счётчиков в графическом контроллере лучше округлить в большую сторону, т.е.342 пиксела ), соответственно 262.5*(4/3)==350
Таким образом, полагая пиксел квадратным, для соотношения 4 к 3 получаем "правильный" экран 342 на 256 пиксел с бордюром слева и справа по (350-342)/2==4 пиксела, а снизу и сверху по (262.5-256)/2==3.25 пиксела ( тоже придётся округлять )
HardWareMan wrote:
А вот про строки тоже не ясно, сколько именно строк должно быть в КОХ.
Со строками всё вполне даже ясно.
В полном кадре 625 всего, из них 525 видимых, 100 не отображаются
, соответственно в полукадре 312.5 всего, из них 262.5 видимых, 50 не отображаются - идёт обратный ход кадровой развёртки.
По времени тоже всё ясно : 20мс/312.5==64мкс==0.064мс
0.064мс*262.5==16.8мс идёт отображение
0.064мс*50==3.2мс идёт обратный ход кадровой развёртки


02 Oct 2013 23:17
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
Совершенно верно, именно полагая экран плоским и "правильным".:idea:
Чисто математически идеализируя, то есть.
В реале, понятное дело, надо будет ещё много чего учитывать.
Shaos wrote:
А буквы делить вас в школе не учили? ;)
Типа a/b=c ;)
Не знаю, как там в ВУЗ ( у меня неполное среднее, если что.. ), но в школе учили делить некие неизвестные величины, абстрактно изображаемые буквами.
Но сами буквы можно делить разве что на чёрточки и точечки, из которых они и составляются.
Вот как то так..
Вы уж извините, ежели я не в курсе последних достижений британских "учоных"


Last edited by petrenko on 03 Oct 2013 00:11, edited 1 time in total.



02 Oct 2013 23:45
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
"Вау" тута усе такие грамотные, просто жуть..
Куда уж там нам с неполным средним образованием, да постигать сложнейшие тайны..

Зато я теперь знаю, с чего начинаются форумные"мега-холивары"- они начинаются с зашкаливающей грамотности всех участвующих в оных оппонентов.

Всем удачи в освоении компьютера "Фах³вець-85" ! :rotate:

( если кому нужны консультации по арифметике в рамках начальной школы - пожалуйста - можете обращаться, мало ли кто после двух - трёх В.У.З. забыл что-нибудь, ну или без калькулятора перемножить или разделить не сможет - поможем, чем можем, мы люди простые, добрые.. )


03 Oct 2013 00:05
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
Не волнуйтесь, я очень добрый, на коллег не обижаюсь.
Просто у меня своеобразное чувство юмора.. :rotate:
А вот без этого самого юмора и вправду можно было бы свихнуться от любой мелочи, хоть даже и от отсутствия "умляута" над "ё" :o
А то, что простые люди иногда что-нибудь могут перепутать - так не всем же повезло с учителями. Вот в одной стране главный ( ГБ-шник кстати ) и тот называет"цифру инфляции" :D , и ничего - терпим..

По теме : несколько не соответствующие соотношению 4 к 3 графические контроллеры многих ЛК - это компромисс, упрощающий организацию счётчиков. "Правильные" контроллеры графического дисплея я видел, но они во-первых сами сложнее, а во-вторых требуют более мало-доступного устройства отображения, нежели бытовой телевизор.


03 Oct 2013 02:14
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
HardWareMan wrote:
На принтер 6337 у меня тоже круг выходил круглый. Но на телевизоре он был овалом. И настраивать круг на нем меня ломало, ибо таблицу УЭИТ он показывал идеально. Так что мимо кассы ты тут с венгерскими накрученными мониторами. :3

А мне кажется это ты всегда мимо кассы... но что бы не спорить, я соглашусь - пусть
у HardWareMan всё самое лучшее, ну а у меня - такое, какое уж было:
Lavr wrote:
у меня на зелёном венгерском мониторе "Орион" круг был просто идеальным!
... круг выходил совершенно правильным кругом на печать
моим любимым принтером тех времен - УВВПЧ.
То есть имел место полный "ВизВиг"...

Вероятно потому как одним было влом подстраивать, а другие просто работали за
хорошим монитором.

_________________
iLavr


03 Oct 2013 04:04
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Поскольку у меня заработал он-лайн эмулятор 6502, я занялся программированием на ассемблере
этого процессора. Ну и поскольку, кроме графического экранчика 32х32 точки на 16 цветов в этой
системе устройств практически нет, пришлось вспомнить примитивы растровой графики...

Линии круги и более сложные кривые на растровом устройстве помогают отрисовать Алгоритмы Брезенхема.

Ну и линию отрисовывает Bresenham's line algorithm, суть которого в двух словах заключается в том,
что, поскольку в растровой графике линия аппроксимируется ломаной линией по пикселям, то закрашивается
тот пиксель растра,среднеквадратичное отклонение которого от линии наименьшее.

Алгоритм Брезенхема интересен тем, что работает в целых числах, не нуждается в сложных операциях, а основная
хитрость его заключается в удвоении отклонения, в результате чего в целых числах становится уверенно различимым.

Image

Этот алгоритм я ещё давно реализовывал с помощью одной хорошей книжки по графике, и на языке Васик этот
алгоритм выглядит примерно следующим образом:
Code:
     DEFINT A-Z

     SCREEN 7 ' 320 x 200 graphics; 40 x 25 text format, character box size 8 x 8
              ' Assignment of 16 colors to any of 16 attributes
Start:
COL = 4

' Absolute pixel coordinates for line origin.
x1 = 200
y1 = 140

' Absolute pixel coordinates for line end.
x2 = 250
y2 = 14

  LINE (x1, y1)-(x2, y2), 2 '--- LINE QBASIC для сравнения

DO
  Key$ = INKEY$
LOOP WHILE Key$ = ""

    dy = y2 - y1
    dx = x2 - x1

    IF dy < 0 THEN  '--- (y1 > y2)
       dy = -dy
       stepy = -1
     ELSE
       stepy = 1
    END IF

    IF dx < 0 THEN  '--- (x1 > y2)
       dx = -dx
       stepx = -1
     ELSE
       stepx = 1
    END IF

    dx = dx + dx
    dy = dy + dy

'--Displays a pixel at given absolute (x, y) location
   PSET (x1, y1), COL

    IF dx > dy THEN
       fraction = dy - (dx \ 2)'  Integer division
       WHILE x1 <> x2
          IF fraction >= 0 THEN
               y1 = y1 + stepy
               fraction = fraction - dx
          END IF
               x1 = x1 + stepx
               fraction = fraction + dy
             PSET (x1, y1), COL
        WEND
     ELSE  ' dx = dy
       fraction = dx - (dy \ 2)'  Integer division
       WHILE y1 <> y2
          IF fraction >= 0 THEN
             x1 = x1 + stepx
             fraction = fraction - dy
          END IF
             y1 = y1 + stepy
             fraction = fraction + dx
             PSET (x1, y1), COL
        WEND
    END IF


На языке С алгоритм можно воплотить примерно вот так:
Code:
//---------------------------------------------------------------------------
void B_Line (int x1, int y1, int x2, int y2)
{
 if (x1 < x2)
    {
      xi = 1; // Step X ;
      dx = x2 - x1;
    }
     else
    {
      xi = -1; // Step X ;
      dx = x1 - x2;
    }

 if (y1 < y2)
    {
     yi = 1; // Step Y ;
     dy = y2 - y1;
    }
     else
    {
     yi = -1; // Step Y ;
     dy = y1 - y2;
    }

    PutPixel (x1, y1);

 if (dx > dy)
    {
     ai = (dy - dx) * 2;
     bi = dy * 2;
      d = bi - dx;

     while (x1 != x2)
       {
         if (d > 0)
            {
            y1 += yi; // Step Y ;
             d += ai;
            }
            else   
             d += bi;
            x1 += xi;
         PutPixel (x1, y1);
       }
   }
 else
   {
     ai = (dx - dy) * 2;
     bi = dx * 2;
      d = bi - dy;

     while (y1 != y2)
       {
         if (d > 0)
            {
             x1 += xi;
              d += ai;
            }
           else
              d += bi;
             y1 += yi;
         PutPixel (x1, y1);
       }
   }


Ну а на ассемблере 6502 этот алгоритм реализуется следующим образом:
Code:
;----------------------------------
;--- Random Lines with ------------
;--- Bresenham's line algorithm ---
;   Click [Compile] and [  Run  ]
;----------------------------------
  *= $0010
l_dx:
  *= $0011
l_dy:
  *= $0012
l_xi:
  *= $0013
l_yi:
  *= $0014
l_ai:
  *= $0015
l_bi:
  *= $0016
l_d:
  *= $0017
l_x1:
  *= $0018
l_y1:
  *= $0019
l_x2:
  *= $001a
l_y2:
  *= $001b
l_XY:
  *= $001c
h_XY:
  *= $001d
rCOL:

  *= $0600
start:
  LDA #16;    Center
  STA l_x1;   X1 = 16
  STA l_y1;   Y1 = 16
loop:
  LDA $fe;    A = RND
  AND #$1F;   A <= 32
  STA l_x2;   X2 = RND <= 32
  LDA $fe;    A = RND
  AND #$1F;   A <= 32
  STA l_y2;   Y2 = RND <= 32
  LDA $fe;    A = RND
  STA rCOL;   COLOR = RND
  JSR line;   LINE(X1,Y1-X2,Y2)
  LDA l_x2;
  STA l_x1;   X1 = X2
  LDA l_y2;
  STA l_y1;   Y1 = Y2
  JMP loop

  *= $c100
line:
x1mx2:  LDA l_x1
  CMP l_x2;       x1 - x2
  BCC x1mx2_; if (x1 < x2)
  JMP x1wx2;else [x1 => x2]
x1mx2_:
;--------------  then [x1 < x2]
  LDA #1
  STA l_xi;   xi = 1;
  LDA l_x2
  SEC;    BORROW = 0
  SBC l_x1;   x2 - x1 - BORROW
  STA l_dx;   dx = x2 - x1
  JMP y1my2
;--------------  else [x1 => x2]
x1wx2: lda #255;     A = -1
  STA l_xi;    xi = -1; -> step_X
  LDA l_x1
  SEC;     BORROW = 0
  SBC l_x2;    x1 - x2 - BORROW
  STA l_dx;    dx = x1 - x2
;- deciding what direction to draw + steps
y1my2: ;   [y1 < y2]
;-- if
  LDA l_y1
  CMP l_y2;  if (y1 < y2)
  BCC y1my2_
  JMP y1wy2
y1my2_:
;-- then
  LDA #1;       A = 1;
  STA l_yi;    yi = 1; -> step_Y
  LDA l_y2
  SEC;     BORROW = 0
  SBC l_y1;    y2 - y1 - BORROW
  STA l_dy;    dy = y2 - y1
  JMP skok1
;-- else [y1 > y2]
y1wy2:
  LDA #255;      A = -1;
  STA l_yi;     yi = -1; -> step_Y
  LDA l_y1
  SEC
  SBC l_y2
  STA l_dy;     dy = y1 - x2
skok1:
;-- put first pixel
  JSR Pset; putpix(x1,y1);
;-- check 'primary axis' (longer distance)
  LDA l_dx
  CMP l_dy; if (dx>dy)  // (dy<dx)
  BCC wiod_oy
wiod_ox:
;-- solve ai
  LDA l_dy
  SEC
  SBC l_dx
  CLC
  ROL;        a
  STA l_ai;   ai = (dy-dx)*2
;-- solve bi
  LDA l_dy
  CLC
  ROL;        a
  STA l_bi;   bi = dy * 2
;-- solve d
  LDA l_bi
  SEC
  SBC l_dx
  STA l_d ;    d = bi - dx
;-- while (x1 != x2)
whx1rx2:
  LDA l_x1
  CMP l_x2
  BNE if_d
  JMP l_fin
if_d:
;-- if (d > 0)
  LDA l_d
  CMP #0
  BEQ _a
  BPL _else
;-- < 0
_a:
  LDA l_d
  CLC
  ADC l_bi
  STA l_d;     d += bi;
  JMP _reszta

;-- else [d>0]
_else:
  LDA l_y1
  CLC
  ADC l_yi
  STA l_y1;    y1 += yi;
  LDA l_d
  CLC
  ADC l_ai
  STA l_d;     d += ai;
;-- end else
_reszta:
  LDA l_x1
  CLC
  ADC l_xi
  STA l_x1;     x1 += xi;
;-- putpix(x1,y1);
  JSR Pset
  JMP whx1rx2; (petla while: )

wiod_oy:
;-- solve ai
  LDA l_dx
  SEC
  SBC l_dy
  CLC
  ROL;         a
  STA l_ai;    ai = (dx-dy)*2
;-- solve bi
  LDA l_dx
  CLC
  ROL ;a
  STA l_bi;    bi = dx * 2
;-- solve d
  LDA l_bi
  SEC
  SBC l_dy
  STA l_d;     d = bi - dy
why1ry2:
;----- while (y1 != y2)
  LDA l_y1
  CMP l_y2
  BNE if_nd
  JMP l_fin

if_nd:
;-- if (d > 0) then
  LDA l_d
  CMP #0
  BEQ _b
  BPL _elsey
_b:  ; <0
  LDA l_d
  CLC
  ADC l_bi
  STA l_d;      d += bi;
  JMP _resztay
;-- else [d > 0]
_elsey: ; >0
  LDA l_x1
  CLC
  ADC l_xi
  STA l_x1;     x1 += xi;
  LDA l_d
  CLC
  ADC l_ai
  STA l_d;       d += ai;
;-- end else
_resztay:
  LDA l_y1
  CLC
  ADC l_yi
  STA l_y1;      y1 += yi;

;-- putpix(x1,y1);
  JSR Pset
  JMP why1ry2
;-- The END --
l_fin:
  RTS

Pset:
  LDA l_y1
  ASL;      2* l_x1
  TAX;  X = 2* l_x1
  LDA offs,x
  INX
  CLC
  ADC l_x1
  STA l_XY
  LDA offs,x
  ADC #$02
  STA h_XY
  LDX #0
  LDA rCOL
  STA ($1B,X)
  RTS
offs:
  dcb $00,$00
  dcb $20,$00
  dcb $40,$00
  dcb $60,$00
  dcb $80,$00
  dcb $a0,$00
  dcb $c0,$00
  dcb $e0,$00
  dcb $00,$01
  dcb $20,$01
  dcb $40,$01
  dcb $60,$01
  dcb $80,$01
  dcb $a0,$01
  dcb $c0,$01
  dcb $e0,$01
  dcb $00,$02
  dcb $20,$02
  dcb $40,$02
  dcb $60,$02
  dcb $80,$02
  dcb $a0,$02
  dcb $c0,$02
  dcb $e0,$02
  dcb $00,$03
  dcb $20,$03
  dcb $40,$03
  dcb $60,$03
  dcb $80,$03
  dcb $a0,$03
  dcb $c0,$03
  dcb $e0,$03
;------end-------------------------


А результат работы этой программы - следующий:

------------Image

Самое интересное, как реализовать этот самый: PSET (x1, y1) или PutPixel (x1, y1) ...

На ассемблере 6502 я это сделал табличным методом и немного неоптимально сточки зрения
режимов адресации 6502.
Но суть вот какая: поскольку точке экрана соответствует 1 байт памяти, а размер экрана -
32х32 точки, и начало экранной области - в $0200, то от координат экрана, к адресам памяти
переходим по простой формуле ADDRxy = $0200 + Y *$20 + X.
Собственно, Y *$20 и вычисляется таблично для скорости.

А вот в графике "Специалиста" этот процесс чуть сложнее, поскольку на экране отображаются
отдельные биты каждого байта экранной области, и как с ними работают - я расскажу далее, раз
уж я завел речь о растровой графике в ветке ПК "Специалист"...

_________________
iLavr


19 Jan 2015 20:02
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Экранное ОЗУ ПК "Специалист" начинается с ячейки 9000Н (—28672) и заканчивается ячейкой
0BFFFH (—16385).
Каждому биту в случае монохромного экрана соответствует точка (1 — светлая, 0 — темная).

Image

Всего в строке выводится на экран 48 байт. Для того чтобы получить 64 символа в строке,
подпрограмма вывода символа на экран в матрице 5х7 (C037Н) уплотняет их по горизонтали.
В одном байтовом столбце - 256 байт по оси Y. А один байт - 8 графических точек по оси Х.

Таким образом, сдвигу на 8 бит по оси Х соответствует сдвиг на 256 байт от начала экрана - 9000H.
Содержимое экранного ОЗУ выводится на дисплей таким образом, что координата байта по оси Х
соответствует старшему байту адреса в машинном представлении, а координата Y — младшему байту.

Исходя из этих соотношений алгоритм вывода точки на экран следующий: по координате Х находим
адрес столбца экрана, прибавляем координату Y и находим нужный байт. В этом байте устанавливаем
(гасим) бит, номер которого слева указан в 3-х младших битах экранной координаты Х.

На ассемблере это выглядит следующим образом:
Code:
;--- PLOT X, Y, Z
PLOT:
  PUSH H;         Save HL
  LHLD X_c;       X-coord;
  PUSH H;         HL = X-coord;
  LXI  D,0FE80H ; DE = -384
  DAD  D;         HL = X - 384
  JC   ERR; ----- error: X > 384;
  POP  H;         HL = X-coord;
  MOV  A,L
  ANI  07H; 0000.0111b 8-lsb bits
  DAD  H; HL * 2
  DAD  H; HL * 4
  DAD  H; HL * 8
  DAD  H; HL * 16
  DAD  H; HL * 32
  LXI  D,9000H; Screen 1-st byte
  DAD  D; 9000H + HL * 32
  MOV  C,A
  LDA  Y_c;       Y-coord;
  MOV  L,A; HL - Byte at X,Y - coord;

  MVI  A,01H
SBT:RRC;    Set bit in Byte at X,Y - coord;
  DCR  C
  JP   SBT

  CALL PUT
  POP  H;         Restore HL;
  RET

PUT:MOV  C,A
  LDA  Z_p
  CPI  01H
  JZ   K01
  CPI  02H
  JZ   K02
  CPI  03H
  JZ   K03
  RET

K01:MOV  A,C; AND Screen BIT;
  CMA
  ANA  M
  MOV  M,A
  RET

K02:MOV  A,C; OR Screen BIT;
  ORA  M
  MOV  M,A
  RET

K03:MOV  A,C; XOR Screen BIT;
  XRA  M
  MOV  M,A
  RET

ERR:    ; error: X > 384;
  POP  H;         Restore HL;
  POP  H;         Restore HL;
  RET

X_c:DB   00H
  DB   00H
Y_c:DB   00H
Z_p:DB   02H

  END

_________________
iLavr


19 Jan 2015 20:51
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Ну и мне захотелось и с окружностями разобраться в растровом представлении...
А это также реализует Алгоритм Брезенхема построения окружности, и как везде пишут,
на алгоритм рисования линии он весьма похож, только в этом алгоритме строится дуга
окружности для первого квадранта, а координаты точек окружности для остальных
квадрантов получаются симметрично.
На каждом шаге алгоритма рассматриваются три пикселя, и из них выбирается наиболее
подходящий, путём сравнения расстояний от центра до выбранного пикселя с радиусом
окружности.

Image

При этом, естественно, отталкиваются от уравнения окружности: R^2 = X^2 + Y^2

Более подробно все выкладки можно посмотреть, к примеру, вот здесь...

А на языке Васик этот алгоритм выглядит даже довольно просто:
Code:
'--- "A Fast Bresenham Type Algorithm For Drawing Ellipses" by John Kennedy ---

     DEFINT A-Z

     SCREEN 12
px = 160
py = 120
 r = 100

 f = 1 - r
dx = 1
dy = -2 * r

 x = 0
 y = r

PSET (px, py - r)
PSET (px, py + r)
PSET (px - r, py)
PSET (px + r, py)

WHILE (x < y)

  IF (f >= 0) THEN
     y = y - 1
    dy = dy + 2
     f = f + dy
  END IF

   x = x + 1
  dx = dx + 2
   f = f + dx

  PSET (px + x, py + y)
  PSET (px + x, py - y)
  PSET (px - x, py - y)
  PSET (px - x, py + y)
  PSET (px - y, py + x)
  PSET (px - y, py - x)
  PSET (px + y, py - x)
  PSET (px + y, py + x)

WEND


Ну а теперь, как это реализовано на языке ассемблера внутри Васика нашего "Специалиста".
(Была у него такая добавочка CIRCLE, разобраться с которой у меня в свое время руки так и не дошли...)
Code:
;-----------------;
; CIRCLE  SP-580  ;
;-----------------;
  ORG  0000H

  JMP  START
RAD:DW   127;--- RADIUS
XPZ:DW   128;--- X-COORD.
Y_c:DB   128;--- Y-COORD.
X_c:DW   0000H
Z_p:DB   02H;--- OR with Screen Byte

START:
  MVI  A,1FH
  CALL 0F80FH
  CALL 0F80FH; Clear Screen
  LHLD RAD;  0=>R=>127
  DAD  H;    HL * 2
  DAD  H;    HL * 4
  DAD  H;    HL * 8
  DAD  H;    HL * 16
  DAD  H;    HL * 32
  DAD  H;    HL * 64
  DAD  H;    HL * 128
  DAD  H;    HL * 256
  DAD  H;    HL * 512
  XCHG;      HL<->DE
  LHLD XPZ;  0=>X=>511
  DAD  D;    HL = 512*R+X
  CALL CIR;
MT0:CALL 0C803H; KBD
  CPI  1BH;  ESC?
  JNZ  MT0;  NOT ESC...
  JMP  0F800H;  EXIT SYSTEM
  NOP
  NOP

K01:MOV  A,C; AND Screen BIT;
  CMA
  ANA  M
  MOV  M,A
  RET

K02:MOV  A,C; OR Screen BIT;
  ORA  M
  MOV  M,A
  RET

K03:MOV  A,C; XOR Screen BIT;
  XRA  M
  MOV  M,A
  RET

ERR:
  POP  H;         Restore HL;
  POP  H;         Restore HL;
  RET

M04:DB   00H;---- xx44h
  DB   00H
M05:DB   00H
  DB   00H
M06:DB   00H
  DB   00H
M07:DB   00H
  DB   00H
M08:DB   00H
  DB   00H
M09:DB   00H
  DB   00H
MASK:
  DB   00H;---- 1_1_1_1 1_1_1_1b

;-- PLOT X,Y,Z
PLOT:
  PUSH H;         Save HL
  LHLD X_c;       X-coord;
  PUSH H;         HL = X-coord;
  LXI  D,0FE80H ; DE = -384
  DAD  D;         HL = X - 384
  JC   ERR; ----- error: X > 384;
  POP  H;         HL = X-coord;
  MOV  A,L
  ANI  07H; 0000.0111b 8-lsb bits
  DAD  H; HL * 2
  DAD  H; HL * 4
  DAD  H; HL * 8
  DAD  H; HL * 16
  DAD  H; HL * 32
  LXI  D,9000H; Screen 1-st byte
  DAD  D; 9000H + HL * 32
  MOV  C,A
  LDA  Y_c;       Y-coord;
  MOV  L,A; HL - Byte at X,Y - coord;

  MVI  A,01H
SBT:RRC;    Set bit in Byte at X,Y - coord;
  DCR  C
  JP   SBT

  CALL PUT
  POP  H;         Restore HL;
  RET

PUT:MOV  C,A
  LDA  Z_p
  CPI  01H
  JZ   K01
  CPI  02H
  JZ   K02
  CPI  03H
  JZ   K03
  RET

; PLOT 512* R + X, Y, Z:' (0=>R=>63)
; PLOT -65536 + 512 * R + X, Y, Z:' (64=>R=>127)
; 0=>R=>127: 512 * 127 = 0FE00h
; 0=>X=>511: 511d = 1FFh - 1 byte + 1 hi bit.
; 0=>Y=>255
;
CIR:
  NOP;         HL = 512*R+X-coord;
  XRA  A;       A = 0; c = 0
  MOV  B,A;     B = 0;

  MOV  A,H;
  RAR;        c765.4321->0 - msb X
  MOV  C,A;   C = H/2 = R;

  MOV  A,B;     B = 0;
  RAL;        6543.210c<-7
  MOV  H,A;   xxx_.L - 0=>X=>511
  SHLD M04;

  MOV  H,B;   H = B = 0;
  MOV  L,C;   L = R; 0=>R=>127;
  SHLD M06;

  LDA  Y_c;   Y-coord: 0=>Y=>255;
  MOV  L,A;   H = B = 0; L = Y ;
  SHLD M05

  MOV  L,B;   L = B = 00h;
  SHLD M08;    = 0000h;
  SHLD M09;    = 0000h;
  DCR  H
  MOV  A,B
  SUB  C
  MOV  L,A
  SHLD M07

  DAD  H
  MVI  C,03H
  DAD  B

  PUSH H
M0B:LDA  MASK
  LXI  H,TB1;---
  CALL M0E
  POP  H

  PUSH H
  DAD  H
  LHLD M08
  JC   M0C
  XCHG
  LXI  H,M06
  DCR  M
  LHLD M07
  INX  H
  SHLD M07
  DAD  D
M0C:DAD  H
  DAD  H
  LXI  D,0006H;
  DAD  D
  POP  D

  DAD  D

  PUSH H
  LHLD M09
  DCX  H
  SHLD M09
  LXI  H,M08
  INR  M
  LDA  M06
  CMP  M
  JC   M0D

  PUSH PSW
  MOV  A,B
  LXI  H,TB2;---
  CALL M0E
  POP  PSW

  JNZ  M0B
M0D:POP  H
  NOP
  RET

M0E:RLC
  MOV  B,A
  MVI  C,04H
M0F:MOV  A,M
  STA  M10+1; mod. Addr.low;
  INX  H
  MOV  A,M
  STA  M11+1; mod. Addr.low;
  MOV  A,B
  RRC
  RRC
  MOV  B,A
  JC   M13
  PUSH H
;--------v low;
M10:LHLD M09
  XCHG
  LHLD M04
  DAD  D
  SHLD X_c
  LXI  D,0FE80H; -384;
  DAD  D
  JC   M12
;--------v low;
M11:LHLD M06
  XCHG
  LHLD M05
  DAD  D
  MOV  A,L
  STA  Y_c
  LXI  D,0FF00H; -256;
  DAD  D
  PUSH B
  CNC  PLOT; EQU  17D8H;
  POP  B
M12:POP  H
M13:DCR  C
  JNZ  M0F
  RET

  NOP
  NOP

TB1:DB   48H;
  DB   4EH;
  DB   4AH;
  DB   4CH;
TB2:DB   48H;
  DB   4CH;
  DB   4AH;
  DB   4EH;
  DB   48H;

  END

Сразу предупреждаю, что программа самомодифицирующаяся, и с другого адреса её запустить трудно,
поскольку в теле есть таблица, привязанная к конкретным смещениям.
Я смещения пересчитывать заленился и выровнял NOP-ами таблицу на подходящие адреса.

В результате получается вот что:

Image

Как я и говорил тут ранее:
Lavr wrote:
А у меня на зелёном венгерском мониторе "Орион" круг был просто идеальным!
...круг выходил совершенно правильным кругом на печать моим любимым принтером
тех времен - УВВПЧ. То есть имел место полный "ВизВиг"...


А на ассемблере 6502 код для рисования окружностей у меня вышел следующим:
Code:
;*******************************************
; Draw circles using Bresenham's algorithm *
;*******************************************

;--- ZP base address of data area
    *= $0020; Center Point X;
l_XC:
    *= $0021
h_XC:
    *= $0022; Center Point Y;
l_YC:
    *= $0023
h_YC:
    *= $0024; radius (1 byte)
lRAD:
    *= $0025
hRAD:
    *= $0026; plot point
l_XP:
    *= $0027;
h_XP:
    *= $0028;
l_YP:
    *= $0029;
h_YP:
    *= $002a;  x,y intermediate
l_X1:
    *= $002b;
h_X1:
    *= $002c;
l_Y1:
    *= $002d;
h_Y1:
    *= $002e;  difference
l_FF:
    *= $002f;
h_FF:
    *= $0030;  diff x
l_FX:
    *= $0031;
h_FX:
    *= $0032;  diff y
l_FY:
    *= $0033;
h_FY:
    *= $0034;
l_XY:
    *= $0035
h_XY:
    *= $0036
rCOL:

    *= $0600  ;
start:
  LDA #16;    Center low;
  STA l_XC;   XL = 16
  STA l_YC;   YL = 16
  LDA #0;     Center high
  STA h_XC;   XH = 00
  STA h_YC;   YH = 00
  STA hRAD;   RADH = 00
loop:
  LDA $fe ;   RND Radius low;
  AND #$0F;   A <= 15
  STA lRAD;   RND RADL = A <=15
  LDA $fe ;   A = RND;
  STA rCOL;   COLOR = RND;
  JSR CIRCLE; CIRCLE(XC,YC-lRAD)
  JMP loop;   jump CYCLE ;

; ----------------------------------
; CIRCLE: Draw a circle around the
; center XC/YC with radius in lRAD.
    *= $c000
CIRCLE:
  lda  lRAD     ; get Radius
  bne  _C1
  lda  l_XC    ; if lRAD=0, plot center point and exit
  sta  l_XP    ; move center point to plot point var
  lda  h_XC
  sta  h_XP
  lda  l_YC
  sta  l_YP
  lda  h_YC
  sta  h_YP
  jmp  PSET  ; Plot as a point and exit

;  int y = radius;
_C1:
  lda  lRAD    ; 8 bit radius - can be expanded to 16 bit
  sta  l_Y1
  ldx  #$00
  stx  h_Y1
; int  x = 0;
  stx  l_X1;
  stx  h_X1;
; if using 16 bit radius, this code
; section will need modifications
; int f = 1 - radius;
  sec
  lda  #$01
  sbc  lRAD
  sta  l_FF
  ldx  #$00
  stx  h_FF
  bcs  _C2
  dec  h_FF
; int ddF_x = 1;
_C2:
  lda  #$01
  sta  l_FX
  ldx  #$00
  stx  h_FX
; if using 16 bit radius, this code section
; will need modifications also
; int ddF_y = -2 * radius;
  stx  h_FY
  lda  lRAD
  asl      ; *2
  sta  l_FY
  rol  h_FY
  lda  l_FY
  EOR  #$FF
  sta  l_FY
  lda  h_FY
  EOR  #$FF
  sta  h_FY
  inc  l_FY
  bne  _C3
  inc  h_FY
;  tgi_setpixel(xC, yC + y);
_C3:
  lda  l_XC
  sta  l_XP
  lda  h_XC
  sta  h_XP
  clc
  lda  l_YC
  adc  l_Y1
  sta  l_YP
  lda  h_YC
  adc  h_Y1
  sta  h_YP
  jsr  PSET

;  tgi_setpixel(xC, yC - y);
  sec
  lda  l_YC
  sbc  l_Y1
  sta  l_YP
  lda  h_YC
  sbc  h_Y1
  sta  h_YP
  jsr  PSET

;  tgi_setpixel(xC + y, yC);
  clc
  lda  l_XC
  adc  l_Y1
  sta  l_XP
  lda  h_XC
  adc  h_Y1
  sta  h_XP
  lda  l_YC
  sta  l_YP
  lda  h_YC
  sta  h_YP
  jsr  PSET

;  tgi_setpixel(xC - y, yC);
  sec
  lda  l_XC
  sbc  l_Y1
  sta  l_XP
  lda  h_XC
  sbc  h_Y1
  sta  h_XP
  jsr  PSET

_CLOOP:
;  while (x < y) {    ; calculate next plot step
  sec
  lda  l_X1
  sbc  l_Y1
  lda  h_X1
  sbc  h_Y1
  bcc  _C4  ; x<y
  rts

_C4:
  lda  h_FF
  bmi  _C6

  lda  l_Y1
  bne  _C5
  dec  h_Y1
_C5:
  dec  l_Y1
  clc
  lda  l_FY
  adc  #$02
  sta  l_FY
  tax
  lda  h_FY
  adc  #$00
  sta  h_FY
  tay
  clc
  txa
  adc  l_FF
  sta  l_FF
  tya
  ADC  h_FF
  sta  h_FF

_C6:
  inc  l_X1
  bne  _C7
  inc  h_X1
_C7:
  clc
  lda  l_FX
  adc  #$02
  sta  l_FX
  tax
  lda  h_FX
  adc  #$00
  sta  h_FX
  tay
  clc
  txa
  adc  l_FF
  sta  l_FF
  tya
  ADC  h_FF
  sta  h_FF
; computations done - now plot 8 Octants

; tgi_setpixel(xC + x, yC + y);
  clc
  lda  l_XC
  adc  l_X1
  sta  l_XP
  pha
  lda  h_XC
  adc  h_X1
  sta  h_XP
  pha
  clc
  lda  l_YC
  adc  l_Y1
  sta  l_YP
  lda  h_YC
  adc  h_Y1
  sta  h_YP
  jsr  PSET

; tgi_setpixel(xC - x, yC + y);
  sec
  lda  l_XC
  sbc  l_X1
  sta  l_XP
  lda  h_XC
  sbc  h_X1
  sta  h_XP
  jsr  PSET

; tgi_setpixel(xC - x, yC - y);
  sec
  lda  l_YC
  sbc  l_Y1
  sta  l_YP
  lda  h_YC
  sbc  h_Y1
  sta  h_YP
  jsr  PSET

; tgi_setpixel(xC + x, yC - y);
  pla
  sta  h_XP
  pla
  sta  l_XP
  jsr  PSET

; tgi_setpixel(xC + y, yC + x);
  clc
  lda  l_XC
  adc  l_Y1
  sta  l_XP
  pha
  lda  h_XC
  adc  h_Y1
  sta  h_XP
  pha
  clc
  lda  l_YC
  adc  l_X1
  sta  l_YP
  lda  h_YC
  adc  h_X1
  sta  h_YP
  jsr  PSET

; tgi_setpixel(xC - y, yC + x);
  sec
  lda  l_XC
  sbc  l_Y1
  sta  l_XP
  lda  h_XC
  sbc  h_Y1
  sta  h_XP
  jsr  PSET

; tgi_setpixel(xC - y, yC - x);
  sec
  lda  l_YC
  sbc  l_X1
  sta  l_YP
  lda  h_YC
  sbc  h_X1
  sta  h_YP
  jsr  PSET

; tgi_setpixel(xC + x, yC - y);
  pla
  sta  h_XP
  pla
  sta  l_XP
  jsr  PSET
  jmp  _CLOOP

; ------------------------------------------------
; PSET: Test pixel @ XP,YP and plot it on screen
PSET:
  LDA l_YP
  ASL;      2* l_YP ;
  TAX;  X = 2* l_YP ;
  LDA offs,x
  INX
  CLC
  ADC l_XP
  STA l_XY
  LDA offs,x
  ADC #$02
  STA h_XY
  LDX #0
  LDA rCOL
  STA ($34,X)
  RTS
offs:
  dcb $00,$00
  dcb $20,$00
  dcb $40,$00
  dcb $60,$00
  dcb $80,$00
  dcb $a0,$00
  dcb $c0,$00
  dcb $e0,$00
  dcb $00,$01
  dcb $20,$01
  dcb $40,$01
  dcb $60,$01
  dcb $80,$01
  dcb $a0,$01
  dcb $c0,$01
  dcb $e0,$01
  dcb $00,$02
  dcb $20,$02
  dcb $40,$02
  dcb $60,$02
  dcb $80,$02
  dcb $a0,$02
  dcb $c0,$02
  dcb $e0,$02
  dcb $00,$03
  dcb $20,$03
  dcb $40,$03
  dcb $60,$03
  dcb $80,$03
  dcb $a0,$03
  dcb $c0,$03
  dcb $e0,$03
;------end-------------------------


И в результате работы этого кода получаются вот такие результаты: :wink:

------------Image

_________________
iLavr


19 Jan 2015 21:31
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
Lavr , мы внимательно следим за всем этим. :wink:

Как считаете, если организация экранной области идёт как бы "задом наперёд" по отношению к нашему старому доброму "Специалисту" ,то есть левая колонка 0FEFFh ,следующая 0FDFFh и т.д. на уменьшение по 256 байт на колонку ,то подойдёт алгоритм товарища Брезенхема и в таком случае , так ведь ?

Что там придётся изменить, в тексте для асм8080 не затруднит ли подчеркнуть.. :roll:


20 Jan 2015 01:16
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
petrenko wrote:
Как считаете, если организация экранной области идёт как бы "задом наперёд" по отношению к нашему старому доброму "Специалисту" ,то есть левая колонка 0FEFFh ,следующая 0FDFFh и т.д. на уменьшение по 256 байт на колонку ,то подойдёт алгоритм товарища Брезенхема и в таком случае , так ведь ?

Алгоритм Брезенхема подойдет в любом случае, поскольку он одинаков для всех организаций экрана,
он работает до экранных координат X и Y.
Ну а дальше должна быть конкретная реализация аппаратно-зависимой функции установки точки по
адресу в видео-ОЗУ - PLOT, PSET или PutPixel.

Здесь не очень много сказано про организацию. Но я так понимаю, что есть максимальный адрес начала
экрана и на каждые 8 бит по Х идет уменьшение на 265 байт по Y.
Я полагаю, что в функции PLOT после умножения на 32 результат надо вычитать от базового.
То есть дополнение до единицы и сложение с базовым - как-то так я представляю это.

_________________
iLavr


20 Jan 2015 06:13
Profile
Doomed

Joined: 10 Mar 2012 16:21
Posts: 598
Location: РФ
Reply with quote
Post 
Ага, как то так тоже подумал.

И я уточнял именно за реализацию, на асм для 8080 :idea:

И наверное есть варианты переделать модуль в адресно-независимый ( что вообще то для 8080 всегда было затруднением ).

Ну и быстродействие тоже важно для столь медленной системы, в этом смысле смущают в первую очередь CALL ,сразу хочется заменить их на макросы например.


20 Jan 2015 07:07
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 16 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 10 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:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.