PDA

Просмотр полной версии : Общая тема для моих вопросов (ассемблер и zx spectrum)



moronizzz
20.07.2016, 20:36
Здравствуйте,

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

* Есть ли хорошая книга и внятная статья по работе со screen memory (как в желаемом месте желаемым цветом нарисовать точку)? Есть ли простой способ определить адрес какой-то точки на экране?

Я уже частично понял суть, нарисовал линию из восьми писелей:



ORG #8000
ld hl, #5920 ; адрес атрибутов для строки #4820
ld a, %01000100 ; первый бит - мерцание, второй бит - яркость, три бита бумага, три бита чернила.
ld (hl), a ; загрузили атрибуты цвета для строки
ld de, #4820 ; это адрес начала строки
ld a, %11111111 ; это какие пиксели заполнены
ld (de), a ; выводим символы
ret


Но "придумывать" как это работает приходится самому на основе http://www.animatez.co.uk/computers/zx-spectrum/screen-memory-layout/ и http://speccy.info/%D0%9F%D0%B5%D1%87%D0%B0%D1%82%D1%8C_%D1%82%D0%B5% D0%BA%D1%81%D1%82%D0%BE%D0%B2%D0%BE%D0%B9_%D1%81%D 1%82%D1%80%D0%BE%D0%BA%D0%B8_%D1%88%D1%80%D0%B8%D1 %84%D1%82%D0%BE%D0%BC_8%D1%858_%D1%81/%D0%B1%D0%B5%D0%B7_%D0%B0%D1%82%D1%80%D0%B8%D0%B1% D1%83%D1%82%D0%BE%D0%B2

* Я компилирую код при помощи pasmo (pasmo -d -v --bin zzz.z80 zzz.bin), после этого создаю tap с загрузчиком при помощи bin2tap (./bin2tap -b zzz.bin) (почему-то .tap с загрузчиком, получаемый из pasmo у меня работает некорректно). При загрузке полученного .tap в fuse-gtk сверху и снизу отображаются данные Бейсика ("Bytes: aaa" и "0 OK, 60: 1") есть ли возможность не показывать/скрывать эти данные?

57627

* Я хочу создать .trd файл с загрузчиком. "Автоматизированный" способ при помощи tap2trd у меня не получился (при загрузке его из tr-dos я получаю "чёрный экран"). И здесь совсем не понятно в какую сторону копать, то ли tap2trd некорректно отработал, то ли я некорректно в tr-dos данные запускаю, то ли загрузчик, который в моём .tap, не подходит. Вот здесь начинается проблема с тем, что я не понимаю суть различий форматов файлов и создания загрузчиков для кода. Есть ли где-то статья на тему того, как "вручную" написать загрузчик при написании ассемблерного когда, чтобы у меня на этапе компиляции уже бинарник с загрузчиком получился, или так не бывает? Или может быть можно "вручную" создать .trd?

* Нашёл утилиту bin2trd, она при выполнении говорит "Descriptor must have TRL extention", кто-нибудь знает что такое trl?

Black Cat / Era CG
21.07.2016, 01:24
"Автоматизированный" способ при помощи tap2trd у меня не получился (при загрузке его из tr-dos я получаю "чёрный экран"). И здесь совсем не понятно в какую сторону копать, то ли tap2trd некорректно отработал, то ли я некорректно в tr-dos данные запускаю, то ли загрузчик, который в моём .tap, не подходит.
Само собой загрузчик не подходит. Он пытается, код с кассеты грузить, а не с диска.

Надо сначала б руками и глазами посмотреть и понять, что такое загрузчик (бейсик в общих чертах представлять), тогда вопросов резко станет меньше.


При загрузке полученного .tap в fuse-gtk сверху и снизу отображаются данные Бейсика ("Bytes: aaa" и "0 OK, 60: 1") есть ли возможность не показывать/скрывать эти данные?

