PDA

Просмотр полной версии : Перевод гайда How to Write ZX Spectrum Games



helcril
13.03.2015, 09:09
Здесь буду постепенно выкладывать мой перевод на русский гайда How to Write ZX Spectrum Games от Jonathan Cauldwell (разработчика игр и автора AGD).
Надо добавить, что гайд не по AGD, а по программированию игр на Ассемблере. Оригинал в формате doc в приложении HowTo0.6.zip.

Пока перевел:
Введение
Оглавление
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Обновление, переведена седьмая глава, перезалит архив с пдф (HowTo0.6 Rus).

В тексте много кода и технических понятий, с которыми я знаком поверхностно. Так что в теме приветствуются знатоки в качестве редакторов. Пишите ваши мысли по поводу уже готового перевода.

kgbplus
13.03.2015, 10:55
Так а что непонятно то? Спрашивайте.

helcril
13.03.2015, 11:37
Пока все ок. В процессе перевода могут возникнуть сложности, о них я буду спрашивать в следующих постах.

kgbplus
13.03.2015, 11:42
Используйте словарь Мультитран (www.multitran.ru). Там 99% терминов переведены.

helcril
13.03.2015, 11:49
Спасибо, но я не о переводе терминов. Просто возможно из-за незнания чего-либо специфического могу исказить смысл текста, или комментариев к коду.

helcril
13.03.2015, 16:05
Кстати, может тему перекинуть в раздел Программирование?

Ewgeny7
14.03.2015, 17:26
Кстати, может тему перекинуть в раздел Программирование?
Нет, не стОит. Это именно пресса.

helcril
16.03.2015, 09:28
Вопрос по коду из гайда и комментарию к нему:

ld hl,15616 ; ROM font.
ld de,60000 ; address of our font.
ld bc,768 ; 96 chars * 8 rows to alter.
font1 ld a,(hl) ; get bitmap.
rlca ; rotate it left.
or (hl) ; combine 2 images.
ld (de),a ; write to new font.
inc hl ; next byte of old.
inc de ; next byte of new.
dec bc ; decrement counter.
ld a,b ; high byte.
or c ; combine with low byte.
jr nz,font1 ; repeat until bc=zero.
ld hl,60000-256 ; font minus 32*8.
ld (23606),hl ; point to new font.
ret
Сам я не понял для чего конкретно нужен этот код (подозреваю, что-то связано с переносом при декременте). Перевел пока вот так:

ld hl,15616 ; загружаем адрес ROM-шрифта.
ld de,60000 ; адрес нашего нового шрифта.
ld bc,768 ; 96 символов * 8 строк для изменения.
font1 ld a,(hl) ; получаем изображение символа.
rlca ; сдвиг влево.
or (hl) ; совмещаем два изображения.
ld (de),a ; записываем в новый шрифт.
inc hl ; следующий байт старого шрифта.
inc de ; следующий байт нового шрифта.
dec bc ; уменьшаем счетчик.
ld a,b ; старшую часть байта.
or c ; объединяем с младшей.
jr nz,font1 ; повторяем пока bc не будет=0.
ld hl,60000-256 ; адрес шрифта минус 32*8.
ld (23606),hl ; указываем на новый шрифт.
ret

Поясните и поправьте, если надо, пожалуйста.

denpopov
16.03.2015, 09:36
Поясните и поправьте, если надо, пожалуйста

навскидку генерируется из стандартного жирный шрифт
комментарий неуместен, это просто цикл на 768 байт, так он организован.

helcril
16.03.2015, 10:03
навскидку генерируется из стандартного жирный шрифт
комментарий неуместен, это просто цикл на 768 байт, так он организован.

Спасибо. Я забыл написать, что вопрос возник по выделенному жирным шрифтом. Т.е.

ld a,b ; high byte.
or c ; combine with low byte.

Остальной код вполне понятен даже мне. :D
Однако, т.к. этот текст предназначен новичкам, думаю будет полезным комментировать все действия.

denpopov
16.03.2015, 10:14
Остальной код вполне понятен даже мне
регистр BC счетчик цикла на 768 байт.

т.е. B=3, C=0

проверка на достижение счетчиком 0:
ld a,b
or c

helcril
16.03.2015, 10:29
регистр BC счетчик цикла на 768 байт.

т.е. B=3, C=0

проверка на достижение счетчиком 0:
ld a,b
or c

Спасибо, просто мне эти битовые махинации и непонятны. Поправлю комментарий.

denpopov
16.03.2015, 10:46
просто мне эти битовые махинации и непонятны
а что сложного?
нельзя проверить регистровые пары на значения в лоб, это самый простой способ - 16-битное значение разбито на два байта, в данном случае - младший и старший байт.

т.е. 768= $300(в шестнадцатеричном режиме)
B=3 - это ст. байт
C=0 - мл. байт.
вместе 16 бит получается как 3*256+0 = 768.
Но к играм это отношение не имеет, это азы программирования.

helcril
16.03.2015, 11:12
а что сложного?
нельзя проверить регистровые пары на значения в лоб, это самый простой способ - 16-битное значение разбито на два байта, в данном случае - младший и старший байт.

т.е. 768= $300(в шестнадцатеричном режиме)
B=3 - это ст. байт
C=0 - мл. байт.
вместе 16 бит получается как 3*256+0 = 768.
Но к играм это отношение не имеет, это азы программирования.

Я понимаю, что регистровая пара состоит из старшего и младшего байта. И то, как это выглядит в шестнадцатеричном виде, тоже знаю.
Но не знал, что нельзя проверять на значение сразу пару, и мне непонятно каким образом ld a,b or c может это делать. :v2_conf2: К сожалению, как-то так.
Тем не менее Глава 1 закончена, пройдусь еще завтра свежим взглядом и обновлю пдф. Читайте, критикуйте, предлагайте. Спасибо за помощь.

