|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
Геометрия экрана "Специалист"
Author |
Message |
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А в "Орионе" - 2.5МГц и тоже натянуто на ту же сетку частот и тот же арбитр...
Как же так по-разному получилось? При фактически идентичной схемотехнике?
_________________ iLavr
|
01 Oct 2013 10:16 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Вот я подчеркнутую мысль и высказал, собственно говоря:
Если посмотреть расчет - то в параметры стандарта там всё очень четко уложено,
чего не скажешь об "Орионе".
И про какие "исправления аспекта" можно говорить, когда у "Ориона" экран заужен
при тех же изначальных 384х256?
Ну и вопрос я свой адресовал-таки нашему авторитетному источнику - PNP - чтобы
услышать, как оно было на сАмом деле...
А то мы много тут чего предполагали, а он нас покритиковал чутка...
Так что - просто хотелось бы узнать правду от человека, близкого к первоисточнику.
_________________ iLavr
|
02 Oct 2013 05:12 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А у меня на зелёном венгерском мониторе "Орион" круг был просто идеальным!
Огорчу тебя также тем, что круг выходил совершенно правильным кругом на печать
моим любимым принтером тех времен - УВВПЧ.
То есть имел место полный "ВизВиг"...
Так что это у тебя с телевизором что-то не тоё было...
_________________ iLavr
|
02 Oct 2013 15:43 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
В результате огорчился не он, а я, поскольку не могу никак подобрать систему, в которой 384 поделённое на 256 будет равно 4/3 ...
В известных мне системах почему то 384/256==3/2 .. Странно.
Может в разных школах разные математики ?
А правду говорят, что в СССР была СЕКАМ и из 625 строк полного кадра видимыми должны были быть 525 ? А в полукадре соответственно 262. 5 строк видимых ?
А то может и справочники разные..
Вот который я читал, в том про черезстрочную кадровую развёртку 50Гц~~20мс-полукадр, 25Гц~~40мс-полный кадр и строчную частоту 15625Гц что то написано, а в каком другом справочнике может всё и по другому..
|
02 Oct 2013 21:52 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
Ну вот я опять огорчился. У нас в начальной ( и средней ) школе вообще никогда не делили цифры. Делили только числа.( ибо "цифра есть значок, употребляемый для записи чисел", а "число есть абстрактная форма записи некоего реального количества". - согласно определению из учебника.. ) А вот если умножить не на 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 пиксела ( тоже придётся округлять ) Со строками всё вполне даже ясно.
В полном кадре 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 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
Совершенно верно, именно полагая экран плоским и "правильным".
Чисто математически идеализируя, то есть.
В реале, понятное дело, надо будет ещё много чего учитывать.
Не знаю, как там в ВУЗ ( у меня неполное среднее, если что.. ), но в школе учили делить некие неизвестные величины, абстрактно изображаемые буквами.
Но сами буквы можно делить разве что на чёрточки и точечки, из которых они и составляются.
Вот как то так..
Вы уж извините, ежели я не в курсе последних достижений британских "уч оных"
Last edited by petrenko on 03 Oct 2013 00:11, edited 1 time in total.
|
02 Oct 2013 23:45 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
"Вау" тута усе такие грамотные, просто жуть..
Куда уж там нам с неполным средним образованием, да постигать сложнейшие тайны..
Зато я теперь знаю, с чего начинаются форумные"мега-холивары"- они начинаются с зашкаливающей грамотности всех участвующих в оных оппонентов.
Всем удачи в освоении компьютера "Фах³вець-85" !
( если кому нужны консультации по арифметике в рамках начальной школы - пожалуйста - можете обращаться, мало ли кто после двух - трёх В.У.З. забыл что-нибудь, ну или без калькулятора перемножить или разделить не сможет - поможем, чем можем, мы люди простые, добрые.. )
|
03 Oct 2013 00:05 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
Не волнуйтесь, я очень добрый, на коллег не обижаюсь.
Просто у меня своеобразное чувство юмора..
А вот без этого самого юмора и вправду можно было бы свихнуться от любой мелочи, хоть даже и от отсутствия "умляута" над "ё"
А то, что простые люди иногда что-нибудь могут перепутать - так не всем же повезло с учителями. Вот в одной стране главный ( ГБ-шник кстати ) и тот называет"цифру инфляции" , и ничего - терпим..
По теме : несколько не соответствующие соотношению 4 к 3 графические контроллеры многих ЛК - это компромисс, упрощающий организацию счётчиков. "Правильные" контроллеры графического дисплея я видел, но они во-первых сами сложнее, а во-вторых требуют более мало-доступного устройства отображения, нежели бытовой телевизор.
|
03 Oct 2013 02:14 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А мне кажется это ты всегда мимо кассы... но что бы не спорить, я соглашусь - пусть у HardWareMan всё самое лучшее, ну а у меня - такое, какое уж было:
Вероятно потому как одним было влом подстраивать, а другие просто работали за
хорошим монитором.
_________________ iLavr
|
03 Oct 2013 04:04 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Поскольку у меня заработал он-лайн эмулятор 6502, я занялся программированием на ассемблере
этого процессора. Ну и поскольку, кроме графического экранчика 32х32 точки на 16 цветов в этой
системе устройств практически нет, пришлось вспомнить примитивы растровой графики...
Линии круги и более сложные кривые на растровом устройстве помогают отрисовать Алгоритмы Брезенхема.
Ну и линию отрисовывает Bresenham's line algorithm, суть которого в двух словах заключается в том,
что, поскольку в растровой графике линия аппроксимируется ломаной линией по пикселям, то закрашивается
тот пиксель растра,среднеквадратичное отклонение которого от линии наименьшее.
Алгоритм Брезенхема интересен тем, что работает в целых числах, не нуждается в сложных операциях, а основная
хитрость его заключается в удвоении отклонения, в результате чего в целых числах становится уверенно различимым.
Этот алгоритм я ещё давно реализовывал с помощью одной хорошей книжки по графике, и на языке Васик этот
алгоритм выглядит примерно следующим образом:
| | | | 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 | | | | |
На языке С алгоритм можно воплотить примерно вот так: Ну а на ассемблере 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------------------------- | | | | |
А результат работы этой программы - следующий:
------------
Самое интересное, как реализовать этот самый: 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 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Экранное ОЗУ ПК "Специалист" начинается с ячейки 9000Н (—28672) и заканчивается ячейкой
0BFFFH (—16385).
Каждому биту в случае монохромного экрана соответствует точка ( 1 — светлая, 0 — темная).
Всего в строке выводится на экран 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 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Ну и мне захотелось и с окружностями разобраться в растровом представлении...
А это также реализует Алгоритм Брезенхема построения окружности, и как везде пишут,
на алгоритм рисования линии он весьма похож, только в этом алгоритме строится дуга
окружности для первого квадранта, а координаты точек окружности для остальных
квадрантов получаются симметрично.
На каждом шаге алгоритма рассматриваются три пикселя, и из них выбирается наиболее
подходящий, путём сравнения расстояний от центра до выбранного пикселя с радиусом
окружности.
При этом, естественно, отталкиваются от уравнения окружности: 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-ами таблицу на подходящие адреса. В результате получается вот что: Как я и говорил тут ранее: А на ассемблере 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------------------------- | | | | |
И в результате работы этого кода получаются вот такие результаты:
------------
_________________ iLavr
|
19 Jan 2015 21:31 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
Lavr , мы внимательно следим за всем этим.
Как считаете, если организация экранной области идёт как бы "задом наперёд" по отношению к нашему старому доброму "Специалисту" ,то есть левая колонка 0FEFFh ,следующая 0FDFFh и т.д. на уменьшение по 256 байт на колонку ,то подойдёт алгоритм товарища Брезенхема и в таком случае , так ведь ?
Что там придётся изменить, в тексте для асм8080 не затруднит ли подчеркнуть..
|
20 Jan 2015 01:16 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Алгоритм Брезенхема подойдет в любом случае, поскольку он одинаков для всех организаций экрана,
он работает до экранных координат X и Y.
Ну а дальше должна быть конкретная реализация аппаратно-зависимой функции установки точки по
адресу в видео-ОЗУ - PLOT, PSET или PutPixel.
Здесь не очень много сказано про организацию. Но я так понимаю, что есть максимальный адрес начала
экрана и на каждые 8 бит по Х идет уменьшение на 265 байт по Y.
Я полагаю, что в функции PLOT после умножения на 32 результат надо вычитать от базового.
То есть дополнение до единицы и сложение с базовым - как-то так я представляю это.
_________________ iLavr
|
20 Jan 2015 06:13 |
|
|
petrenko
Doomed
Joined: 10 Mar 2012 16:21 Posts: 598 Location: РФ
|
Ага, как то так тоже подумал.
И я уточнял именно за реализацию, на асм для 8080
И наверное есть варианты переделать модуль в адресно-независимый ( что вообще то для 8080 всегда было затруднением ).
Ну и быстродействие тоже важно для столь медленной системы, в этом смысле смущают в первую очередь CALL ,сразу хочется заменить их на макросы например.
|
20 Jan 2015 07:07 |
|
|
Who is online |
Users browsing this forum: No registered users and 5 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
|
|