Bytes: aaa
выдает команда LOAD "" CODE (которая и загружает ваш код) в загрузчике. Это ее нормальное поведение.
Другое дело, что после нее можно (желательно) очистить экран (CLS) перед запуском самого кода, но скорее всего в "готовом" загрузчике этого просто нет.
Там скорее всего идет просто RANDOMIZE USR Addr (Addr - адрес запуска вашего кода).
Далее, после того как ваш код выполнится, он по команде ret передает управление назад в загрузчик, а так как строк в загрузчике больше и нет, работа его успешно завершается с соответствующим сообщением.
Все логично. А что же должно происходить? Зависание? Программа выполнена, код ваш выполнен.

Alex Rider
23.07.2016, 13:13
Есть ли хорошая книга и внятная статья по работе со screen memory (как в желаемом месте желаемым цветом нарисовать точку)?
Настоятельно рекомендуется прочитать вот это (http://zxpress.ru/book.php?id=2) (ассемблер) и (опционально) вот это (http://zxpress.ru/book.php?id=3) (Basic). Очень доступные книги обо всем, читаются легки и понятно. Конкретно по графике можно посмотреть вот это (http://zxpress.ru/book.php?id=9) (это только первый том), там как раз про расчет адреса видеопамяти есть отдельная глава (http://zxpress.ru/book_articles.php?id=1538) (впрочем, об этом и в других книгах тоже много есть). Под рукой в качестве справочника Библии всегда иметь вот это (http://zxpress.ru/book.php?id=132) и вот это (http://zxpress.ru/book.php?id=18). Вообще, всяких книг исключительно про Spectrum много тут (http://zxpress.ru/books.php).

- - - Добавлено - - -


Я компилирую код при помощи pasmo (pasmo -d -v --bin zzz.z80 zzz.bin), после этого создаю tap с загрузчиком при помощи bin2tap (./bin2tap -b zzz.bin) (почему-то .tap с загрузчиком, получаемый из pasmo у меня работает некорректно).
Ассемблер sjasm умеет делать сразу trd и sna (для более быстрой отладки). Есть пара толковых инструкций по созданию среды разработки из редактора, sjasm и эмулятора, позволяющей запускать программы на ассемблере из редактора "в один клик".

Kakos_nonos
23.07.2016, 14:21
Чтоб создать .trd программой bin2trd надо приложить .trl файл, в котором будет описано какие файлы на диск помещать. У меня в одном проекте вот такой фаил:


NORMAL "DISK"
HOBETA "DEMO____.$B"
BINARY "file.BIN","DEMO","C",25000
BINARY "to.scr","TOTOTOTO","C",49152
BINARY "zas.scr","ZASTZAST","C",49152
BINARY "CHEMPHON.SCR","CHEMPHON","C",57344
HOBETA "Hot mix.$C","MUSICAAA","C",40000


Необходимы только первые два - это бейсик загрузчик (трдос-загрузчик) и сам бинарный фаил с данными. Могу приложить все файлы, если интересно. Хотя, сейчас все пишут на sjasm+, он сам может компонавать trd/tap. Про тап не знаю, а трд делается так:


DEVICE ZXSPECTRUM128
emptytrd "aa.trd"
org 25000

;Пишем тут код


ee:
jp ee

endpr:
savetrd "aa.trd","DEMO.C",25000,endpr-25000
org 25000
inchob "boot.b" ; Бейсик загрузчик. Тот же что и в первом примере
endb:
savetrd "aa.trd","boot.B",25000,endb-25000

Кстати, sjasm+ есть и для линукса.
Прикладываю загрузчик.

- - - Добавлено - - -


есть ли возможность не показывать/скрывать эти данные?
Можно очистить экран перед выводом изображения, например так:


ld hl,16384
ld de,16385
ld (hl),0
ld bc,6144
ldir


А после рисования впасть в бесконечный цикл


label:
jp label

moronizzz
22.08.2016, 16:41
1) А как из ассемблера установить цвета по-умолчанию для бумаги и чернил? (аналог BORDER и INK), попробовал напрямую в системные переменные значения записать необходимые, но кажется, что не сработало. Хочу несколько знакомест заполнить одним цветом, и не выставлять цвет для каждого из них.

2) Подскажите хорошую книгу, или статью по кодированию музыки, например на бипере. И чтобы было понятно, как совместить вывод звуков и вывод графики.

Hacker VBI
22.08.2016, 16:49
1.