goodboy
16.03.2015, 11:20
мне непонятно каким образом ld a,b or c может это делать. правильней OR A,C (но А не указывается поскольку подразумевается что операция проводится только с ним)
на биты в А накладываются биты из С при этом используется логическое сложение
https://ru.wikipedia.org/wiki/%D0%94%D0%B8%D0%B7%D1%8A%D1%8E%D0%BD%D0%BA%D1%86%D 0%B8%D1%8F

флаг нуля Z установится только когда все биты в обоих операндах =0


Таблица истинности
~x ~y x or y
~0 ~0 ~0
~0 ~1 ~1
~1 ~0 ~1
~1 ~1 ~1

denpopov
16.03.2015, 11:24
правильней OR A,C
часть ассемблеров смееццо над тобой:)


Читайте, критикуйте, предлагайте
то ли я ступил, то ли мой пост пропал: неплохо бы к переводу приложить готовые листинги, которые можно ассемблировать. Например, для pasmo.

helcril
16.03.2015, 11:28
флаг нуля Z установится только когда все биты в обоих операндах =0
Вот теперь все понятно. Понимал, что or c тестит младшую часть на ноль. А вот как это работает в связке с ld a,b не допетривал. Спасибо.

goodboy
16.03.2015, 11:34
скорее создаётся аналог or b,c на 0 проверяются обе части

Reobne
16.03.2015, 12:20
; Генерируем утолщённый шрифт.
ld hl,15616 ; ПЗУ-шрифт.
ld de,60000 ; адрес нашего нового шрифта.
ld bc,768 ; меняем 96 знаков * 8 строчек.
; Начало цикла
font1 ld a,(hl) ; берём биты строчки.
rlca ; сдвигаем влево.
or (hl) ; объединяем оба изображения.
ld (de),a ; пишем в новый шрифт.
inc hl ; следующий байт старого.
inc de ; следующий байт нового.
dec bc ; уменьшаем счетчик.
ld a,b ; старший байт (счётчика)
or c ; объединяем с младшим байтом.
jr nz,font1 ; цикл повторяем, пока не настанет bc=zero.
;новый шрифт устанавливаем как текущий.
ld hl,60000-256 ; адрес шрифта минут 32*8.
ld (23606),hl ; записываем в системную переменную.
ret

denpopov
16.03.2015, 12:26
ld hl,15616 ; ПЗУ-шрифт.

может, адрес хранящего в ПЗУ шрифта?

helcril
16.03.2015, 13:32
может, адрес хранящего в ПЗУ шрифта?

Ну, у меня почти так:

ld hl,15616 ; загружаем адрес ROM-шрифта.
ld de,60000 ; адрес нашего нового шрифта.
Только и правда ROM надо на ПЗУ поменять.

---------- Post added at 18:32 ---------- Previous post was at 18:30 ----------


скорее создаётся аналог or b,c на 0 проверяются обе части

Да, я действительно правильно. Ведь в аккумулятор мы загрузили содержимое b. А результатом операции OR C будет ноль, только если в обоих байтах (a и c) все биты будут нули.

denpopov
16.03.2015, 13:36
"Пишем книгу как "написать игру" " вместе:)

helcril
16.03.2015, 13:56
"Пишем книгу как "написать игру" " вместе:)

Ну, я сразу предупреждал, что скорее всего понадобится помощь с техническими моментами. :D

denpopov
16.03.2015, 14:00
Ну, я сразу предупреждал, что скорее всего понадобится помощь с техническими моментами

А... всегда рады помочь, если что:)

helcril
16.03.2015, 16:54
Обновление, переведена Глава 1

Andrew771
16.03.2015, 17:04
"Пишем книгу как "написать игру" " вместе
такая книга уже есть, 1995 года, авторы Капульцевичи и Евдокимов :)
кстате, они тоже активно юзают процедуры из ПЗУ, а это не гуд для крутых поделий. Быстродействие будет как у Бейсика.

helcril
16.03.2015, 18:10
такая книга уже есть, 1995 года, авторы Капульцевичи и Евдокимов :)
кстате, они тоже активно юзают процедуры из ПЗУ, а это не гуд для крутых поделий. Быстродействие будет как у Бейсика.

В уже переведенном тексте написано, что продвинутые способы будут дальше. А процедуры ПЗУ он использует для, так сказать "быстрого старта" читателей. Джонатан реальный игродел и автор конструктора AGD, думаю, что качество материала должно быть хорошее.

Reobne
17.03.2015, 08:40
Быстродействие будет как у Бейсика.
Ну, не совсем. Новички всё воспринимают буквально.
На самом бейсике, всё таки, получается в разы медленнее программа.
Но не используя подпрограммы ПЗУ, можно делать в разы быстрее.
Использовать ПЗУ это промежуточный вариант между чистым бейсиком и чистым ассемблером.

Alex Rider
18.03.2015, 11:31
кстате, они тоже активно юзают процедуры из ПЗУ, а это не гуд для крутых поделий. Быстродействие будет как у Бейсика.
Спорное утверждение. К использованию процедур ПЗУ нужен мудрый подход - велосипедостроение никогда не рекомендовалось как best practices.

helcril
24.03.2015, 10:45
Перевод второй главы почти закончен, готово все, кроме комментария к вот этом коду. Процедура отвечает за опрос клавиатуры. Т.е. можно опросить любые клавиши. Помогите, пожалуйста, понятно и правильно перевести комментарии к коду. Привожу два переведенных абзаца, предшествующих коду:

