Прав, но хотел скомпилировать именно с помощью tasm-а
Спасибо.Цитата:
Сообщение от ivagor
Вид для печати
А я сам покритикую рыбу hello world. Для учебного примера возможно стоит вывод символов сделать попроще, без стека и необходимости запрещать прерывания.
Если отвлечься от рыбы и принять, что программа будет загружаться в магнитофонный загрузчик, то можно обойтись без прерываний и без программирования палитры. Только надо рисовать в плоскости C000-DFFF. Есть даже примеры игрушек, сделанных в таком стиле.
Да уж, опечаток в тесте есть немного ) в использовании меток и не только, но скомпилировалось )
Работать правда не заработало, но это уже буду вечером смотреть, что не так.
УРАААААААААА!!! )))) Какая прелесть, оно заработало! )))) И еще пищит сволочь ))))
Для тех кто будет повторять ORG 1800h замените на ORG 100h , дело было не в этом, я просто как обычно через одно место попытался запустить, но просто напоминаю, что при запуске как обычное приложение нужно править исходник.
Компиляция tasm32 с ключём -i
Всем спасибо.
Что-то криво вставился правленный исходник Секретов Вектора под спойлер, поэтому приаттачиваю архив со всем необходимым для компиляции (win10 x64 полет нормальный).
Еще раз всем спасибо кто помогал разбираться с поставленной задачей.
Что до использования стека, тут соглашусь, но мне лень переделывать то, что работает. Хотя вообще это все-таки не учебник, а просто на Векторе нет принципиально более легкого способа написать HELLO WORLD. Выбрасывать программирование палитры в Векторовских реалиях — это какое-то тяжкое зло. Исторически неказистые игры уж точно не пример для подражания. Наоборот лучше дополнить рыбу и вместо слегка зашифрованного кода set_palette, который там сейчас, сделать пример, в котором очевидным образом задаются значения R, G, B.
Чтобы были нули в неиспользуемых местах (DS или если текущий адрес через ORG сдвигается).
-f0 не особо нужен, по умолчанию tasm заполняет "пустые" места нулями.
Командная строка осталась ещё со времён ДОСовского варианта, наверное уже не нужно. Вопрос в том, как винда выделяет память. У меня в эмуле тоже насильно не обнуляется, но почти вся память в эмулируемом компе забита нулями, кроме первых нескольких байт.
- - - Добавлено - - -
Данная опция полезна для ПЗУ, можно неиспользуемые места забивать байтом FF.
Кто знает, есть ли в Векторе скрытые регистры, которые можно использовать как ячейки памяти?
В которые можно было-бы записать произвольные значения.
Например можно-ли остановить ВИ53 и использовать регистры каналов как 6 Байт памяти?
KTSerg, часы реального времени, например, на КР512ВИ1 имеют 50байт памяти, но вот только эти сами часы на Векторе практически не встречаются.
Вроде бы в эту тему.
Допустим, я хочу написать жутко динамическую игру.
Для этого я собираюсь использовать под игровое поле поочерёдно то план 0 то план 1, план 2 скажем будет под индикаторы, план 3 не показывается.
Включать/выключать планы 0/1 я собираюсь конечно палитрой.
Вопрос - как это правильно организовать?
Правильно ли я понимаю, что цикл игры должен завершаться hlt и затем сразу установка палитры - переключение планов.
Или же лучше поместить включение нужной палитры прямо в прерывание, сразу после установки режимов дисплея?
Или можно и так и так?
Можно и так и так. Немного капитанства - если программирование палитры в основном обработчике прерываний, но реально все время программировать палитру 50 раз в секунду не нужно, организуем флаг необходимости программирования палитры и проверяем его в обработчике (или jmp с модифицируемым адресом).
Спасибо.
Процессор работает на частоте 3 МГц, получается на один фрейм 60000 циклов процессора - или меньше?
Где можно посмотреть табличку циклов процессора по операциям?
По поим наблюдениям, очистка одного плана экрана через push занимает больше одного фрейма - это норм или я накосячил?
В заводском мануале Вектора по Ассемблеру. Почему именно там, а не, скажем, в интеловском даташите по i8080 - в Векторе процессор работает не на полной скорости из-за особенностей доступа к шине видеоконтроллера, и поэтому длительность исполнения команд на Векторе считается именно в циклах (каждый из который равен какому-то количеству тактов).
312 строк*192 такта=59904 такта/фрейм.
Например здесь в вектор-user 15, правда там есть пара-тройка опечаток. Где-то был исправленный вариант, кажется svofski выкладывал (не в картотеке).
Если полностью развернуть цикл очистки (что конечно не стоит делать), получится 16 тактов*4096 команд=65536 тактов, т.е. немного больше длительности фрейма.
Речь вот об этой табличке: https://github.com/svofski/vector06c...uction_Timings
Пытаюсь сократить свою демку (для ДЕМОДУЛЯЦИЯ 2021 - нужно не больше 256 байт) и вот дошёл до программирования палитры цветов.
Вот установка палитры из программы прерываний (взято у Лебедева из "Секреты Вектора")
Что можно в ней сократить ?
В основном я имею ввиду команду OUT 0CH
поскольку у Лебедева 8 раз прописана OUT 0CH (для надёжности т.к. некоторые Векторы имели плохую запись в ОЗУ цветогенератора)
в тоже время у Черезова всего лишь 3 раза OUT 0CH
а просматривая исходники других авторов я видел даже 2 раза OUT 0CH
Эмулятор и с одного раза OUT 0CH пишет как надо. Но не знаю на ДЕМОДУЛЯЦИИ на чём будут запускать - на реальном Векторе или на эмуляторе.
Где золотая середина ? :)
;========================
MVI A,88H
OUT 00H
LXI H,COLR15 ; ЗАПИСЬ ПАЛИТРЫ.
LXI D,100FH ; d=16 e=15
INIT1: MOV A,E
OUT 02
MOV A,M
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
OUT 0CH
DCX H
OUT 0CH
DCR E
OUT 0CH
DCR D
OUT 0CH
JNZ INIT1
mvi a,15 ; УСТАНОВКА ЦВЕТА БОРДЮРА
OUT 02
;========================
Ещё вопрос, что будет если квазидиск подключен, а в коде вот этих начальных настроек нету, будет ли это мешать исполнению программы ?
XRA A ;ВЫКЛ. ОЗУ КВАЗИДИСКА.
OUT 10H
Если глянуть исходники МДОС Т-72, то там палитру тоже устанавливали за два раза, но между ними была небольшая задержка:
Думаю, такой вариант можно считать оптимальным и по скорости, и по объёму.Код:...
L_F613: OUT 00Ch ; палитра -- установка физического цвета
PUSH PSW
POP PSW
PUSH PSW
POP PSW
DCR E
DCR D ; (счётчик -1)
OUT 00Ch ; палитра -- установка физического цвета, ещё раз
...
Все ПЗУ на Векторах, как правило, имели при запуске команду отключения КД. Кроме того, квази-диск отключает БЛК-СБР -- там это сделано аппаратно, таким образом, если демку будут запускать, например, загрузкой "с ленты", или из загрузочной записи дискеты, то можно этот момент пропустить, а если из под МДОСа -- то эти команды обязательны.
но это вариант "общего назначения", в микродеме как правило можно еще сократить за счет трюков.Код:SetPal:
lxi h,COLR15
mvi e,15
SetPalLoop:
mov a,e
out 2
mov a,m
out 0Ch
xthl
xthl
dcx h
dcr e
mov a,a
out 0Ch
jp SetPalLoop
Improver, ivagor спасибо !!
ivagor, а какое назначение команд xthl и mov a,a ? Это чтобы просто паузу создать между двумя out 0Ch ?
Да, нужно обойти "зоны непрограммируемости". Если временно отвлечься от темы оптимизации по размеру, то есть и оптимальный по скорости вариант, там для каждого цвета out 0Ch только один раз.
Для сокращения кода хочу убрать следующие команды при инициализации программы
;MVI A,0C3H ; установить переход (код команды JMP) в
;STA 0038H ; адрес вызова прерывания.
;LXI H,INIT ;УСТАНОВКА ВЕКТОРА ПРЕРЫВАНИЯ.
;SHLD 0039H
Допустимо ли такой вариант ORG 0031h ?
Пока что у меня чёрный экран выходит.
;==================================
ORG 0031h
STRINT: DI
LXI SP,7E03h ;100H
jmp Progrm
;=================================== обработка прерываний
INIT:
PUSH PSW
.......................
POP PSW
EI
RET ; выход из прерываний
;================================================= СТАРТ ПРОГРАММЫ
Progrm:
EI
lxi h, 0e000h ; куда в экран
...............
;==================================
С ORG 0031h это вопрос скорее к организаторам конкурса, какие векторовские форматы они принимают и как (откуда) будут запускать демы. Если допустима загрузка с магнитофонного входа, то стартовый адрес д.б. кратен 256 байтам. Если запуск из доса, то два варианта - или 100h (com/rom) или, если с "запускалкой", r0m (согласны ли организаторы использовать запускалку?). Грузить с (более-менее) произвольного адреса можно в монитор-отладчик или, например, эмулятор РК/Микроши. Опять же - организаторы согласны на это? И, кстати, если грузить в монитор отладчик затирая вектор прерываний, то это скорее всего закончится не вполне хорошо.
Не назвал бы это трюком, я несколько о другом.
Например можно расположить палитру в памяти с адреса кратного 256 (100h) и тогда не нужен отдельный счетчик цветов (тут я не обязательно про дему в 256 байт). Убираем mvi e,15; dcr e; меняем dcx h на dcr l. Можно этот трюк модифицировать и для некоторых других адресов. Подобные придумки перечислить в рамках форумного поста вряд ли возможно.
Вопрос и простой и сложный одновременно... Трюков, вроде, не так много, но определённого их сборника или каталога нет, перечислять их тут -- как написать книгу. :) Попробуйте посмотреть в каталоге Базис периодические и электронные издания: Вектор-User, Байт, Scaner, InVector и др., там встречалось много советов по программированию, и спрашивайте конкретные моменты тут, посоветуем, как лучше.
Ответ можно разбить на две части: собственно программные трюки под конкретный проц - раз; учет аппаратных особенностей компа - два.
8080, конечно, не совсем Z80, но кое-какие мысли изложу, а что подойдет для Вектора - кодерам под 8080 виднее.
Именно для компактности кода, а не скорости исполнения, забываем про развернутые циклы и подобные "бусты" на скорость.
Начинаем с выравнивания кода и данных по "ровным" HEX-адресам, а также циклов (с некоторыми допущениями).
Для циклов это избавит в части случаев от задания количества повторов цикла в регистре, либо сверки его с конкретным числом.
Например, заполняем некую область данными, при этом на старте HL=#XX00, нам нужно забить 100/128/200 байт. Ниже коды Z80, но общий смысл, думаю, будет понятен.
Можно организовать цикл на 100 (или сколько там) повторений, а можно просто увеличивать регистр L, пока он не обнулится. То бишь конструкцией вида INC L: JR NZ,repeat.
Аналогично, проверяя аккумулятор через ротацию и зная, какое число в нем было изначально (для Z80 можно и любой регистр), можно сделать нужный счетчик.
Например, нам нужен цикл с повторением 4 (либо с реакцией на каждый 4-й проход), при этом сам счетчик даже необязательно перезагружать.
Для этого в аккумулятор грузим #88 (%10001000 бинарно), а в программе циклически сдвигаем (RRCA или как там у 8080 пишется) и делаем переход/нужное по флагу переноса.
Флаг этот будет устанавливаться каждый четвертый проход, при этом "счетчик" будет самовосстанавливаться. Таким же путем делаются счетчики на 2 и 8, числами #AA и #80.
Учитывая аппаратные особенности конкретного компа (строение экрана, например), можно тоже сокращать код. Особенно часто это делается на Спектруме с его хитрым экраном.
Выше уже писали насчет палитр Вектора, вот как раз на эту тему.
Спасибо за этот сниппет. Очень класный.
Вот мой вариант который может тищить данные с квазидиска и сетить палитру без отключения прерываний. За основу был взят приведенный тобой код.
Код:; Set palette copied from the ram-disk no blocking interruptions
; input:
; de - the addr of the first item in the palette
; use:
; hl, bc, a
PALETTE_COLORS = 16
SetPaletteFromRamDisk:
hlt
; store sp
lxi h, $0000
dad sp
shld @restoreSp+1
; copy unpacked data into the ram_disk
xchg
RAM_DISK_ON()
sphl
mvi a, PORT0_OUT_OUT
out 0
mvi e, $00
@loop:
pop b
; even color
mov a, e
out 2
mov a, c
out $0c
xthl ; delay 24
xthl ; delay 24
inr e ; counter plus delay 8
inr h ; delay 8
dcr h ; delay 8
out $0c
; odd color
mov a, e
out 2
mov a, b
out $0c
xthl ; delay 24
xthl ; delay 24
inr e ; counter plus delay 8
inr h ; delay 8
dcr h ; delay 8
out $0c
mov a, e
cpi PALETTE_COLORS
jnz @loop
@restoreSp: lxi sp, TEMP_ADDR
RAM_DISK_OFF()
ret
.closelabels
; mount the ram-disk
.macro RAM_DISK_ON(_command = RAM_DISK0_B0_STACK)
mvi a, _command
out $10
.endmacro
; dismount the ram-disk
.macro RAM_DISK_OFF()
xra a
out $10
.endmacro
Какие алгоритмы в реальности используются, для вывода на экран спрайта (многоцветного) с маской?
Или сначала в буфере создается микс (фона и спрайта), который потом просто копируется на экран?
Тогда интересует алгоритм создания микса.
Я таким ни когда не занимался, прикинул, цикл получился (если правильно посчитал) 112 тактов на байт :(
Скрытый текст
Код:...
adr:
ldax b
ana m
xchg
ora m
xchg
mov m,a
inx h
inx d
inx b
adr_a:
mvi a,8
dcr a
sta adr_a+1
jnz adr
...
[свернуть]
Вывод в одну плоскость что-то вроде
с использованием стека
Код:;SP - маска, байт спрайта, маска, байт спрайта, ...
;HL - VRAM
pop b\ mov a,m\ ana c\ ora b\ mov m,a\ dcr l
;12+8+4+4+8+8=44 такта/байт
[свернуть]
без стека
Код:;HL - маска, байт спрайта, маска, байт спрайта, ...
;DE - VRAM
ldax d\ ana m\ inx h\ ora m\ inx h\ stax d\ dcr e
;8+8+8+8+8+8+8=56 тактов/байт
[свернуть]
Вместо dcr l и dcr e могут быть другие dcr или inr, смотря как выводим. Если две плоскости, то просто используем оставшуюся регистровую пару (DE или BC соответственно). Для 3-4 плоскостей придется добавлять переходы.
Не все так плохо.
По битпланам без стека
Код:;HL - маска
;DE - спрайт
;BC - VRAM
ldax b\ ana m\ inx h\ xchg\ ora m\ inx h\ xchg\ stax b\ dcr c
;8+8+8+4+8+8+4+8+8=64 такта/байт
[свернуть]
После каждого битплана отматываем маску на начало.
Или
В два битплана стеком
Код:;SP - маска, байт спрайта, байт спрайта, маска, байт спрайта, байт спрайта, ...
;HL и DE - VRAM
;начало
pop b\ mov a,m\ ana c\ ora b\ mov m,a\ dcr l
ldax d\ ana c\ pop b\ ora c\ stax d\ dcr e
;установившийся режим
dcx sp\ pop b\ mov a,m\ ana c\ ora b\ mov m,a\ dcr l
ldax d\ ana c\ pop b\ ora c\ stax d\ dcr e
;(12+12+8+4+4+8+8)+(8+4+12+4+8+8)=100 тактов/2 байта=50 тактов/байт
[свернуть]
Такой вариант я раньше привел
У двухбитпланового стекового варианта есть серьезный недостаток - несовместимость с методом Медноногова, нельзя использовать при разрешенных прерываниях. Исправление этого недостатка + небольшое ускорение:
Скрытый текст
Код:;SP - маска, байт спрайта, байт спрайта, маска, байт спрайта, байт спрайта, ...
;HL и DE - VRAM
pop b\ mov a,m\ ana c\ ora b\ mov m,a\ dcr l
ldax d\ ana c\ pop b\ ora c\ stax d\ dcr e
;12+8+4+4+8+8+8+4+12+4+8+8=88 тактов
mov a,b\ sta $+10\ ana m\ pop b\ ora c\ mov m,a\ dcr l
ldax d\ ani 0\ ora b\ stax d\ dcr e
;8+16+8+12+4+8+8+8+8+4+8+8=100 тактов
;(88+100)/4=47 тактов/байт
[свернуть]
ivagor, пора книгу писать с фрагментами программ для вектора. Ну или в вики хотя бы выписывать - был бы отличный справочник, меньше затыков при разработке под Вектор.
Можно вот тут например собирать: http://www.emuverse.ru/wiki/%D0%9A%D...D1%80-06%D0%A6