ld hl,#5800
ld de,$5801
ld bc,#2ff
ld (hl),7
ldir

Заполнение всех аттрибутов цвета экрана чёрным папером и белым инком.

2. возьми музыкальный редактор для бипера и попробуй ним экспорт в бинарник.

Black Cat / Era CG
22.08.2016, 17:09
Типа так


ATRRs EQU %01000111 ;тут 2 старших бита - FLASH, BRIGHT, потом PAPER, INK. Это константа, ее значение можно поменять только до компиляции
Fill LD HL,StartAddr ;Адрес 1 знакоместа, которое надо заполнять в области атрибутов экрана
LD (HL),ATTRs
LD DE,StartAddr+1
LD BC,Len-1 ;Len - сколько знакомест подряд (они идут друг за другом построчно) заполнять.
LDIR
RET
Пользовать так:
CALL Fill
Можно чуть иначе:


Fill LD HL,StartAddr ;Адрес 1 знакоместа, которое надо заполнять в области атрибутов экрана
LD A,(ATTRs)
LD (HL),A
LD DE,StartAddr+1
LD BC,Len-1 ;Len - сколько знакомест подряд (они идут друг за другом построчно) заполнять.
LDIR
RET
ATTRs DEFB %01000111 ;тут 2 старших бита - FLASH, BRIGHT, потом PAPER, INK. Это переменная, ее значение можно менять когда угодно

Пользовать так:

LD A,нужное значение
LD (ATTRs),A
CALL Fill

moronizzz
22.08.2016, 17:31
2. возьми музыкальный редактор для бипера и попробуй ним экспорт в бинарник.

Как из музыки сделать бинарник более-менее понятно, не понятно, как объеденить графику и звук, чтобы они "параллельно" выполнялись.

- - - Добавлено - - -

И ещё, хочу добавить в код "именованные переменные", таким образом, чтобы их можно было модифицировать (уменьшать, увеличивать, копировать туда данные из регистров, оттуда данные брать в регистр). Как это правильно сделать? Вижу, что при помощи EQU можно значение присвоить метке, но изменить его уже нельзя.

Vadim
22.08.2016, 17:44
1) А как из ассемблера установить цвета по-умолчанию для бумаги и чернил?

Поместить нужные значения в переменные бейсика. Описание переменных (их имена и назначение) можно найти в многочисленных книгах по бейсику, "Таники ZX" и прочих. У вас скорее всего всё сработало. Дело в том, что переменные эти используются лишь тогда, когда спектрум бейсик выводит текст своими процедурами. Либо мы вызываем процедуру вывода символов или строк из ПЗУ бейсик. Если же вы работаете напрямую с экранной областью, т.е. пишите свои процедуры вывода символа, на её основе вывод строк, рисование линий и т.д. То само собой, что переменные эти никак не влияют на вывод, если вы сами не будете брать оттуда значения для задания цвета.

Black Cat / Era CG
22.08.2016, 17:45
Смотри мой второй пример, там именно переменная же.
Имя переменной DEFB 0 ;1-байтная переменная (значение 0 можно менять)

Hacker VBI
22.08.2016, 19:26
moronizzz, размещай это дело в памяти


ld a,(foo)
inc a
ld (foo),a
ld hl,(foow)
ret

foo db 1
foow dw #8001

moronizzz
23.08.2016, 03:06
Я нашёл статью, где немного описывается как звуки из бипера извлекать: http://zxpress.ru/article.php?id=5441&lng=eng

В связи с этим появились новые вопросы:

1) Есть ли где-то шпаргалка по соответствию задержек (частоты смены 4 бита) и нот?

2) Если предложенную функцию запускать в цикле, получается, что цвет бордюра постоянно меняется (из-за того, что используется XOR, чтобы менять значение 4 бита), есть ли общеизветный способ это обойти? Пока надумал только тестировать четвёртый бит при помощи BIT и устанавливать/сбрасывать в зависимости от предыдущего результата, но по-моему это очень медленно получится.

На всякий случай код из статьи:


10 DI; ban interrupt
20 LD BC, 2560; BC = length
30 LD A, 7; A = Border color
40 BEGIN XOR 16; inverting bits D4
50 OUT (254), A; output to port A 254
60 LD D, 100; D = delay (frequency)
70 PAUSE DEC D; D = D-1
80 JR NZ, PAUSE; if D <> 0 then loop
90 DEC BC; BC = BC-1
100 LD D, A; preservation A
110 LD A, B; BC =
120 OR C; 0?
130 LD A, D; A recovery
140 JR NZ, BEGIN; if BC <> 0 then loop
150 EI; permission to interrupt
160 RET; return to BASIC

3) Есть ли где-то пример того, как музыку на бипере приделывают к демо/интро? Выглядит так, как будто должна быть написана процедура (subroutine), издающая звуки, и к этой процедуре должны производиться регулярные обращения при выполнении программы - это так?

Reobne
23.08.2016, 08:01
moronizzz,
2) По хитрому не знаю. Нужно по честному: знать какой у тебя сейчас цвет бордюра, и при записи в порт FE этот цвет подтверждать в младших трёх битах.
Вот посмотри на код из статьи, строка 30. Программист знал, что цвет белый и только белый. И он смело пишет константу 7.

moronizzz
23.08.2016, 09:58
moronizzz,
2) По хитрому не знаю. Нужно по честному: знать какой у тебя сейчас цвет бордюра, и при записи в порт FE этот цвет подтверждать в младших трёх битах.
Вот посмотри на код из статьи, строка 30. Программист знал, что цвет белый и только белый. И он смело пишет константу 7.

Тут "подтверждение" работает только один раз, потому что если в цикле заново указывать цвет, то будет сбрасываться и четвёртый бит, у меня сейчас примерно так всё это выглядит:


DI ; ban interrupt

LD A, %00000100 ; A = Border color

main_loop:
LD A, D ; A recovery
LD BC, 2000 ; BC = length
BEGIN:
;XOR %00010000 ; inverting bits D4

; чтобы сохранить цвет бордюра
BIT 4, A
LD A, %00000100

JP NZ, skip_set
SET 4, A
skip_set
JP Z, skip_res
RES 4, A
skip_res

OUT (254), A ; output to port A 254
LD E, A
LD A, (delay)
LD D, A ; D = delay (frequency)
LD A, E

PAUSE:
DEC D ; D = D-1
JR NZ, PAUSE ; if D <> 0 then loop

DEC BC ; BC = BC-1
LD D, A ; preservation A

LD A, B ; BC = 0?
OR C ;

JR NZ, BEGIN ; if BC <> 0 then loop

LD A, (delay)
SUB 5
CP 0
JP Z, finish
LD (delay), A
JR main_loop
RET
finish:
nop

EI ; permission to interrupt
RET ; return to BASIC

delay: DEFB 255

SAM style
23.08.2016, 11:38
BIT 4, A
LD A, %00000100
JP NZ, skip_set
SET 4, A
skip_set
JP Z, skip_res
RES 4, A
skip_res
Если ты в E хранишь текущее значение, выведенное в #fe, то лучше его и использовать, а не сохранять A куда попало:


LD A, E
XOR %00010000 ; изменить бит 4 на противоположный
LD E,A
OUT (254), A
Другой вопрос - если менять кол-во тактов между выводами в #FE, меняется и частота звука бипера

Reobne
23.08.2016, 12:38
LD A, %00000100 ; A = Border color
main_loop:
LD A, D ; A recovery

Записал в А цвет бордюра, и тут-же его стёр. А что в D - неизвестно.

moronizzz
23.08.2016, 18:08
Вижу, что люди добавляют в образ с программой картинки и музыку бинарниками - где почитать как эти бинарники использовать из кода? Про графику, опять же, более-менее понятно, достаточно знать в какую область памяти она загружена и копировать на экран, а в случае с музыкой как будет?

SAM style
23.08.2016, 18:13
Вижу, что люди добавляют в образ с программой картинки и музыку бинарниками - где почитать как эти бинарники использовать из кода? Про графику, опять же, более-менее понятно, достаточно знать в какую область памяти она загружена и копировать на экран, а в случае с музыкой как будет?
А в случае музыкой тебе нужен плеер, который эти музыки будет играть через вызов его каждое прерывание.