Мы можем установить необходимый адрес порта для каждой группы клавиш, используя формулу из руководства пользователя Спектрума. Адрес порта будет 254+256*(255-2^n), где n – это номер группы, принимающий значения от 0 до 7. Так же в ПЗУ, по адресу 654, есть очень полезная подпрограмма, которая возвращает код нажатой клавиши (от 0 до 39) в регистр e. Коды от 0 до 7 – это клавиши, которые в каждой группе ближе к середине (т.е. B, H, Y, 6, 5, T, G и V), 8-15 – следующие за ними, а 39 – крайняя клавиша последней группы – CAPS SHIFT. Кстати, статус клавиши SHIFT так же возвращается в регистр d. Значение 255 говорит о том, что не нажата ни одна клавиша.

Данная подпрограмма ПЗУ может возвращать код только одной клавиши, и не подходит для определения нескольких одновременных нажатий. Тогда для определения нажатия какой-либо клавиши в любой момент времени, нам необходимо конвертировать полученный код в адрес порта и номер бита, а затем считать оттуда значение. Для этого я использую одну очень удобную процедуру. Это единственная процедура в моих играх, написанная не мной. Выражаю за нее свою признательность Стивену Джонсу, программисту, который много лет назад писал отличные статьи для «Spectrum Discovery Club». Для работы с этой подпрограммой, загрузите в аккумулятор код клавиши, нажатие которой вы хотите проверить, вызовите ktest, и проверьте флаг переноса. Если он установлен, то клавиша не была нажата, если сброшен – то была. Если вам этот способ кажется запутанным и не слишком правильным, поставьте инструкцию ccf перед ret.



ktest ld c,a ; key to test in c.
and 7 ; mask bits d0-d2 for row.
inc a ; in range 1-8.
ld b,a ; place in b.
srl c ; divide c by 8,
srl c ; to find position within row.
srl c
ld a,5 ; only 5 keys per row.
sub c ; subtract position.
ld c,a ; put in c.
ld a,254 ; high byte of port to read.
ktest0 rrca ; rotate into position.
djnz ktest0 ; repeat until we've found relevant row.
in a,(254) ; read port (a=high, 254=low).
ktest1 rra ; rotate bit out of result.
dec c ; loop counter.
jp nz,ktest1 ; repeat until bit for position in carry.
ret

kgbplus
24.03.2015, 14:43
ktest ld c,a ; код клавиши помещаем в c.
and 7 ; оставляем только биты d0-d2 для получения номера ряда.
inc a ; прибавляем единицу, чтобы значение стало от 1 до 8.
ld b,a ; помещаем в b.
srl c ; делим c на 8,
srl c ; для того, чтобы найти позицию внутри ряда.
srl c
ld a,5 ; в ряду 5 клавиш.
sub c ; вычитаем из кода значение позиции.
ld c,a ; результат помещаем в c.
ld a,254 ; старший байт номера порта из которого будем читать.
ktest0 rrca ; с помощью сдвига вычисляем старший байт адреса порта.
djnz ktest0 ; повтор, пока не найдем соответствующий ряд.
in a,(254) ; читаем порт (a=старший байт, 254=младший).
ktest1 rra ; сдвигаем биты в прочитанном результате.
dec c ; счетчик цикла.
jp nz,ktest1 ; повторять пока нужный нам бит не окажется в флаге переноса.
ret

helcril
25.03.2015, 05:14
ktest ld c,a ; код клавиши помещаем в c.
and 7 ; оставляем только биты d0-d2 для получения номера ряда.
inc a ; прибавляем единицу, чтобы значение стало от 1 до 8.
ld b,a ; помещаем в b.
srl c ; делим c на 8,
srl c ; для того, чтобы найти позицию внутри ряда.
srl c
ld a,5 ; в ряду 5 клавиш.
sub c ; вычитаем из кода значение позиции.
ld c,a ; результат помещаем в c.
ld a,254 ; старший байт номера порта из которого будем читать.
ktest0 rrca ; с помощью сдвига вычисляем старший байт адреса порта.
djnz ktest0 ; повтор, пока не найдем соответствующий ряд.
in a,(254) ; читаем порт (a=старший байт, 254=младший).
ktest1 rra ; сдвигаем биты в прочитанном результате.
dec c ; счетчик цикла.
jp nz,ktest1 ; повторять пока нужный нам бит не окажется в флаге переноса.
ret

Спасибо большое. :v2_thumb: Попытался сам разобраться в коде, благодаря вашей правке. Нашел одну ошибку (выделил жирным в обоих вариантах комментариев), добавил дополнительные пояснения по регистрам, ну и поправил под свой стиль перевода.:D Так же инструкции ротации не стал называть сдвигом, т.к. имхо все-таки это разные вещи. Посмотрите, и поправьте, где нужно:


ktest ld c,a ; код клавиши помещаем в c.
and 7 ; оставляем только биты d0-d2,
; для определения номера группы.
inc a ; прибавляем 1 чтобы получить значение от 1 до 8.
ld b,a ; загружаем номер порта в b.
srl c ; делим c на 8,
srl c ; чтобы найти позицию клавиши внутри группы.
srl c ; значение позиции будет от 0 до 4.
ld a,5 ; в группе только пять клавиш.
sub c ; вычитаем из aккумулятора значение позиции,
ld c,a ; и помещаем его в регистр c (результатом
; будет число от 1 до 5).
ld a,254 ; старший байт порта, из которого будем читать.
ktest0 rrca ; с помощью ротации аккумулятора вычисляем
; старший байт адреса порта.
djnz ktest0 ; повторяем, пока не найдем соответствующую группу
; (номер группы у нас хранится в b).
in a,(254) ; читаем порт (a=старший байт, 254=младший).
ktest1 rra ; ротация бит в полученном результате.
dec c ; счетчик цикла (в регистре c значения от 1 до 5).
jp nz,ktest1 ; повторяем, пока нужный бит не окажется
; во флаге переноса.
ret

kgbplus
25.03.2015, 14:24
1. О какой группе речь? Посмотрите здесь (http://www.wikiznanie.ru/ru-wz/index.php/%D0%A3%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D 0%B2%D0%BE_ZX-Spectrum) как устроена клавитаура Спектрума. Речь идет о рядах, (а точнее о полурядах)
2. В выделенном ошибся конечно, там не из кода вычитается положение в полуряде, а из 5.
Позиции в полуряде выглядят так 0 1 2 3 4, соответственно, чтобы например вытеснить позицию 2 с помощью rra нужно выполнить команду три раза.
3. Слова "ротация" в русском языке, на сколько я знаю, нет.

goodboy
25.03.2015, 14:43
с помощью ротации аккумулятора вычисляем
сдвигаем биты в A

Andrew771
25.03.2015, 15:34
Слова "ротация" в русском языке, на сколько я знаю, нет.
ну да? (https://ru.wiktionary.org/wiki/%D1%80%D0%BE%D1%82%D0%B0%D1%86%D0%B8%D1%8F)

denpopov
25.03.2015, 16:09
сдвиги, ротация - какая разница?

helcril
25.03.2015, 16:39
1. О какой группе речь? Посмотрите здесь (http://www.wikiznanie.ru/ru-wz/index.php/%D0%A3%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D 0%B2%D0%BE_ZX-Spectrum) как устроена клавитаура Спектрума. Речь идет о рядах, (а точнее о полурядах)
2. В выделенном ошибся конечно, там не из кода вычитается положение в полуряде, а из 5.
Позиции в полуряде выглядят так 0 1 2 3 4, соответственно, чтобы например вытеснить позицию 2 с помощью rra нужно выполнить команду три раза.
3. Слова "ротация" в русском языке, на сколько я знаю, нет.
1. Я знаю как устроена клавиатура спектрума. Вот ваш термин полуряд подходит, а ряд - нет. Я не догадался использовать слово полуряд и придумал термин группа. В любом случае он не искажает смысл.
2. Ну, я и не критиковал, просто сказал, что исправил ошибку.
3. А я точно знаю, что слово ротация есть, например ротация кадров. В ассемблере есть команды сдвига, а есть команды ротации. Они похожи, но не идентичны. Т.к. в данном коде именно команды ротации, то я так и пишу.


сдвигаем биты в A
Но ведь здесь инструкции ротации, а не сдвига. Я понимаю, что смысл примерно один, но это ведь будет некорректно.

kgbplus
25.03.2015, 16:51
ну да?

В оригинале команда rra делает rotate.
И внезапно (http://www.multitran.ru/c/m.exe?CL=1&s=rotate) - у этого слова нет перевода "ротация", потому что оно не обозначает оборот, а обозначает циклический сдвиг.

---------- Post added at 16:51 ---------- Previous post was at 16:46 ----------



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

Но ведь здесь инструкции ротации, а не сдвига. Я понимаю, что смысл примерно один, но это ведь будет некорректно.

Я чуть выше ссылку привел. Ротация кадров есть, признаю. Ротации битов нет. Перевод ваш, дело ваше. Но в данном случае "ротация" звучит так же дико, как у некоторых горе-переводчиков "партиция", "инсталляция" и "дебаггинг".

helcril
25.03.2015, 16:57
В оригинале команда rra делает rotate.
И внезапно (http://www.multitran.ru/c/m.exe?CL=1&s=rotate) - у этого слова нет перевода "ротация", потому что оно не обозначает оборот, а обозначает циклический сдвиг.

---------- Post added at 16:51 ---------- Previous post was at 16:46 ----------



Я чуть выше ссылку привел. Ротация кадров есть, признаю. Ротации битов нет. Перевод ваш, дело ваше. Но в данном случае "ротация" звучит так же дико, как у некоторых горе-переводчиков "партиция", "инсталляция" и "дебаггинг".

По ссылке ходил, но правда не ваша. Кроме "циклического сдвига" там куча других значений, в том числе "проворачивать", "обращаться". Все они по смыслу подходят.
Ваше замечание я понял. Возможно я не прав, и профи так не говорят. Но этот термин я не из головы взял, и не тупым переводом оригинальной мнемоники (я стараюсь переводить как раз осмысленно и глядя на другие источники). Так эти команды называют например в книге "Программирование в машинных кодах и на языке Ассемблера". Вот цитата оттуда:
5.14.3. Однобайтные команды ротации аккумулятора.
Поскольку регистр А широко используется во многих программах, для него продублированы 4 команды ротации. Они выполнены как однобайтные. Это позволяет при их использовании экономить память.
А вообще спасибо за помощь и хорошо, что перевод кто-то читает и поправляет.:v2_thumb:
Кстати, партицию перевел бы как раздел, дебаггинг как отладку. А вот перевод инсталляции зависит от контекста. Иногда правильней будет написать именно инсталляция.
Добавлю пару еще пару источников, где так же используется термин ротация бит:
http://marsohod.org/index.php/prodmarsohod2/amber-arm-soc/226-arm-instr
http://www.studfiles.ru/preview/1196320/

P.S. Если уж все так против слова "ротация", то на "циклический сдвиг" можно заменить. Но просто "сдвиг" точно писать не буду.

Reobne
25.03.2015, 18:08
P.S. Если уж все так против слова "ротация", то на "циклический сдвиг" можно заменить. Но просто "сдвиг" точно писать не буду.
Тут логически важен именно сдвиг, и лучше писать просто "сдвиг". Свойство его цикличности неважна.
(Это также коряво, как вместо "используйте туалетную бумагу" писать "используйте вращающуюся туалетную бумагу". Хотя никто не переспорит, что она вращается на бобине.)

helcril
26.03.2015, 02:35
Тут логически важен именно сдвиг, и лучше писать просто "сдвиг". Свойство его цикличности неважна.
(Это также коряво, как вместо "используйте туалетную бумагу" писать "используйте вращающуюся туалетную бумагу". Хотя никто не переспорит, что она вращается на бобине.)

А то, что этот сдвиг проходит через флаг переноса, в отличие от обычного разве не играет роли?
Хорошо, я буду писать "сдвиг", "сдвигаем" и пр. в комментариях к коду и пояснениях, но если речь будет идти о командах типа rra, rrca то буду писать все-таки команды ротации.

Reobne
26.03.2015, 05:11
А то, что этот сдвиг проходит через флаг переноса, в отличие от обычного разве не играет роли?
Да, роли не играет. Нам тут важно чтобы был сдвиг, и выпихнутые биты попадали в CF.
Такой логике действия удовлетворяют и команда RRA и RRCA. Эти две команды отличаются только источником для запихивания бита с другого конца. Но нам, в данном месте, это не важно.

И моё мнение, что лучше писать "сдвиг" чем "ротация". "Ротация" это грубый перевод. Ребятишкам более понятен термин "сдвиг"(понятное русское слово). Те примеры, которые показывают, что можно употреблять слово "ротация", это всего лишь примеры грубого перевода. То есть, опрометчиво следовать всем подряд примерам, лучше разобраться, какие примеры удачные, а какие нет. Вот такое моё мнение.

helcril
26.03.2015, 07:14
"Ротация" это грубый перевод. Ребятишкам более понятен термин "сдвиг"(понятное русское слово).

Хорошо, коллективными стараниями вы меня убедили. :D
Буду писать "сдвиг", надо пробежаться по тексту и поправить.

Но ответ на вопрос неоднозначный, если честно. Глянул в учебник Юрова по Ассемблеру для ВУЗов, там команды такого типа называют "циклический сдвиг". А вот в книге "Схемотехника: аппаратура и программы" пишут "команды ротации (сдвига)", "ротация влево, вправо", "кольцевой сдвиг". И здесь:http://www.xn--s1ab0a.xn--p1ai/electr/microproc/laba2new/index.php?fname=_r10.php так же используют термин "ротация". Это все русские источники, русские авторы, хорошо знакомые с областью, о которой пишут.
Так что зря вы меня обвиняете в "дословном, грубом переводе" и "использовании неудачно переведенных источников". Термин вполне используется в русскоязычных источниках. Вон какие умные русские дядьки пишут то же самое. :D Просто мне слово "ротация" слух не режет и я понимаю, что оно значит. Но раз большинству не нравится, буду исправлять.
Кстати, разве книга "Программирование в машинных кодах и на языке Ассемблера" - это перевод?.

Reobne
26.03.2015, 07:20
там команды такого типа
Да, команды, это команды.
Но в комментариях мы должны не названия команд расшифровывать, а что именно мы делаем с помощью этих команд.


Так что зря вы меня обвиняете
Нет, нет. Я не обвиняю, и не говорю за большинство. Это моё мнение, мне попадалась другая литература, которая сформировала моё мнение. За большинство, пусть скажут другие за себя, и тогда может и наберётся большинство.

helcril
26.03.2015, 07:45
Да, команды, это команды.
Но в комментариях мы должны не названия команд расшифровывать, а что именно мы делаем с помощью этих команд.

Согласен, исправлю и спасибо за критику.



Нет, нет. Я не обвиняю, и не говорю за большинство. Это моё мнение, мне попадалась другая литература, которая сформировала моё мнение. За большинство, пусть скажут другие за себя, и тогда может и наберётся большинство.

Ну это я просто обобщил конечно. Просто не вы первый сказали "грубый перевод", "перевод в лоб". Даже аналогии проводили с теми кто пишет "партиция" и "дебаггинг". :D
Но все равно всем спасибо. Перевод только лучше станет, а заодно и для себя что-то новое узнал.

denpopov
26.03.2015, 09:23
кто пишет "партиция" и "дебаггинг"

дада, меня часто смешило слово "релокатабельная":)

а эти слова - раздел и отладка?

kgbplus
26.03.2015, 10:41
Вот что рискну предложить. Есть книга, ZX-Spectrum & TR-DOS для пользователей и программистов Ларченко и Родионова. (http://zxpress.ru/book_articles.php?id=1844)
Эта книга, во-первых, с самого начала стала библией пользователей и программистов на Спектруме, а во-вторых, лично для меня, всегда была образцом систематизации, оформления и подачи материала.
В ней, кроме прочего, приведены почти все термины и в том числе привычные многим названия команд. Возьмите эту книгу за основу и ориентируйтесь на то, как переведено в ней.
А книги для pc оставьте писишникам ;-)

helcril
26.03.2015, 10:48
а эти слова - раздел и отладка?
Да, как я уже выше писал, я бы перевел их так. А вот инсталляцию, над которой тоже смеялись, все-таки в зависимости от контекста. Т.е. иногда ее лучше не переводить.

---------- Post added at 15:48 ---------- Previous post was at 15:43 ----------


Вот что рискну предложить. Есть книга, ZX-Spectrum & TR-DOS для пользователей и программистов Ларченко и Родионова. (http://zxpress.ru/book_articles.php?id=1844)
Эта книга, во-первых, с самого начала стала библией пользователей и программистов на Спектруме, а во-вторых, лично для меня, всегда была образцом систематизации, оформления и подачи материала.
В ней, кроме прочего, приведены почти все термины и в том числе привычные многим названия команд. Возьмите эту книгу за основу и ориентируйтесь на то, как переведено в ней.
А книги для pc оставьте писишникам ;-)

ОК, спасибо. Буду заглядывать туда.
Но из тех источников, что привел я только одна книга для PC. Остальное из разных областей, одна для Спектрума, другая вообще по схемотехнике, сайт уже не помню, но точно не про ПК.

helcril
27.03.2015, 06:16
Переведена Глава 2.

---------- Post added at 11:16 ---------- Previous post was at 10:13 ----------


неплохо бы к переводу приложить готовые листинги, которые можно ассемблировать. Например, для pasmo.
А в каком виде лучше? Исходники отдельными файлами?
Я проверяю примеры из книги тупо копируя прямо из текста, и запихивая их в ZXSpin-ассемблер.

denpopov
27.03.2015, 06:59
А в каком виде лучше? Исходники отдельными файлами?
Думаю, что лучше в примерах.

helcril
27.03.2015, 07:09
Думаю, что лучше в примерах.
А это как?:v2_conf3:

denpopov
27.03.2015, 07:51
А это как
хотя бы так:

Я проверяю примеры из книги тупо копируя прямо из текста
как будет готов, сделаем сырки для Pasmo и для SjASM.

helcril
03.04.2015, 08:56
Обновление, переведена Глава 3.

helcril
24.04.2015, 06:53
Обновление, переведена Глава 4.

kgbplus
07.10.2015, 16:09
Остановилось дело?

Bedazzle
11.10.2015, 10:19
Оригинал здесь: http://www.sendspace.com/file/alhxcq


Оригинал по линку больше недоступен.
Полное или нет, но что-то есть тут (https://chuntey.wordpress.com/category/z80-assembly/).

specorg
11.10.2015, 11:40
Оригинал по линку больше недоступен.
Полное или нет, но что-то есть тут (https://chuntey.wordpress.com/category/z80-assembly/).
Там на главной есть новость о том что блог переезжает на новое место


Bytes: Chuntey has moved to a new (more permanent) address @ www.chuntey.arjunnair.in. This blog will no longer be updated here. Please refer to the new link for futher updates!
Так что теперь всё находится тут http://chuntey.arjunnair.in/?cat=61

helcril
21.10.2015, 03:27
Остановилось дело?

Пока да, к сожалению. В ближайшее время планирую возобновить. Пятая глава почти переведена.
Английский оригинал в формате Word у меня сохранился. Могу прикрепить к первому посту.

lzb_j77
21.10.2015, 18:56
что-то не вижу оригинала в .doc

helcril
22.10.2015, 06:52
что-то не вижу оригинала в .doc

Прикрепил к первому посту.

helcril
29.10.2015, 06:48
Обновление. Перевел пятую главу.

kgbplus
03.11.2015, 15:46
Обновление. Перевел пятую главу.

Все отлично, кроме "текущиИ координаты"

helcril
07.11.2015, 11:15
Все отлично, кроме "текущиИ координаты"

Спасибо. На следующей неделе, по завершении перевода шестой главы, исправлю эту опечатку.

helcril
19.11.2015, 09:38
Шестая глава практически переведена, осталось немного причесать. Однако, в первый раз меня подвел встроенный ассемблер эмулятора ZX Spin. Ругается на строчку ld a,(ix), выдает "Invalid combination of opcode and operands". Не понимаю что его смущает в данной конструкции. Все же верно: загрузить в аккумулятор значение, которое находится по адресу указанному в ix, так? Скомпилировал в sjasm'е и проверил в Spectaculator - все работает нормально. Может кто подскажет, что нужно подправить, чтобы в ZX Spin заработало (он кстати, гад еще и выражения вычислять не умеет).
Второй момент: я не понял что такое аббревиатура GP в комментариях к коду (Generic Point??). Коментарии я так же выделил жирным шрифтом и оставил непереведенными. Прошу помочь с этим.
Листинг программы из этой главы в приложении.54939

megozavr
22.12.2015, 16:23
Спасибо за перевод! Набрал "простую игру" из второй главы...запустил ...вроде цвет поменялся и всё, курсор мигает и больше ничего...
Участок кода из-за которого не работало:

; Initialise coordinates.

ld hl,21+15*256 ; load hl pair with starting coords. эта начальная координата по x, оставил ld hl,21 и все заработало.
ld (plx),hl ; set player coords.

call basexy ; set the x and y positions of the player.
call splayr

Bedazzle
22.12.2015, 17:56
Спасибо за перевод! Набрал "простую игру" из второй главы...запустил ...вроде цвет поменялся и всё, курсор мигает и больше ничего...

Какой ещё курсор? :/
Скормил это sjasm-у, скомпилировалось. Запускаю в эмуле - чёрный экран с треугольничком, управляется цифровыми клавишами.



DEVICE ZXSPECTRUM48

org 25000

; Устанавливаем черный экран.
ld a,71 ; белые чернила (7) на черной бумаге (0),

; яркость (64).
ld (23693),a ; устанавливаем наши цвета.
xor a ; быстрый способ загрузить 0 в аккумулятор.

call 8859 ; устанавливаем постоянный цвет бордюра.

; Настраиваем нашу графику.
ld hl,blocks ; адрес данных UDG.
ld (23675),hl ; переменная теперь указывает на него.

; ОК, начнем игру.
call 3503 ; Процедура ПЗУ – очищает экран, открывает канал 2.

; Инициализация координат.
ld hl,21+15*256 ; загружаем в hl начальные координаты.
ld (plx),hl ; устанавливаем координаты игрока.

call basexy ; устанавливаем координаты x,y игрока.

call splayr ; выводим изображение игрока.

; Здесь основной цикл.
mloop equ $
; Стираем изображение игрока.
call basexy ; устанавливаем координаты x,y игрока.
call wspace ; выводим пробел поверх изображения игрока.

; Теперь после стирания мы можем передвигать игрока, перед тем как вывести
; его по новым координатам.
ld bc,63486 ; группа клавиш 1-5/порт джойстика 2.
in a,(c) ; смотрим какие клавиши нажаты.
rra ; крайний бит = клавиша 1.
push af ; запоминаем значение.

call nc,mpl ; если была нажата, двигаем влево.

pop af ; восстанавливаем аккумулятор.
rra ; следующий бит (значение 2) = клавиша 2.
push af ; запоминаем значение.

call nc,mpr ; если была нажата, двигаем вправо.

pop af ; восстанавливаем аккумулятор.
rra ; следующий бит (значение 4) = клавиша 3.
push af ; запоминаем значение.

call nc,mpd ; если была нажата, двигаем вниз.

pop af ; восстанавливаем аккумулятор.
rra ; следующий бит (значение 8) считывает клавишу 4.

call nc,mpu ; если была нажата, двигаем вверх.

; После передвижения игрока можем снова отобразить его.
call basexy ; устанавливаем координаты x,y игрока.
call splayr ; выводим игрока.

halt ; задержка.

; Переходим на начало основного цикла.
jp mloop

; Движение игрока влево.
mpl
ld hl,ply ; запомните, y координата по горизонтали!
ld a,(hl) ; каково текущее значение?
and a ; оно равно нулю?
ret z ; если да – мы не можем больше идти влево.
dec (hl) ; вычитаем 1 из координаты y.
ret

; Движение игрока вправо.
mpr
ld hl,ply ; запомните, y координата по горизонтали!
ld a,(hl) ; каково текущее значение?
cp 31 ; это правый край экрана (31)?
ret z ; если да - мы не можем больше идти вправо.
inc (hl) ; прибавляем 1 к координате y.
ret

; Движение игрока вверх.
mpu
ld hl,plx ; запомните, x координата по вертикали!
ld a,(hl) ; каково текущее значение?
cp 4 ; это верхний край экрана (4)?
ret z ; если да – не можем двигаться выше.
dec (hl) ; вычитаем 1 из координаты x.
ret

; Движение игрока вниз.
mpd
ld hl,plx ; запомните, x координата по вертикали!
ld a,(hl) ; каково текущее значение?
cp 21 ; это нижний край экрана (21)?
ret z ; если да – не можем двигаться ниже.
inc (hl) ; прибавляем 1 к координате x.
ret

; Установка координат x, y для позиции игрока.
; Эта процедура вызывается перед выводом и стиранием изображения игрока.
basexy
ld a,22 ; управляющий ASCII-код AT.
rst 16
ld a,(plx) ; x координата игрока.
rst 16 ; устанавливаем ее.
ld a,(ply) ; y координата игрока.
rst 16 ; устанавливаем ее.
ret

; Вывод игрока в текущей позиции печати.
splayr
ld a,69 ; голубые чернила (5) на черной бумаге (0),
; яркость (64).
ld (23695),a ; устанавливаем наши временные цвета.
ld a,144 ; ASCII-код для символа UGD 'A'.
rst 16 ; выводим изображение игрока.
ret

wspace
ld a,71 ; белые чернила (7) на черной бумаге (0), яркость (64).
ld (23695),a ; устанавливаем наши временные цвета.
ld a,32 ; символ пробела.
rst 16 ; выводим пробел.
ret

plx defb 0 ; x координата игрока.
ply defb 0 ; y координата игрока.

; UDG графика.
blocks defb 16,16,56,56,124,124,254,254 ; изображение игрока.


SAVESNA "program.sna",25000

helcril
23.12.2015, 08:57
Спасибо за перевод! Набрал "простую игру" из второй главы...запустил ...вроде цвет поменялся и всё, курсор мигает и больше ничего...
Участок кода из-за которого не работало:

; Initialise coordinates.

ld hl,21+15*256 ; load hl pair with starting coords. эта начальная координата по x, оставил ld hl,21 и все заработало.
ld (plx),hl ; set player coords.

call basexy ; set the x and y positions of the player.
call splayr
Пожалуйста. Жаль, что переводить в более быстром темпе никак не получается. Все дело в том, что встроенный ассемблер ZX Spin не умеет вычислять выражения, поэтому здесь необходимо поставить конкретное число 3861. Тогда все будет ОК.

megozavr
23.12.2015, 09:52
встроенный ассемблер ZX Spin не умеет вычислять выражения
Я так и понял) Ждем новых глав!!!

helcril
11.01.2016, 05:44
Обновление. Перевел шестую главу. Еще раз попрошу людей разбирающихся помочь с переводом комментариев к коду:
GP x area.
GP y area.
set up GP y coord.
Сам я так и не разобрался для чего эти строчки, а самое главное, что здесь означает GP?

Bedazzle
11.01.2016, 07:41
а самое главное, что здесь означает GP?

Не вникал. Может, "graphics primitive"?

helcril
11.01.2016, 09:50
Не вникал. Может, "graphics primitive"?

Спасибо, жду еще вариантов.

Sameone
12.01.2016, 18:01
Там вроде бы описывается перемешение главного героя? Тогда General Personage.

helcril
12.01.2016, 18:33
Там вроде бы описывается перемешение главного героя? Тогда General Personage.

В этой части кода - перемещение сороконожки, насколько я понимаю.

goodboy
12.01.2016, 18:44
В этой части кода - перемещение сороконожки, насколько я понимаю.
правильно понимаешь
скорее всего GetPosition

Sameone
12.01.2016, 23:07
Я по диагонали глянул, не вникал что за игра. Да, GetPosition лучше. Там как раз запоминаются координаты в BC перед передачей управления.
А зачем в книге перепутаны x и y координатные оси относительно общепринятых?
Перед переходом на segml мы же сохранили координаты в ВС, зачем сразу после него опять читать y их памяти? Он же есть в BC, и ld a,b лучше чем ld a,(ix+2).
Затем, проверив достижение левой границы экрана, мы уменьшаем аккумулятор и записываем его в B. Но ведь можно сразу dec B?
Да, и почему там где проверяется возможность движения сороканожки влево -- написано look right? т. е. смотри вправо?

Bedazzle
13.01.2016, 00:38
А зачем в книге перепутаны x и y координатные оси относительно общепринятых?

Про это в начале книги автор пишет особо, что он так привык.

goodboy
13.01.2016, 11:01
segmov ld a,(ix+1) ; x coord.
ld c,a ; GP x area.
ld a,(ix+2) ; y coord.
ld b,a ; GP y area.
ld a,(ix) ; status flag.

проще
ld c,(ix+1)
ld b,(ix+2)

helcril
22.01.2016, 04:59
Обновление. Переведена седьмая глава.

В этой главе меня заинтересовал один вопрос. Джонатан предлагает в качестве менее жесткой проверки на столкновение использовать алгоритм, с "отсечением" углов спрайтов. Так вот мне очень интересно на каком геометрическом принципе это основано? Пытался понять сам - так и не получилось. :v2_confu::v2_laugh: Если кто знает - объясните пожалуйста, желательно с картинкой!

goodboy
22.01.2016, 10:23
Джонатан предлагает в качестве менее жесткой проверки на столкновение использовать алгоритм, с "отсечением" углов спрайтов. Так вот мне очень интересно на каком геометрическом принципе это основано? Пытался понять сам - так и не получилось.
геометрия и `отсечение` углов тут совсем не-причём, ты как-то очень заумно всё представил.

если расстояние между двумя спрайтами меньше их общей ширины то они столкнулись (наложились)
(тут надо вспомнить алгебру - метод интервалов)

http://xnafan.net/wp-content/uploads/2013/04/image20.png

отсечение углов применяется когда спрайт занимает не целое знакоместо (рассматривается его фактический размер в пикселях)

helcril
22.01.2016, 11:43
геометрия и `отсечение` углов тут совсем не-причём, ты как-то очень заумно всё представил.


отсечение углов применяется когда спрайт занимает не целое знакоместо (рассматривается его фактический размер в пикселях)
Спасибо, но там же как раз об этом и идет речь. В конце главы. Именно об этом я и спрашиваю.
А тот принцип, что на картинке, я вроде и сам понял.

goodboy
22.01.2016, 12:39
http://docs.yoyogames.com/source/dadiospice/001_advanced%20use/more%20about%20sprites/basic_collisions_image.png

goodboy
22.01.2016, 13:17
Всегда вычислял след образом
xli=max(xl1,xl2)
xri=min(xr1,xr2)

возможно я объяснил косноязычно, но что у тебя вычисляется в скобках мне тоже непонятно.

goodboy
22.01.2016, 13:45
для простых объектов (допустим кубики 16х16) рассчёт столкновения (как у Джонатана) на-бейсике выглядит так

IF ABS (x1-x2) < l then collision

helcril
22.01.2016, 13:53
А к чему эта картинка? В примере программы из гайда же маска не используется.

goodboy
22.01.2016, 13:58
А к чему эта картинка? В примере программы из гайда же маска не используется.
как пример для алгоритмов Джонатана.

helcril
22.01.2016, 14:17
как пример для алгоритмов Джонатана.
Видимо, какое-то недопонимание происходит. Как выглядит столкновение не квадратных спрайтов мне понятно.
Непонятно как работает вот это:


; Check (l, h) for collision with (c, b), cutting corners.

colc16 ld a,l ; x coord.
sub c ; subtract x.
jr nc,colc1a ; result is positive.
neg ; make negative positive.
colc1a cp 16 ; within x range?
ret nc ; no - they've missed.
ld e,a ; store difference.

ld a,h ; y coord.
sub b ; subtract y.
jr nc,colc1b ; result is positive.
neg ; make negative positive.
colc1b cp 16 ; within y range?
ret nc ; no - they've missed.

add a,e ; add x difference.
cp 26 ; only 5 corner pixels touching?
ret ; carry set if there's a collision.

Т.е. формула в конце алгоритма такая:
|(x1-x2)+(y1-y2)|<=25 то столкновение считается, если больше, то нет.
Мне не код непонятен, а именно геометрический (?) принцип лежащий в основе него. Я так понимаю, что манипулируя вот этим числом (в данном случае 25) можно изменять размер отсекаемых углов. Поправьте меня, если я что-то не так понял.

goodboy
22.01.2016, 21:43
как в анекдоте "1/2+0.5=? нутром чую что литр, а доказать немогу"
специально по-пути домой купил тетрадку в-клеточку.
формула работает, осталось доказать зависимость суммы разницы координат

helcril
23.01.2016, 09:20
как в анекдоте "1/2+0.5=? нутром чую что литр, а доказать немогу"
специально по-пути домой купил тетрадку в-клеточку.
формула работает, осталось доказать зависимость суммы разницы координат
Примерно мои мысли и действия описаны :v2_laugh:

Sinner
09.01.2018, 18:18
Только сейчас вспомнил, что давеча скачивал эту книгу - было переведено 4 главы - до "Случайных чисел" включительно. С английским оригиналом точность не сравнивал - каюсь, слабо и долго читаю английский текст, сноровка не велика - но ваша версия читается и воспринимается прекрасно. Спасибо.

Reobne
09.01.2018, 18:44
Т.е. формула в конце алгоритма такая:
|(x1-x2)+(y1-y2)|<=25 то столкновение считается, если больше, то нет.
Не модуль суммы, а сумма двух модулей.
|(x1-x2)|+|(y1-y2)|<=25
Для координат x1 и y1 эта область - ромб, с диагоналями параллельными осям, центром в точке (x2,y2) и длиной полудиагонали 25.