Прежде всего. Насколько Вы знаете машину? Понимаете, выучить Ассемблер очень легко! ![]() А пользоваться им для программирования (о-о-очень трудно). Дело в том, что, не зная до тонкостей машины (процессор, ПЗУ, ОЗУ, OS, DOS и пр. И как эта вся 'нелюдь' работает?) Вы не будете знать, где Вы находитесь и куда идти. Если Вы не знаете, для чего ячейка 88, Вы не будете знать как её применять. ![]() Если Вы даже знаете для чего какая-то ячейка, но не знаете как она обрабатывается операционной системой 'по умолчанию', Вы всё равно не будете знать как с ней работать. Начать надо с удивления тому, что комп не умеет НИЧЕГО, кроме как перегонять биты из одного места в другое!!! Вычисления и 'побочные действия' (например прорисовка экрана) получаются при алгоритмизации этого процесса, то есть при применении ВНЕШНИХ, по отношению к процессору правил!!! Pioneer 1910. Светадиод и 220. Panasonic tx-32le8 схема. Как разобрать принтер epson R220. Dex 271 прошивка. Схема релевизора РЕКОРД. Что делать, если стиральная машина не переключает режимы. Если вопросы будут - отвечу. Всё, что содержит информацию МОЖЕТ! Либо помочь, Либо помешать. Давайте пытаться программиривать. Ну, начнём, помолясь. Я в ассемблере программировал только на MAC/65, поэтому и инструкции ассемблера будут для MAC/65. Чтобы всё было интересно сразу раскрою тайну. Программировать будем статусную строку для состояния консоли. Консольные клавиши в Атари - это START,SELECT,OPTION. Общая идея такова: 1. Сначала добавим статусную строку и увидем её на экране. Она должна заполняться не меняя нашей работы с Атари. Вот и начнём. Есть такая фишка в Атари, которая называется Дисплей Лист. Это - место в памяти, в котором лежат инструкции по отображению данных, которые исполняет ANTIC (Alphanumeric Television Interface Controller - Знако-Цифровой Контроллер телевизионного интерфейса). Стандартный DLIST таков: > dlist BC20: 3 раза по 8-BLANK BC23: MODE 2 + LMS(BC40) BC26: MODE 2 (23 раза) BC3D: JVB BC20 Утомлю командами ANTIC для DLIST. Они аддитивны, то есть их можно и нужно (с участием моска!) складывать. Кроме этого, нужно вспомнить, что обычная текстовая строка Атари состоит из 8 заполненных растровых линий TV! 8 ЛИНИЙ РАСТРА!); Display List Commands;; ПРОБЕЛЫ - (незаполненые растровые линии телевизора/ЛУЧ ВЫКЛЮЧЕН - например, черная область выше голубого экрана!) BL1=$00 BL2=$10 BL3=$20 BL4=$30 BL5=$40 BL6=$50 BL7=$60 BL8=$70;; СТРОКИ - неважно текстовые, или графические, но, выводящие на экран данные из экранной памяти. GR* - это режимы Бейсика AN* - это режимы ANTIC, недоступные для Бейсика. GR0=$02 AN3=$03 AN4=$04 AN5=$05 GR1=$06 GR2=$07 GR3=$08 GR4=$09 GR5=$0A GR6=$0B ANC=$0C GR7=$0D ANE=$0E GR8=$0F;; ПЕРЕХОДЫ - так как, даже если мы ничего не делаем на Атари, всё равно надо прорисовывать экран, а также и по многим другим причинам, неоюходимы переходы с конца прорисовки на начало - по циклу, или всякие другие. JTO=$01 - Jump To(далее Адрес!) - переход на конкретный адрес экранной памяти. JVB=$41 - Jump by Vertical Blank(далее Адрес!) - Переход по дефолту на начало экранной памяти, если прорисован весь экран, для постоянной прорисовки экрана.;; ДЕЙСТВИЯ HSC=$10 - Включение оборудования горизонтального скроллирования VSC=$20 - Включение оборудования вертикального скроллирования LMS=$40 - Load Memory Scan - Включение прорисовки экранной памяти. LIN=$80 - Display List Interrupt - Включение прерывания со следующей строки сканирования. Обычную текстовую строку над голубеньким экраном, но так, чтобы Атари её не замечал. Есть - и есть. Вот это и есть - наша глобальная задача. Посмотрим стандартный DLIST (выше.) Там сверху непрорисованных 24 линии сканирования, то есть 3 раза по BL8. (8+8+8)=(8+7+8(здесь появится НАША текстовая строка, а не пробельные строчки сканирования)+1) Вот такой NEWDL мы и начнём. А что ждём-то? Это же данные, а не ассемблирование! Их так и так надо вносить. Обиняки: Будем кодить в выделенном месте для программирования пользовательских программ на ассемблере! Потом, уже задумаемся, куда всё поместить. Запускаем MAC/65 Увидели на экране Edit Пишем ручками: NUM 1000,10 - нумерация от 1000 с шагом 10 Получаем: 1000 Дописываем: 1000 CODES *=$0600 1010 Звёздочка - это состояние PC - Program Counter, то есть ГДЕ мы находимся при ИСПОЛНЕНИИ программ. Здесь призадумаемся. Нам нужна инициализация многих подпрограмм, значит - ДО исполнения, а именно в этом месте нужно перейти к ней. В этом случае ассемблер будет знать Что,Где,Когда! Итак, 1000 CODES *=$0600 1010 JMP INIT - прыгаем на INIT. Получаем: 1000 CODES *=$0600; Адрес начала кодов 1010 JMP INIT; Адрес инициализации. 1020 Что мы знаем? Задали метку CODES, Это пользовательская 6 страница! Начинаем с $0600 (Переходим на INIT, - пока не задали!) Вот здесь мы упёрлись в структуризацию программы! Начало тупое - START Инициализация данных всех подпрограм - INIT Объявление всех системных адресов - EQUATES Объявление всех системных векторов - VECTORS Объявление всех наших констант - CONSTANTS (Эти данные сугубо необходимы для того, чтобы ассемблер хоть что-то понял.) Далее идут исполняемые Коды - CODES А здесь прервёмся. Я уже тексты утомился писать. Сохранись в Ассемблере Бра! SAVE #DL.m65 Я буду писать помаленьку. Двигаемся потихоньку. 'Кривые руки - причина боли моска!' В прошлом уроке сразу ошибка. Надо: SAVE #D: DL.M65 Пардон, но всё же назову CODES -> START так привычнее. 1000 START *=$0600 В редакторе эта строчка перепишет прежнюю. Кстати, Эта команда - инструкция для MAC/65, а не для процессора. Первая инструкция для процессора, которая будет помещена на 6 страницу - 1010__JMP INIT. Специально выделил 2 пробела перед JMP! Если один пробел -> это будет воспринято как МЕТКА! 1000 START *=$0600 1010 JMP INIT 1020; 1030 NEWDL.BYTE BL8,BL7 1040.BYTE GR0+LMS 1050.WORD DLDATA Вот здесь включаем моск! MAC/65 при компиляции сразу выдаст ошибку фазирования, так как DLDATA ещё не определена нигде! Увы, надо исправлять! Не, на самом деле ATARIKI маленько отбезобразничал. Я ранее писал, что Если один пробел после начальной цифирки -> это будет воспринято как МЕТКА! То есть Ассемблер ждёт какого-то невиданного. Невиданной программы JMP! Ответ - для Ассемблера ПРОСТ! У него невиданный только Макрос. А теперь к делу. Поблагодарю GOODBOY, надо! Поблагодарю ATARIKI - он Аудитория! Я с Вами ОДНОВРЕМЕННО программирую! И я - не программист. И потом, Если мы только ввели и сохранили данные, а не программу, разве мы написали программу? НАДО включать моск! На этом этапе компилировать НЕЧЕГО! Обработчика данных НЕТ! Просто пишем и сохраняем. Ассемблер определяет инструкции по отступам. Сайт отступы уничтожает. Уж, поверьте, мой текст был другим. То, что программа выполняется чисто, я проверил в мониторе. Вот старый DLIST > dlist 9C20: 3x 8 BLANK 9C23: LMS 9C40 MODE 2 9C26: 23x MODE 2 9C3D: JVB 9C20 Вот новый DLIST > dlist 202B: 8 BLANK 202C: 7 BLANK 202D: LMS 2003 MODE 2 2030: 1 BLANK 2031: JMP 9C23 9C23: LMS 9C40 MODE 2 9C26: 23x MODE 2 9C3D: JVB 202B Как видно, всё как мы и хотели. - - - Добавлено - - - 2Atariki. Отвечая на Ваш вопрос, скажу следующее. Да, в Атари существуют поименованные ячейки памяти. Каждая такая ячейка имеет уникальное имя и связанную с ней функцию. Из таких мы в программке использовали только две. SDMCTL - Shadowed Direct Memory Control Теневой регистр управления Прямым Доступом к памяти. Если в него внести число #$00 - прямой доступ к памяти выключается. Если внести число #$22 - прямой доступ к памяти включается. SDLSTL/SDLSTH - Shadowed Display LiST Это системный указатель на начало Дисплейного Листа. По поводу Ассемблирования скажу честно. Пока не напишешь тыщу тонн кода - не научишься. Раньше программировали в Машинных Кодах. Вот наша программа в машинных кодах: > m 2000 (Смотрю в мониторе начиная с адреса загрузки программы, то есть $2000) 2000: 4C 34 20 00 00 23 6F 6E 73 6F 6C 1A 00 0F 33 74 L4.#onsol.3t 2010: 61 72 74 0F 00 0F 33 65 6C 65 63 74 0F 00 0F 2F art.3elect./ 2020: 70 74 69 6F 6E 0F 00 00 00 00 00 70 60 42 03 20 ption.p.B. 2030: 00 01 23 9C A9 00 8D 2F 02 AD 30 02 85 C0 18 69.#./.0.i 2040: 03 8D 32 20 AD 31 02 85 C1 8D 33 20 A9 2B 8D 30.2.1.3.+.0 2050: 02 A0 1E 91 C0 A9 20 8D 31 02 A0 1F 91 C0 A9 22..1.' 2060: 8D 2F 02 60 00 00 00 00 00 00 00 00 00 00 00 00./.. Ничего утешительного, не правда ли? Тем не менее, идея ассемблирования очень проста - заменить цифры Машинного Кода запоминающимися знако-сочетаниями. Проделаем эту процедуру. $4C $34 $20 - Это и есть наша первая команда JMP INIT Здесь $4C - JMP, а адрес $2034 (в памяти лежит наоборот, то есть младший байт первый.) это вычесленный ассемблером адрес INIT. Проверим так ли это? По этому адресу лежат байты $A9 $00, а это и есть LDA #$00, как в нашей программе. Да, кстати, впервые вижу книжку по Атари на Русском. На железном ATARI верх и низ экрана смещены в сторону, вобщем отображается некорректно, в эмуляторе после загрузки уходит в self test 56334 - - - Добавлено - - - да, rts в конце убрал скомпилил и на 'железе' всё стало норм. Естественно, rts - выход в Бейсик или в никуда. Какой-то левый DLIST у тебя сначала три по 112 - пустые или blank линии, потом это байт из $40+режим ANTICтаблица (вслед за байтом идет слово - адрес, где в памяти хранятся данные. Следующие байты - это режимы ANTIC, например 23 байта 2 - текстовый режим последние $41 и слово - адрес начала инструкции DLIST Адреса инструкций помещаются в ячейки $230(мл. Байт адреса) и в $231(ст. Байт) Читай memory mapping или кинь мне в личку, если надо, я залью, сидеть на форуме некогда. В общем, непонятно с кодом и лево сделано. Проще сделать.XEX в atasm так:.bank *=$2000; тут весь код lda #dliadr&255 sta $230 lda #dliadr/256 sta $231 jmp *;зациклили на время dliadr.byte $70,$70,$70.byte $42;режим стандартный GR.0.word $3000; данные берутся с адреса $3000.byte 2,2,2;всего 23.byte $41;инструкция ожидания и перехода к началу.word dliadr.bank *= $02E0.word $2000 $2E0 - адрес автостарта программы. Как сделать в MADS - я не знаю. Denpopov, привет! Ну Вы же знаете, что команды Ассемблера к Бейсику не могут иметь НИКАКОГО отношения. RTS - Это выход в вызывающую подпрограммуу, а именно, на тот адрес, который следует за вызовом, то есть в случае загрузки программы DOS-ом, мы остаёмся в Цикле исполнения DOS-а!!! Я так понимаю, что Вы все Балуетесь со XEX-ами, но файлы XEX - Это просто переименованые файлы COM. АБСОЛЮТНО ничего более. То есть, если у Вас не загружен сам ВЫЗЫВАЮЩИЙ программу ДОС, а вызывает её ЭМУЛЯТОР, к чему же Вы можете вернуться? У меня прекрасно и в эмуле и в HW всё работает до сих пор. У меня прекрасно и в эмуле и в HW всё работает до сих пор Вы просто счастливчик) я до сих пор не могу подключить рабочую Атари 130ХЕ к ТВ. Ну Вы же знаете, что команды Ассемблера к Бейсику не могут иметь НИКАКОГО отношения. RTS - Это выход в вызывающую подпрограммуу, а именно, на тот адрес, который следует за вызовом, то есть в случае загрузки программы DOS-ом, мы остаёмся в Цикле исполнения DOS-а!!! Что Вы говорите? При вызове USR из Бейсика на стеке помещаются: номер параметров и параметры, т.е A=USR(1536,8,7) на стеке даст 2,8,7. Поэтому обычно ассемблерная часть выглядит как PLA. Немножко кода. RTS Вызов ассемблерных процедур из Бейсика реализуем, например можно перевести опкоды в символы ATASCII и вызвать как мы делали A=USR(ADR('строка')) g0blinish писал (подобный пример. Заодно выполнять RTS на непонятной среде - это моветон. Я всё думал, что же Вы спрашиваете. Пришёл к выводу, что Вас интересует не программирование, которое Вы знаете, а сама работа с MAC/65. Ну там команд-то, конечно много. Я использую пару из них. Я работаю в эмуле Atari800WinPlus 4.1 Помаленьку пользуюсь его преимуществами, которых (Don't kill me ZEman!!!) нет у Altirra. (Я печатаю свои программы, когда мне нужно подумать над кодом.) Загрузка кодов в ТЕКСТОВОМ ФОРМАТЕ. ENTER #H6:CONSOL.LST - Загрузка файла листинга в текстовом формате с устройства, которое само перекодирует ASCII в ATASCII. И для сохранения ТЕКСТА: LIST #H6:CONSOL.LST (Реально есть устройство H1:, которое НЕ ПЕРЕКОДИРУЕТ. С него *.com можно загрузить. И его Зеркальное устройство, которое ПЕРЕКОДИРУЕТ различия в кодировках - H6.) Надо задать настройки, например C: ATARI HDD -> H1: И всё. Загружать данные с жесткого диска могут всего несколько ДОСов. AtariDOS 3, или 4 (не помню), Sparta (Все версии, с которыми я встречался.) и по моему OSS DOSXL или ДОС XE (тоже не помню). Больше ничего! Естесственно забыл MyDOS! Он ТОЖЕ МОЖЕТ работать с жестким диском. Лучше многих! Я работаю со SPARTA3.3A, потому-что к нему есть Shell33а- та программка, которая ДЕРЖИТ в ОЗУ 2 директории, которые я сам задаю. В этом случае я обращаюсь и к системным утилитам и к программам, которые мне нужны без определения путей доступа. Для быстрой загрузки и быстрого программирования я использую команды: SAVE D1:CONSOL.M65 LOAD D1:CONSOL.M65 Эти команды работают не с текстом, а с токенами. 2Denpopov Да никакой я не счастливчик. Когда у меня моя родная Атарька сдохла, из-ха недостатка времени и кривых рук, я не стал с ней возиться и у B&C купил материнку. Они при правильном моём обращении не засунули меня в стоплист, что любят делать, и прислали мне счастье. Я не очень понимаю, почему у Вас страдает вывод на экран. Мне пришлось купить монитор, SONY PVM, чтобы как-то беспроблеммно с Атарькой работать. Я сигнал по S-Video вывожу. Поверьте, работу со стеком в Бейсике я знаю. Знаю также интерфейсы к многим Си-языкам. В любом случае возврат из подпрограммы ведётся куда-то! Ну, в случае с xex, он ведётся. Доса и Бейсика-то НЕТУ! Ну, не загружены они! - - - Добавлено - - - 2Atariki Да, можно, но я ваще никогда его не делал. У меня есть SnagIt, который, вроде позволяет. Моя Атарьская PC-шка очень слабенькая она вообще полуживёт. Давайте думать об этом, как о проекте. Atariki, Здравствуйте. Значит, до сих пор мы решили только одну задачу. Применили наш кастомный Дисплей лист к читанию консоли. Мы показали, что он работает. Мы показали, что он НЕ ТРОГАЕТ РАБОТУ АТАРИ, так как там можно и вызывать программы (Которые своего дисплей-листа не имеют и работать с ДОСом и т.д.) Мы показали, что программировать ВЕСЕЛО! Задача - считать содержимое регистра Консоли отличается от задачи - вывести ТО, ЧТО хотим, на нашу статусную строку. Когда не можешь запрыгнуть на следующую лестничную площадку, надо идти по ступенькам. Не будем трогать то, что уже работает. Начнём новую программку, которая будет работать и чтобы это можно было бы проверить! Как в первой. Вот мы имеем Разные статусные строки в количестве 8. (Они ВСЕ могут быть правильно выведены нашей предыдущей программой!) Заглавные буквы будут означать ИНВЕРТИРОВАНИЕ символов (высветление). Статусные строки: L7.SBYTE ' Consol: /Start/ /Select/ /Option/ ' L6.SBYTE ' Consol: /START/ /Select/ /Option/ ' L5.SBYTE ' Consol: /Start/ /SELECT/ /Option/ ' L4.SBYTE ' Consol: /START/ /SELECT/ /Option/ ' L3.SBYTE ' Consol: /Start/ /Select/ /OPTION/ ' L2.SBYTE ' Consol: /START/ /Select/ /OPTION/ ' L1.SBYTE ' Consol: /Start/ /SELECT/ /OPTION/ ' L0.SBYTE ' Consol: /START/ /SELECT/ /OPTION/ ' Других выборов из этого списка у нас нет. Я забыл раньше сказать, что в Атари (Это её особенность!).SBYTE - это команда прорисовать экранный байт. О работе Ассемблера. MAC/65 Двухпроходный! В первый проход он запоминает ВСЕ!!! (По Адресам!) метки, поэтому наши метки L* ему ВСЕ известны. Правило Little Endian указывает, что там берётся младший байт двухбайтового слова. Это было исследование. А вот теперь перейдём к Ассемблированию. Так как мы знаем, что Ассемблер УЖЕ (в первый проход прочёл все метки, мы уже можем обращаться с ними как с ДАННЫМИ.) Давайте сделаем таблицу сдвига по нашей таблице Статусных строк. TXTTAB.WORD L7,L6,L5,L4.WORD L3,L2,L1,L0 Что мы видим?.WORD - означает двухбайтовое СЛОВО в порядке LSB/MSB Значит мы создали АССЕМБЛЕРОМ - он же вычисляет это в первом проходе!!! Таблицу адресов. А взять из таблички адреса и подставить их в место где происходит LMS - сканирование (и, конечно, прорисовка) экранной памяти, это - не наша забота. Этим ANTIC занимается. Мы - меняем Адреса! Ну, и давайте. Сначала теория. Если я делаю ASL - значит я умножаю маленькое число на два. Спросите для чего? Адреса хранятся в ДВУХ ячейках и мы просто должны перескакивать на 2 байта. Маленькое число - это то, которое между 0 и 127. ПРОШУ ВАС ПРОВЕРЬТЕ! На виндосном калькуляторе. Над любым МАЛЕНЬКИМ числом сделайте ASL и нажмите равно. Вы получите это число, умноженное на два. А у нас цифра - всего 7! Поэтому без обиняков и смело! Вот тут мы и начнём программировать! Я жутко устал. Спокоси Носи! Вот готовая программа. Консоль работает! Самое странное, с чем столкнулся - это с тем, что некоторые версии MAC/65 не поддерживают символа подчёркивания. Ничего страшного. Можно заменить в тексте какой нибудь буковкой. Что - то я не могу всё это переварить ((( да все просто, но замороченно. Программа инициализирует прерывание VBlank(прерывание перед каждым кадром), сам вектор опрашивает значение ячейки CONSOL( адрес $D01F) и выводит строку на экран, что нажато из клавиш - Start/Select/Option. Параллельно формируется DisplayList, который состоит из двух частей: одна адресована для строки состояния и переход на 'остаток' Display List. Читай Atari Mapping, которую я тебе перезалил и сопоставь с русской версией, которую ты выложил.Качество скана паршивое, конечно, но разобраться можно. Один вопрос: что ты хочешь? Просто так изучить бесполезно имхо. А вот написать игрушку - это другое. Ну что то типа бегающего сантехника, который чинит поломанные трубы и ему мешают там всякие нехорошие персонажи ну и в конце надо замесить босса и выйти победителем. Игра типа комнаты, можно добавить интересностей типа нашёл ключ, открыл сейф, собрал узел - унёс установил. Всякие там преграды типа: вот тут идёт пар, нужно уйти туда-то закрыть вентиль и потом отремонтировать. Игра начнётся глубоко внизу и перс будет подниматься выше и выше, когда он всё починит на верху стоит завод и он заработает. Смесь Scooter, Monty и Spy vs Spy. Можно ещё добавить дикого электрика, который будет кидать фазу 'как бы случайно' на трубы и перса будет бить током вычитая немного жизни. Я начинал с того, что записывал правила, не придуманные мной, а прошитые в Атари. Обязательно на какой-то ножке микросхемы, но не на сигнальных! Контакты устройств выводятся через защитные цепи на ножки микросхемы. - Если управляющий замыкатель разомкнут, значит на ножке микросхемы обязательно будет ~+5V. - Если управляющий замыкатель замкнут, значит на ножке микросхемы обязательно будет ~0V. Как говорят автомобилисты, 'из-за замыкания искра ушла в землю'. Чтобы установить VBI прерывание по 'обратному ходу луча', нужно строго выполнить следующие действия: в A засунуть тип прерывания Немедленное или отложенное, то есть 6 или 7 в X засунуть старший, а в Y- младший байт адреса, обработчика VBI, написанного нами И запустить программу применяющую эти данные для установки прерывания SYSVBV/XITVBV(для отложенного) чтобы беспроблемно установить наше VBI. Таких правил тыща и чтобы понять значение каждой требуется немалое время, работоспособность и терпение. Для игры Вам может понадобиться джойстик, так я могу предоставить очень красивую ассемблерную программу, расшифровки его данных в VBLANK и предоставляющую данные смещений по осям X и Y для перемещающихся объектов. Все правила для всех портов Атари одинаковые, поэтому Вы можете ТОЧНО сказать, что на любом сигнальном бите порта Джойстика всегда будет единица, если он в нейтральном положении. Ну и как всегда, я посоветовал бы писать игры на PL65. Он обладает неоспоримыми преимуществами. Его библиотеки написаны в тексте, а значит могут изменяться любым программистом по СВОЕМУ усмотрению! В нём есть встроенный ПОЛНОЦЕННЫЙ однопроходный, увы, ассемблер. (Однопроходный, значит, что уже к режиму Ассемблирования, он должен знать ВСЕ данные, необходимые в режиме Исполнения.) 3. В нём есть Встроенный редактор кодирования 4. В нём есть Указатели! И ко всему прочему, это - ОДНА программа, не выходя из которой можно всё и написать. Работать с ним - высочайшее удовольствие!!! Я бы хотел, но не умею, написать 'Логистическую стратегию'. Они бывают в разном жанре, но общий принцып - доставь то, что нужно к нужному моменту. Или накачай здоровья или накачай умений(тупо, разведай больше.) или накачай защиты или набери силушки. Я без устали играю в парочку-троечку (и более) таких - Earn 2 Die Learn 2 fly Crash of Castles (Там ещё много вычислений по Ньютоновской физике) Всякие ARENA (Взял дубинушку - веселее стало!) Последняя любовь - Swards and Souls! Там клёвый пошаговый геймплей. Если позаботился о счёте в Банке и он не пуст - он растёт. С каждым уровнем больше. То есть если я уже не могу ничего, то попробую после того как выпью кофе. Может новую Дубинушку куплю. Давайте напишем Трояна для Атари. То есть программу, которая исполняля бы НАШ код, а Атари и не знала бы об этом. Что мы имеем в виду под 'не знала'? То, что Атари свой родной код всё равно исполняла бы, а потом незаметно для себя и наш. Наш Троян безобидный. Пусть он меняет цвет экрана с их голубого на наш красный. Начнём: Опишем ячейки памяти Атари, существенные для нас.; Fully saved Trojan inserted to WARMSTART;; EQUATES DOSINI = $0C COLOR2 = $02C6 MEMLO = $02E7;; CONSTANTS RED = $32 Далее зададим опции компилятора, чтобы он компилил в ПАМЯТЬ и выдавал нам полный листинг. (Неполный листинг нужен, если мы будем использовать библиотеки компилятора. То-есть, будут печататься каждый раз сначала библиотеки, а потом только наша маленькая программка. Кому это надо?); ASM OPTIONS.OPT OBJ,LIST; Пусть пишет в память объектный код и по требованию выдаёт полный листинг программки. Теперь напишем наш Троян. (Сначала функционально, потом, чтоб работал.) Функционально нам нужно изменить цвет. LDA #RED STA COLOR2 Но эта станза будет сразу же затёрта инициализацией горячего старта при нажатии Reset! А вот это уже не троян! Придётся либо искать всегда сохранную память в Атари, которая не инициализируется при горячем старте. Или писать свой код. Пойдём по лёгкому пути, тем более, что это не сложно. Теория: Разница между JMP и JSR JMP является ЕДИНСТВЕННОЙ инструкцией, среди инструкций 6502, использующей косвенную адресацию непосредственно! То есть, для работы ей нужен только Аккумулятор и адрес памяти. Так как комп ЗНАЕТ!, что адресация косвенная и адрес может быть задан ТОЛЬКО при инициализации, то он ждёт второго прохода ассемблера и Фазовую ошибку не вызывает. Для работы всех остальных инструкций ещё нужен стэк. Например, JSR ТРЕБУЕТ, чтобы данные адреса были занесены в стэк. Поэтому, если до момента вызова инструкции JSR, не было явного определения и инициализации адреса, в стэк НЕЧЕГО заносить! Возникает фазовая ошибка. Из всего этого мы должны понять, что если возникает фазовая ошибка, значит виноваты все команды перехода, которые не могут найти адрес перехода, либо явно, как заданный Глобально - EQUATES, VARIABLES, либо как метки, которые должны быть описаны РАНЕЕ вызова команды. Ошибка будет, если они описаны ПОЗДНЕЕ! Вот при этих гнусных условиях нам и придётся работать. Нам нужна ВЕРА! АССЕМБЛЕР МОЖЕТ ВСЁ! Обшая идея такая. Я хочу, чтобы начиная со старого (заведомо рабочего) адреса, до которого докатилась Атари, занести коды трояна, после чего, Перенести указатель на прежний 'заведомо рабочий адрес' на конец моих кодов! И тогда, программа инициализации по Ресет затронет ВСЁ, кроме моих кодов. Ясно, что если я исполню свою идею РАНЬШЕ, чем произойдёт нормальная инициализация по горячему старту, то когда она произойдёт она всё ЗАТРЁТ! Надо, чтобы сначало Атари сделала по-своему, а потом, уж.!!! Да, и ешё, важно держать свои ЗНАНИЯ 'при себе'! То есть ДАННЫЕ по инициализации ТРОЯНА должны быть в нём сАмом! Чтобы узнать адрес с которого я могу действовать, я вызываю комманду SpartaDOS X33A (Без БАТФАЙЛОВ!!!). MEM Memlo: $1900 Memhi: $BC1F То-есть, я могу пользоваться памятью насиная с $1900 Я и начну. START *= $1900 JMP INIT; NEWMLO.WORD 0; Это неинициализированная ПОКА переменная, которая будет; всегда сохранена, покуда мы сохраняем коды трояна. DUMMY TROJAN JSR DUMMY; JSR'у нужен DUMMY, в качестве РАНЕЕ определённой метки! До исполнения ВСЁ - просто заполненная память! Если вместо DUMMY подставить (ВО ВРЕМЯ ИСПОЛНЕНИЯ! Старый адрес DOSINI, то сначала программа выполнит полный цикл горячего старта.) А куда нам надо поднять память? 2denpopov Не уберегли, значит. Кажется кто-то упоминал, что нужна программа для обработки джойстика. Предлагаю программу Джеймса Коренталя для расшифровки положений джойстика. Я думаю, она малопонятная, но самая быстрая. Что мы думаем о джойстике? Прежде всего он замыкает контакты. Может и попарно! Все контакты джойстика нормально разомкнутые и при считывании аппаратного регистра джойстика в разрядах дают логическую ЕДИНИЦУ! При замыкании контакта, это приводит ЕДИНИЦУ к НУЛЮ! (Искра ушла в землю.) Максимум числа джойстиков для Атари - 4. В новых моделях - 2. Вот 'Роза Ветров' положений джойстика: N NW NE W C E SW SE S Всего их 9, А значит 4Joy x 9Dir = 36 предложенных данных для разбора. Вот почему в Бейсике такой разбор по значениям неприемлем! Джойстик сильно абстрагирован от программ. В частности, это означает то, что джойстик ориентируется НЕ НА ДАННЫЕ ПРОГРАММЫ, а только на свои! То есть, когда мы тянем его вниз, то в лётном симуляторе самолётик-то летит вверх, и именно это означает, что обработка данных джойстика лежит не на джойстике, а на программе! Предлагаю битовую таблицу значений для различных положений джойстика:.DIRECTION BINARY HOR VER. E W S N.Center 1 1 1 1.N 1 1 1 0.NE 0 1 1 0.E 0 1 1 1.SE 0 1 0 1.S 1 1 0 1.SW 1 0 0 1.W 1 0 1 1.NW 1 0 1 0 То есть: 1. Коренталь обратил внимание, что Атарьские ГЕНИИ разделили младший Нибл на два полуНибла! Младший полуНибл отвечает за Y (VER), Старший полуНибл отвечает за X (HOR). Он знал, что любые данные, левее младшего полуНибла можно элиминировать с помощью инструкции AND #3. DEC BIN 3 11 Эта инструкция обращает в ноль ВСЁ, что левее младшего полуНибла в байте, оставляя полуНибл неприкосновенным! Кроме этого Коренталь знал, что чтобы скинуть младший полуНибл, если нам нужно исследование ТОЛЬКО старшего полуНиббла (HOR), мы можем два раза сдвинуть значение Аккумулятора вправо, командой LSR A. Это всё стало доступным благодаря Атарьцам! Атарьские Гении разделили! Выходные значения покоординатно и поконтактно следующим образом: 1. На всё определение данных отводится младший нибл байта. Младший полунибл отвечает за вертикаль! Старший полунибл отвечает за горизонталь! Остальная часть байта не имеет значения. Проблема дешифрации не столь очевидна. Наша задача привести данные джойстика к значениям Диффирента по X или по Y! Тогда, прибавляя дифферент по любой координате к текущему положению, мы получим новую координату! Программа Бейсика, иллюстрирующая применение Ассемблерной программы вызывается следующим образом: X=0,Y=1 FOR N=0 TO 3: REM Это для 800-х для новых 0.1 DIR=X: REM For X DX=USR(RDJ,N,DIR) DIR=Y REM For Y DY=USR(RDJ,N,DIR). Some ACTIONS like? NEXT N: REM Возврат на начало цикла для считывания следующего джойстика. Вид СТЭКА в Бейсике определяется Аргументами вызова USR! Справа налево аргументы кладутся ПОСЛОВНО на стэк, Потом кладётся Число аргументов БАЙТ. Многие из этих данных нам не нужны, так как Бейсик использует ТОЛЬКО двухбайтовые данные! Соответственно, для представления однобайтовых данных нам не нужны старшие байты. Кроме этого нам не нужно число аргументов вызова, до тех пор, пока это не существенно для нашей программы! (Это когда вызов с переменным числом аргументов.) Видим сразу, - в отличии от Ассемблера Бейсик Явно избыточен! Вот наш Стэк: Number of Arguments - 1 байт - TOP OF STACK ------------------- MSB of JOYNUM LSB of JOYNUM ------------------- MSB of DIR LSB of DIR ------------------. - BOTTOM of STACK ------------------- Смотрим то, что нам не нужно. Число аргументов нафиг! Номеров джойстика мало, значит MSB нафиг! Номеров направлений ваще два - MSB нафиг! Итак, ПОМНИМ у нас есть пул джойстиков - STICK0.STICK3 (в Лучшем случае.) Вспоминаем, что обращение к Аккумулятору ведёт себя как Экскаватор. Всегда выбрасывает породу. И иногда загружает её в самосвал.;Assembler Joystick Routine;; EQUATES STICK0 = $0278;; VARIABLES ANSWLO = $D4; Произвольный регистр ANSWHI = $D5. На Нулевой странице.;.OPT LIST,OBJ; *= $0600; CODES PLA; Нафиг число аргументов! PLA; Нафиг старший байт числа джойстиков! PLA; Берём младший байт числа джойстиков TAX; Это и будет побайтным смещением в пуле джойстиков! PLA; Нафиг старший байт направлений (всего два!) LDA STICK0,X; Читаем пронумерованный в цикле Бейсика джойстик; На этом этапе, вершина СТЭКа содержит младший (существенный) байт направления (0.1); который, командой PLP заносится в Регистр P-Процессорный статус NV BDIZC - регистр P PLP; Берём флаг P - ЭТО ИНДИКАТОР! Его значения могут быть учтены и считаны,. ПОЗЖЕ, если это нужно ПРОГРАММЕ! На процессор регистр НЕ ВЛИЯЕТ!; Так как в регистре P - наше значение (0.1) Всегда МЛАДШИЙ бит! Это = флаг Carry, то определяем направление. BCS NOTX; Если установлен то мы запрашиваем Игрек, пропуская X. RDX LSR A; Если X, сдвигаем LSR A; на 2 бита вправо. NOTX AND #3; здесь, скрываем все данные старших битов, кроме интересующих нас. SEC; Готовим вычитание SBC #2; Математическая обработка. BPL SAVEIT; Если положительно LDA #2; Если отрицательно SAVEIT STA ANSWLO LDA #0 STA ANSWHI RTS.END Здесь мы приехали к расшифровке данных джойстика..DIRECTION BINARY PROGRAM ANSWER HOR VER. E W S N X-Val Y-Val.Center 1 1 1 1 1 1.N 1 1 1 0 1 0.NE 0 1 1 0 2 0.E 0 1 1 1 2 1.SE 0 1 0 1 2 2.S 1 1 0 1 1 2.SW 1 0 0 1 0 2.W 1 0 1 1 0 1.NW 1 0 1 0 0 0 Караул! ДОКТОР МЫ ЕГО ТЕРЯЕМ! Ничего мы не потеряли!!! Смотрим на X-Val. Чтобы получить стандартные значения (-1 0 1), для смещений по координате X, достаточно в Бейсике сделать DX=USR(.)-1 а для данных Y-val достаточно в Бейсике сделать DY=1-USR(.) Вот! Решил перейти в эту тему про ассемблер. Пока у меня после восстановления моей железки продолжаются муки выбора стартовой литературы. Вот тут 2 очень интересные книги Под шапкой Osborne / McGraw-Hill: 6502 Assembly Language Далее еще одна книженция. И всякие сводные таблицы по процу 6502 Еще хвалят такую книжку: Atari: De Re Atari Ну и еще та 130Xe про которую упоминал в своей теме про неизвестные знаки:). Остановился на одной книге как основной. Это Programming the 6502 Rodnay Zaks четвертое издание 83го года. Материал изложен нормально, как я привык видеть в более современных изданиях. И главное она толстая:) Что то многие старые книги какие то ущербные по ассемблеру. В помощь ей еще один фолиант Osborne / McGraw-Hill: 6502 Assembly Language Programming Ну и Atari Roots иногда поглядываю. Изучаю неспеша пока азы. Ссылки бы на книжки подкинул, я о 6502, атари корни уже есть. Да и не забудь что атари это не только процессор. Понимаете, выучить Ассемблер очень легко! А пользоваться им для программирования (о-о-очень трудно). Гораздо труднее выучить современный язык программирования со всеми его 'мегафичами', а потом иметь голову как дом советов чтобы представлять во что написанный код откомпилируется. Если ты знаешь ассемблер, понимаешь как работает машина и имеешь в руках компилятор с мощной системой макросов, то на ассемблере писать одно удовольствие (собственно си в свое время вырос из такого ассемблера, он своими конструкциями языковыми идеально укладывается в архитектуру PDP). По состоянию на сегодня мне проще даже под windows писать на ассемблере, чем разбираться с гигабайтами говна что идет в составе SDK и потом как-то работает (а чаще не работает) и я не понимаю как от слова вообще без отладчика. И код получается в 100 раз компактнее. Причем по состоянию на сегодня даже под подобные системы проще писать программы на ассемблере и потом если надо их переписывать под другую архитектуру наново, чем писать на том-же си, и потом ловить годами на них глюки, потому-что оно компилируется, но из-за нюансов компиляторов, многозначностью стандартов и проглядов программиста работает неверно. Просто исходный текст программы на ассемблере раз в 20 короче сишного. И его быстрее переписать заново (все едино разбираться), чем в 20 раз больше разбираться а потом неуловимых блох там топтать. А сложно писать на ассемблере только всякие тест-ромы, когда у тебя нету оперативной памяти и стека вообще, и которые предполагаются выполнять на неисправной машине. И где даже вызов процедуры (а тем более двухуровневый) превращается знатное в извращение, и все что у тебя есть в принципе - набор регистров процессора. Зато извращение изящное. Но такие извращения без ассемблера написать в принципе невозможно. PS: кто-то в соседней теме диггера с писи портировал на куда-то. Написанную на си. Чтоб оно хотя бы компилировалось угробил месяц работы. Если бы она была написана на ассемблере за это время такую программу проще было написать заново. Заколдобистых мест в такой программе - по пальцам посчитать, и это звук и графика. Остальное макросами шляпать можно. В исходниках исправлений было больше чем в ней самого бинарного кода содержится. А сколько глюков потом полезет еще. Гораздо труднее выучить современный язык программирования со всеми его 'мегафичами', а потом иметь голову как дом советов чтобы представлять во что написанный код откомпилируется.Чем писать на асме, да? Насчёт сложности современных языков - подпишусь. А вот реализация в одиночку на асме того, что заговнокодено в тоннах SDK, без преувеличения, займёт не одну сотню лет. Попробуйте, например, написать на асме TCP/IP-стек. Желание контролировать сложность и иметь системы, открытые на всех уровнях и достаточно обозримые, чтобы разобраться в них глубоко за короткое время (например, чтобы исправить баг или добавить фичу) породило интерес к простым ЯВУ. Например, Оберон - самый юзабельный из простых и самый простой из юзабельных. Легко транслируется в Си, но он настолько прост, что только за последние 5 лет я вижу появление десятка новых компиляторов. Есть разные диалекты Оберона, но здесь углубляться в это не буду. Чтобы не быть голословным, приведу несколько ссылок на новодельные компилеры. Вот ещё мотиватор: P.S. Извините, что не по теме. Тема свалилась в оффтоп, по сути дела особой связи между ассемблером и Атари я не вижу. Я с друзьями изучал компьютер по переводу Mapping The Atari, вышло примерно так: - Графические режимы и форматы пикселей - Спрайты или PMG - Display List - система прерываний (Display list, VBLANK,таймеры) 6502 прост, есть мало нюансов, связанных с кодом, например для меня было сложным операции 16бит. Какой язык программирования выбрать? Наиболее популярен cc65, но он громоздкий для настройки и необходимо изучение массы нюансов для Атари. Для затравки предлагаю без ассемблирования угадать, каков результат работы программы? LDY #0 M1: TYA STA(88),Y INY BNE M1. Печать набора ATASCII символов на экране. Почти верно: для любого графического режима отобразятся не ATASCII. К тому же кодировка ATASCII отличается от так называемого internal (А чем все же асм не устраивает? WUDSN с MADS вполне комфортно. К тому же на pouet.net куча примеров. Мне кажется, если с кодом не получается, или трудно написать логику, то проще взять язык. Или дизассембировать полученный код. Я вот забыл где видел описание и таблицу Shadow registers. В Mapping The Atari указывается Shadow/Hardware, список не помню. Почитал тему. Как-то в основном крутится вокруг освоения ассемблера 6502, но он же очень простой. В прошлом году я дизассемблировал игрушку Bruce Lee взятую с Atari 8-bit -- вот что получилось: Раскручивал в основном пользуясь эмулятором Altirra -- он имеет много режимов отладки, хорошо собирает трассу, обращения к памяти. И в этой работе я в итоге понял, что главное чего мне не хватает -- это знания аппаратуры Atari, того как работают устройства, какие есть режимы, как они выбираются итп. -- без этого даже полностью раскрученный исходник непонятен совершенно. Соответственно, чтобы эффективно писать для Atari -- нужно изучить и держать в голове все его возможности, выраженные через способы использования его компонентов. Что главное чего мне не хватает -- это знания аппаратуры Atari, того как работают устройства, какие есть режимы, как они выбираются итп Да пока что и несложно: 0646: A9 78 LDA #$78 0648: 8D 07 D4 STA PMBASE [$D407] Здесь задается адрес спрайтов, т.е. $7800, отсюда видны манипуляции с памятью. Попиарюсь немножко: спрайты или PMG (0632: A9 EA LDA #$EA; 0634: 8D 02 D4 STA DLISTL; 0637: A9 0E LDA #$0E; 0639: 8D 03 D4 STA DLISTH; $0EEA -> DLIST -- game mode display list выходит, адрес DList=$0EEA. Иными словами говоря, это набор инструкций, как отображать экран. Вот только есть ошибка: 0EEC:.byte $40; 5 blank lines Вернее будет LMS - указатель адреса для видеопамяти, по идее получается $2020. Вообще, исследовать игрушки дело трудное. Здравствуйте, коллеги. Я всё время программировал на Ассемблере на MAC/65, но он слишком для меня старорежимый, что-ли. Ненавижу нумерацию строк и никак не могу запомнить команду ASM (кто там и за кем должен следовать.) Когда я с вопросом о совершенном нативном ассемблере обратился к друзьям в AtariAge, мне ответил старина Конрад Кокожкевич Draco030 и написал, что ничего лучшего для Атари нет, кроме как MAE ассемблер Джона Харриса. Я попробовал и оказалось, что это то, о чём я мечтал тыщу лет! Преимущества: - Продуманный интерфейс. (Я и впрямь видел такие славные программы!) - Отсутствие нумерации строк - Возможность работы как с Заглавными, так и со строчными буквами. - Возможность программирования не только 6502, но и 65816 и пр. - 3 режима текста: 40/64/80 колонок! - С обиняками! Совместим с MAC/65 Бяки тоже есть! Он лучше всего работает со 130XE. Здесь спрашивали об ассемблерном доступе к устройствам. Я покопался в текстах и на MAE могу предложить код вывода строки на экран (S:) с помощью CIO (Central Input/Output) Как работает CIO? Прежде всего, этот модуль всегда загружен во включённой Атари! Затем, именно он СТАНДАРТНО обеспечивает АВТОМАТИЧЕСКУЮ работу с устройствами. И наконец, он по Атарьски жутко мобилен. Я имею ввиду то, что Вы и сами можете его полностью переписать! (Так работает Любой СпартаДОС) Для того, чтобы заставить работать CIO нужно совсем немного. Дать Ассемблеру знать о стандартных регистрах CIO. Дать знать о стандартных коммандах. Дать знтать о стандартных режимах этих комманд. Внести инфо о передаваемых данных. Передать управление CIO. Фактически, - заполнить несколько таблиц и вызвать CIO. Далее Атари работает сама! Важная особенность MAE - Желание Автора выполнить выравнивание по длине комманд Ассемблера к оп-кодам процессора Чтобы текст программы стал читаем. Поясню: и те и другие предпочтительно имеют длину 3 знака! Таким образом,.ORG преобразуется к.or (Origin) OUT(нет в MAC/65) преобразуется к.ou (Output to disk).BYTE преобразуется в.by (BYTE).DS преобразуется в.ds - Define Space и так далее. К сожалению, MAE-Руководство написано, хоть и исчерпывающе подробно, но бессистемно и читать его - сущее мучение. ПРИМЕЧАНИЕ: Совсем не обязательно заполнять ВСЕ комманды и ВСЕ режимы CIO! Атари будет пользоваться теми, которые мы указали как СУЩЕСТВЕННЫЕ! 2Atari1974 - Это Инструкция одновременно для 02 и 816, что чудовищно! Не умею загружать на форум вложения. Даю ссылку на atr с тремя 40/64/80 режимами Е: - - - Добавлено - - - Способ взаимодействия Атари с устройствами. Я наверное неоднократно предпринимал попытки рассказать о том, что Атарьские инженеры - вообще говоря, гениальны! Чего стоит один Стив Возняк, который работал на Атари. Не вдаваясь в холивары по поводу Атари, Эпл, и Амига, попробую рассказать о взаимодействии ВНЕШНИХ устройств с Атари. Во первых, они - ВНЕШНИЕ, а значит, придётся иметь дело с Вводом/Выводом. Во вторых, они - РАЗНЫЕ, а значит, обладают разными опциями, которые должен задать Именно Программист. Гениальные Атарьские Инженегры ПРЕДУСМОТРЕЛИ эти особенности и спроектировали УНИВЕРСАЛЬНУЮ систему Централизованного Ввода/Вывода. (Как им это удалось?) Идея была простой. При I/O машинка должна знать/обрабатывать следующие вещи: 1. Как компу распознавать обращение к именно этому устройству? (по именам!) 2. Это устройство ввода, или это устройство вывода? Затем, соответственно генерировать номер ошибки. (Если не срослось.) 3. Если устройств много, нужен порядковый номер. Если устройство НЕ СТАНДАРТНОЕ, то нужны дополнительные опции его работы. Ну, а задав эти вещи, можно запускать универсальную программу. Итак, универсальная. Потому, что применяется и для своих Атарьских внутренних и внешних устройств! Ничего идеологического не нужно менять! Это я к тому, что при включении Атари, хотите Вы или нет, ИСПОЛЬЗУЮТСЯ 1. Возможность вывода на графику 3. Кассетник, Принтер, и пр. По цифрам каналов ввода/вывода это 0, 6, 7. (Ясно, что если чего-то нет, то не используется и можно их программировать. [Но при загрузке инициализируется всегда!]) Пардон, если нет картриджа, так как он главнее! Кроме этого, AtariOS и Бейсик сами произвольно используют что-то из Ввода/Вывода!!! Для внутренних нужд! (Это относится к опциям, а не к вводу/выводу, но они запросто могут переписать Ваши коды,если не убережётесь.) Итак, Атари CIO. Централизованный Ввод/Вывод! С точки зрения пользователя, работает так: Если правильно задать инициализацию и передать управление правильному Вектору (Это такая фигня, которая содержит переходы на обработчики(handlers), то есть JMP.), тогда всё произойдёт само собой и Вы в шоколаде. Если нет, то Ваш обработчик ошибок (А Вы его написали?) выдаст ошибку ввода/вывода, которая легко распознаётся по номеру и всегда больше 127. Это пгтому, что до 127 - это ошибки Бейсика, а после - ошибки устройств. Как написать Инициализацию? В Атари максимально может быть одновременно работающих устройств 8! Программист решает, будет ли он работать с текстом или нет, будет ли он выводить графику, будет ли он работать только с дисководом. В зависимости от этого, определяется количество и нумерация свободных устройств. Откуда берёт данные программа Централизованная ввода/вывода? Из Базы Данных Как и любая База Данных, она строго структурированна и определена. Блоков в ней 8 - по числу устройств, Записей в каждом блоке 16 (с избытком) Начинается она в Атари с адреса $0340! Называется IOCB (Input Output Control Block) Поля в Базе всегда строго определены, для универсальности. Ёрзать с устройствами можно, пользуясь ДОПОЛНИТЕЛЬНЫМИ полями, или, модификаторами. Вот структура этой Базы данных:; CIO Equates IOCB.or $0340 ICHID.ds 1; Handler ID ICDNO.ds 1; Number ICCOM.ds 1; Command ICSTA.ds 1; Status ICBAL.ds 1; Lo BufAdr ICBAH.ds 1; Hi BufAdr ICPTL.ds 1; Lo PutAdr ICPTH.ds 1; Hi PutAdr ICBLL.ds 1; Lo BufLen ICBLH.ds 1; Hi BufLen ICAX1.ds 1; Aux 1 ICAX2.ds 1; Aux 2 ICAX3.ds 1; Aux 3 ICAX4.ds 1; Aux 4 ICAX5.ds 1; Aux 5 ICAX6.ds 1; Aux 6 Поясню,.or в MAE Assembler = Origin.ds в MAE Assembler = Define Space, Size Далее, для прикола. Атарьские Гении поняли, что если длина блока Базы данных будет ровно 16 байт, то тогда программисту не нужно будет ничего считать! То есть: Предполагая адресацию к полям, такую как CMD ADDR,X мы, для нулевого устройства имеем LDX #$00 Для Первого LDX #$10 Для Второго LDX #$20. На сегодня - всё. Atr - это образ атарьского диска. Он, при соответствующем оборудовании, может быть подгружен в нормальную атарьку. У меня есть SIO2PC, что позволяет грузить атры в HW. Также у меня есть SIO2SD и SIO2IDE, что тоже позволяет Атари увидеть SecureDigital или Жесткий диск. Важно другое. Если есть Atari800 Эмулятор, (их тыща!) то и на ПиСишке можно программировать или играть. Главное, что эмулятор видит atr как Диск и читает/пишет его. Сам я использую Atari800WinPlus 4.1 для программирования. Он позволяет налету перекодировать Win-ATASCII то есть, программирую на Win, а затем это гладко читается в Атари. Когда не было Эпл, и Возняк (Крутой инженер) и Джобс (Крутой мэнагер) работали на Атари. Несколько оффтоп конечно, но вот вам иллюстрация какой Джобс 'крутой менеджер'. Речь как раз идёт о том коротком периоде когда в компании Atari работал Стив Джобс. Он вызвался решить задачу по минимизации числа микросхем для новой игры Breakout, и сделал это -- с помощью Возняка. За успешное решение такой задачи была назначена премия. Задача была решена не просто успешно, а 'гениально', и всего за четыре дня, вместо нескольких месяцев -- типичного срока для подобной проблемы. Технарь получил $350, напарник/посредник -- $5350, вроде как за 'общую' работу. (цитата из книги 'Atari Inc. Bussiness is Fun'.). Стандартная работа с вводом-выводом Атари. Изначально, система Ввода/Вывода (I/O) Атари, которая называется CIO, конструировалась гениальными Атарьскими инженерами с целью максимального абстрагирования от устройств. Поэтому, все стандартные устройства I/O, с точки зрения Атари выглядят (а, значит и программируются.) ОДИНАКОВО! Это - огромное облегчение программисту! Раз научился. Первый уровень абстракции - Система Векторов. Вектор - это Адрес, содержащий Адрес Обработчика! Находясь внутри нашей программы мы даём команду JSR ADDR и Обработчик, обязательно заканчивающийся командой RTS, исполнив обработку устройства, вернёт исполнение на команду, следующую за вызовом. Абстракция здесь в том, что изменяя содержимое самих векторов, мы можем программно вызывать не страндартные, а, написанные нами обработчики, притом, что адрес перехода на вектор останется в нашей программе тем же! Второй уровень абстракции - Терминал. Терминал, для тех, кто знаком с языком Си - это три состовляющих: - Стандартный ввод - stdin - Стандартный вывод - stdout - Стандартный вывод ошибок - stderr В Атари, идеологически реализована такая же система!!! Терминалом можно назвать устройство 'E:' (Берёт с 'K:', кладёт в 'S:') хотя с оговоркой, что обработка ошибок лежит на совести программиста! Для нас, в данном контексте, существенно, что: - ошибки OS, в количестве 127 - это ошибки BASIC или AtariOS(Атарьский BIOS) - выше 127 - ошибки Внешних устройств! Любое устройство, взаимодействующее с Атари через CIO, возвращает код ошибки, который автоматически копируется обработчиком CIO в регистр процессора Y!!! Так как любое число типа БАЙТ, превышающее 127 в Атари устанавливает процессорный флаг N(Negative) в единицу, то, скопировав регистр Y в Аккумулятор и проверив этот флаг в ассемблере, мы сразу можем определить прошла операция или нет. Простейшая обработка ошибки заключается в 'ЧИСТОM' закрытии процедуры, без вывода причины. Третий уровень абстракции - Структура IOCB (Блока настроек ввода-вывода.) (IOCB - Input/Output Control Block.) Таких структур, максимально. (Конструктив, ничего не поделаешь.), в Атари может быть 8 (от 0 до 7)! Каждый размером в 16 байт. Этот блок должен содержать: 1. ID - номер обработчика данного устройства в списке устройств, таких как 'C:', 'D:','E:' и пр. Номер актуального устройства (в смысле 'D1:-D8:') 3. Токен команды ввода-вывода 4. Здесь ВЫВОДИТСЯ номер успешности операции или номер ошибки I/O. (Копируется в Y!) 5. Адрес Буфера для данных 6. Адрес PUTCHAR - обработчика вывода данных на экран, без единицы (минус 1) 7. Длина буфера для данных и ещё 6 байт для опций и модификаторов Ввода-Вывода. Ещё раз повторю! С целью унификации доступа ко всем внешним устройствам, Атари определила структуру доступа, которая должна быть целиком, или частично, в зависимости от задачи, заполнена. Эта структура поэлементно поименована и длина её полей однозначно определена. В частности, любые адреса и длина буфера - это значения типа WORD, остальные - типа BYTE. Так как каждое поле структуры поименовано, достаточно добавить правильное СМЕЩЕНИЕ, к нулевой структуре, чтобы получить доступ к ТАКОМУ-ЖЕ полю, нужному нам. Неплохо добавить, что,так как длина любой IOCB структуры равна 16, а в 16-ричном исчеслении $10, то поиск начала структуры не состовляет труда, например отступ структур: - для нулевой = $00 - для первой = $10 - для второй = $20. - для максимальной - седьмой = $70 НРАВИЦА? Прежде, чем пытаться что-то спрограммировать Вы должны понять, что после загрузки, некоторые IOCB в Атари ЗАВЕДОМО используются!!! Нулевой IOCB - для работы с терминалом 'E:' (Именно с ТЕРМИНАЛОМ! Атари так и проектировалась!!! Другой известный терминал - ATARI XEP80, Малоизвестные терминалы - ATR8000 [80-cols], INDUS GT[80-cols], LDW Super2000 [80-cols], CA2001/CA2002 [80-cols]). Шестой IOCB - для работы с графикой и цветными текстовыми режимами. Седьмой IOCB - для работы с Принтерами и Кассетником. Другие - разные, для разных ДОСов используются для обращения к Batch файлам и для перенаправления ввода-вывода. УЧИТЕ МАТЧАСТЬ ДОСов! На сегодня, пожалуй всё. Надеюсь, что был полезен. Здравствуйте, Шинни! Рад, что Вы не устали ещё от ассемблера.:) Дело в том, что идея макропрограммирования - сама собой, принципиально, маленько ущербна. Все макросы АБСОЛЮТНО зависят от ПРОГРАММИСТА, который рожал их парсинг! Макросы на Лиспе - это не то, что макросы на Си, а макросы на ассемблере наличиствуют в количестве штук, равном макроассемблерам. Просто, нет ОБЩЕГО понимания того, что есть макрос. Принципиально, дело в том, что MADS - кроссассемблер. Это важно, так как он работает в нативном режиме на машине в миллион раз более мощной, чем Атари. Но, ведь, существует разница и в родных Макроассемблерах Атари! Например Макроассемблер Ассемблера MAC/65 намного более мощный, чем Макроассемблер МАЕ. Однако, есть большие затруднения в том, чтобы программисту ассемблера понять, по какому пути ему идти!!! Должен признать, я принципиально, не знаю ни одного программиста на MAC/65, который работал бы с макросами. Их просто понять никто не может. А дебаггировать тем более. Да, это - по сути, и не важно. Джон Харрис выбрал путь прямой подстановки!!! Разумеется, прямая подстановка не используется в кроссассемблерах, так как парсинг кода позволяет получать описания ошибок даже ещё при макроассемблировании (в PC), что в МАЕ недоступно. Вот Вам пример ЭЛЕГАНТНОГО макрокода в MAC/65. В нём НИЧЕГО не вычисляется во время исполнения кода!!! Всё вычисления заданы в макросе, а значит, проводятся при первом проходе ассемблера. Код просто проходит по изменяемым адресам в Программном Счётчике и в результате получаем ВОЛШЕБСТВО! 2470;----------------------------- 2480; MACRO #2 'NEWPAGE' 2490; Этот макрос устанавливает программныё счётчик 2500; на следующую чётную страниуц. 2510; EXAMPLE: 2520; (Пусть PC сейчас установлен на $4322) 2530; NEWPAGE 2540; (По выполнении станет $4400) 2550; 2560;Follow: *=$4322 2570.MACRO NEWPAGE 2580 *= *&$FF00; *=$4300 2590 *= */$0100; *=$0043 2600 *= *&$FF; *=$43 2610 *= *+1; *=$44 2620 *= **$0100; *=$4400 2630.ENDM 2640;Follow: *=$4400 2650; Напомню: &FF00 - в разрядах, где FF - всё остаётся, где 00 - стирается. /0100 - получаем точное число страниц с недостатком. В МЛАДШЕМ байте. &$FF - всё, что было - остаётся, но в старшем байте ничего. *+1 - Число страниц увеличивается на 1. **$0100 - и при умножении на 256, становится старшим байтом!!! Как бы это лучше объяснить. Просто, САМ Ассемблер всё считает, а Результат ВОЛШЕБНО появляется в виде числа в коде. Также можно определить 1кб-отступ для нового шрифта(он обязан начинаться на границе 1кб), отступы для PM-графики и так далее. Этот макрос ОЧЕНЬ нужен! Уже двое суток не могу перевести его в МАЕ. Базарная документация и нет примеров. (В доках Харрис хотел описать ВСЁ СРАЗУ для 6502 и 65816. Так как 65816 сложнее, 6502 затерялся! А так, всё понятно. Кто ищет - тот найдёт.) Проблема здесь не в том, что я не понимаю Атари. Проблема в том, что я не понимаю Харриса (Его Дзена описания Макросов.) Так, на то он - Босс! Напомню: &FF00 - в разрядах, где FF - всё остаётся, где 00 - стирается. /0100 - получаем точное число страниц с недостатком. В МЛАДШЕМ байте. &$FF - всё, что было - остаётся, но в старшем байте ничего. *+1 - Число страниц увеличивается на 1. **$0100 - и при умножении на 256, становится старшим байтом!!! Я видел выравнивание при использовании z80: (adres+$FF)/256 к тому же директива align 256 выравнивает код по 'правильному' адресу. Макросы мне не нравились, потому что есть масса ассемблеров и каждый использует макросы по-своему или не использует вообще. В журнале Analog я встретил интересное применение: *=$2000 AUDF1=$D200 AUDC1=$D201 AUDCTL=$D208 SKCTL=$D20F.MACRO SOUND; voice,pitch,dist,vol;,dur lda #%2 sta AUDF1+2*%1 lda #[[%3 * 16]|%4];lda #[[%3 shl 4] or%4] sta AUDC1+2*%1.ENDM lda #0 sta AUDCTL lda #3 sta SKCTL SOUND 0,121,10,8 jmp * это по-нашему xD. Привет всем Атаристам-Восьмибитникам! Метки в МАЕ Ассемблере начинаются с буквы, или символов @, _, или?? - означает, что метка локальная, то есть видна только в данном блоке. Они не должны содержать пробелоа и в тексте метки могут содержать цифры и знак точки. Длина метки может быть до 15 символов. Обычно я заканчиваю файл следующей конструкцией:; ====================; Setup Run Address.or RUNAD.wo start;.en Директива.SBYTE в МАЕ Ассемблере заменена на трёхсимвольную.sb. Залил ещё видео: ez. Это, наверное шутка, так как по разным причинам Харрис решил не пользоваться Программным Счётчиком базарно. То-есть, *= ДОЛЖНА быть заменена на.or. А вот.word start - прокатит, так как Харрис писал MAC/65 и любил его, как и мы все. Он НЕ НАСТАИВАЛ на трёхбуквенных сокращениях! Просто не любил долбить клавиатуру. Могу выложить мои библиотеки, зря, что-ли писал? Я для Вас, тех, которые хотят узнать,ЧТО ТАКОЕ КОМПЬЮТЕР, пишу! Потому, что это - НОВАЯ ЖИЗНЬ, а вовсе не гаджет в кофемолке. Может конфу в скайпе замутим, пообщаемся? Лучше в почту пиши: [email protected] насчет линии - можно как вариант использовать гр.режим 8, тогда каждая линия будет своего цвета, либо попробовать 559=0 и записывать значения в аппаратный для 712(не помню номера). A интересный вариант,надо считать тайминги, не понятно, как этот пример работает. - - - Добавлено - - - по поводу эффекта: описано здесь (и примерчик из демки, порт эффекта на ZX. Я говорю, что у меня наклейки русского шрифта для Атари НА КЛАВЕ! Это - машинописный шрифт! И как сделать -? Как опубликовать - не знаю совсем! Имею Русско-НАПИСАННУЮ! Программу (Самую лучшую! IMHO) для создания шрифтов, Адаптированные программы для текстовок и эл.таблиц. Я, просто не знаю, как это всё публиковать, когда все интернецкие медиа постоянно исчезают! Щас Дропбокс грозится отключить расшаренную область. У меня здоровенный архив фоток с 90-х пропал на minus.com. Семизначник с Аськи сдох, так как он требовал перерегистрацию с 2000-ных, а я не пользовался с 90-х. Дай способ КУДА закинуть атры и я буду соответствовать. И привет, украинским братьям!!! Я с кооперативом 'Фрактал' знаком. Я же, про ту-же историю. Как в рантайме получить адрес в указателе. Это всё о том, что MAC/65 может средствами макроассемблера получить адрес, (писал где-то.) а МАЕ не может. (или может, но я об это убился.) На самом деле, у меня проблем с руссификацией нету. Когда-то прочёл статью в Байтике и вуаляшка! Другое дело, что шрифтового пространства всё равно не хватает! То есть, я в Омниворе заменяю строки в досе как мне надо, а остаются буковки, которые жизнь портят. Например, буковка 'p (past meridiem) или буковка 'a (aint meridiem) в Спартадосе здорово досаждают. Да и это - не беда. Просто, я и с ассемблером не знаком, особенно-то, и со средой тоже, так как коды закрытые и пр. Мучаюсь, преодолеваю. Покуда успешно. Для начала, прилагаю программу руссификации бейсика. Конечно, только для ЭТОГО доса. Называется RUSBAS и работает ТОЛЬКО при подключённом бейсике, так как сама выходит из доса в бейсик. При подключённом бейсике загрузиться и увидеть READY. Набрать DOS и увидеть D1: 3. Набрать RUSBAS и снова увидеть READY Можно работать. Рус - POKE 756,28 Eng - POKE 756,224 ez - - - Добавлено - - - Вот та самая программка на Ассемблере.:) Называется EZFONT (EZ - это я) Подгружает фонт по запросу и защищается от Бейсика. Пока в системе бейсик, ничего с ней не произойдёт. RUS - POKE 756,28 ENG - POKE 756,224; ezfont program; For use with BASIC! Ну, это очень трудно на словах разъяснить. Смысл в том, что любая команда представляется в разном виде, в зависимости от материала, с которым работает. Я к тому, что входящие данные и определяют формат команды. Это - не панацея! Сама команда может не воспринимать чуждые ей форматы! Я это к тому, что программист должен воспринимать команды как их ассемблер воспринимает! То есть, правильно парсить их!!! Кроме этого он должен знать ПРАВИЛА. Некоторые команды - не универсальны и не могут работать со всеми адресами. Самые универсальные - LD?-ST? Они работают со всеми регистрами и операндами. Это - общая инфо. Вряд ли, она что-то даёт. В принципе, способы адресации объясняют ассемблеру, как с данными работать. Непосредственная адресация - говорит, что дано ЧИСЛО! Если однобайтовое - обработай, если двухбайтовое - обработай за два раза. Абсолютная адресация - говорит, что задан адрес (2 байта), в котором ЧИСЛО (м/б двухбайтовое)! Надо доступиться! До числа и затем обработать как ранее. Нулевая страница - исключение! Если операнд на нулевой странице, он требует примитивизации обработки! Бери его и ешь! Следующего байта НЕ БУДЕТ! (Если речь идёт об адресации.) Я к тому, что на нулевой странице может быть BYTE или WORD. Физически данные джойстика закодированы как биты и не могут быть определены без вычислений. Слава богу, Атарьцы запрограммировали это так, что вычисления минимальны. Никакой надежды вычислить это как диагональное движение. Только покоординатное! Поймите, я говорю о том, как было спроектировано!!! 'Всё было украдено до нас!' Я, пока от Вас не получу того, что Вы хотите от джойстика, не знаю КАК делать его программу. Можно было бы сделать джойстик реальным устройством, но ответьте: 1. Что такое открыть канал джойстика? (Смысл инициализации) 2. Что такое считать байт с джойстика (Сам знаю.) 3. Что такое считать состояние джойстика (Вероятно состояние кнопки) В общем, я не понимаю, каким должен быть ДРАЙВЕР. А хендлер ЕСТЬ! - - - Добавлено - - - Данные джойстика берутся из ячейки STICK1=$279 Данные кнопки берутся из ячейки STRIG1=$285 Само по себе это МАЛО! Ну, что же, подправил программку. Приблизительно такие вещи делаются в WEDGE. Это - программка, добавляющая команды к Бейсику. Подменяются вектора своими и после мелкого украшательства возвращается управление Бейсику. Разумеется, Атари, как гениальная машина, такое позволяет. Но, лучше, написать с нуля свой интерпретатор Бейсика или 'чего-надо' со встроенным русским языком. Я - совсем не программист. Писать языки не буду. Моя главная идея, написать управляемую стрелками, искейпом и ритён псевдографическую программку для управления любым ДОСом. А коли на Русском, так ваще шоколад. (СТРОЧНЫЕ буковки на Русском занимают область псевдографики. Невозможно и Русским баловаться и псевдографикой пользоваться!) Мне нравится система бредкрамб и реально она реализована в IBM AIX в виде SMIT (Java). (НЕ smitty (Sic!)). Там много клёвых моментов. Если выучил сокращения, переходишь прямо к нужному пункту меню. Если не выучил, ползаешь по меню. Все пункты меню прописаны в текстовом файле и т.д. (Редактируешь и добавляешь.) Я работал с AIX и никогда не жалел. Так сволота, уволившая меня с работы лишила меня и моего сервера! С кем поведёшся от того и огребёшся. Ну вот допустим захотел я джойстиком погонять точку по экрану в gr.0, как мне логически рассуждать в ассемблере для написания этой программы? Добрый денёк, atariki. Ну, чтобы пиксель гонять по экрану, надо объединить графику 0 с графикой 8.:) Это сделать можно, но там свои проблемы. А вот, чтобы погонять знакоместо (курсор) по экрану в ДОСе, могу предоставить ассемблерную программку. Рассуждаем следующим образом. 1) Что гоняет курсор по экрану? - При нажатии на клаве стрелки, код клавиши идёт в системную программу преобразования кодов в буквы(ATASCII) и окончательно оседает в однобайтовом теневом буфере ввода CH. Таким образом, зная коды стрелок и анализируя положение джойстика, мы можем руководствуясь джойстиком, по нашему желанию подменять коды в регистре CH. Тогда при следующем VBI, наши коды будут двигать системный курсор. 2) Когда подменять коды в CH? - Так как машинка не должна знать, что мы подменяем коды, надо делать это в прерывании по Вертикальному Бланку (по кадрам экрана). 3) Где поместить программу VBI? - Программка достаточно короткая (~40 байт), чтобы быть помещена где угодно!!! В частности, я помещал её в конце аппаратного стека и стек никогда её не затирал. 4) Какой режим VBI выбрать? - Я выбрал Immediate, так как у этого режима около 60 свободных циклов, но можно и Deferred - без разницы. 5) Какой будет скорость курсора? - Нормальная для меня скорость курсора это считывание данных джойстика каждый пятый кадр экрана. (Счётчик кадров должен меняться от 4 до 0). Большие значения счётчика замедляют движение. А вот и сама программа.; Джойстик-курсор; jc.com.ou jc.com; ====================; Ярлыки SETVBV = $e45c; Вектор установки VBI. SYSVBV = $e45f; Возврат на системный VBI. STICK0 = $0278; Теневой регистр джойстика. RUNAD = $02e0; Адрес запуска программы CH = $02fc; Теневой буфер текстовых кодов; --------------------; Константы vbmode = 6; Режим VBI=Immediate speed = $04; Скорость курсора. Cur.up = 142; Величины кодов стрелок. Cur.dn = 143 cur.lt = 134 cur.rt = 135; ====================; Главная программа.or $0110; Конец стека start jmp init; Переход на подпрограмму инициализации; прерывания по VBI; --------------------; Блок данных keytab.by cur.up,cur.dn.by cur.lt,cur.rt counter.by 2; --------------------; Инициализация прерывания VBI init ldy #vbi; MSB исполняемой части VBI lda #vbmode; Режим VBI jsr SETVBV; rts; Возврат в ДОС после инициализации VBI; ====================; Подпрограмма исполняемой части VBI vbi dec counter; Уменьшаем счётчик пропуска считываний джойстика. Bne done; Если не дошел до нуля,; переходим на системный VBI. Lda #speed; Если ноль. Sta counter; обновляем счётчик пропуска считываний джойстика.; lda STICK0; Затем, считываем джойстик eor #$0f; Проводим проверку на движение ручки.; Число $0f равно 15, а это значение, если ручка НЕ ДВИГАЛАСЬ!; eor (Исключающее ИЛИ) ИНВЕРТИРУЕТ данные в Аккумуляторе и; в случае, если там было 15, станет 0.; При анализе положения ручки будут исследоваться уже ИНВЕРТИРОВАННЫЕ данные!!! Beq done; Если ноль, джойстик не двигался и мы; переходим на системный VBI.; ldx #$ff; Если двигался, устанавливаем в 255 (reset); селектор считывания таблицы кодов стрелок.; По сути - это смещение в регистре X. Chkstk inx; Чтобы перейти к следующему значению в таблице,; увеличиваем смещение.; В случае, если мы реинициализировали селектор,; вспоминаем, что в однобайтных вычислениях $ff+$01=$00,; то есть смещение равно нулю и селектор показывает; на первое значение в таблице. Lsr a; Так как в аккумуляторе у нас ИНВЕРТИРОВАННОЕ значение; данных джойстика, сдвинем логически биты вправо.; При этом сдвинутый бит помещается во флаг статуса Carry. Bcc chkstk; Если в Carry ноль, значит в этом направлении; джойстик не двигался, проверяем следующее направление. Lda keytab,x; Если движение было, берём соответствующее значение; данных курсора из таблицы sta CH; и заносим их в теневой буфер CH done jmp SYSVBV; переходим к системному VBI. Немного стало понятно по данной карте памяти по этой тоже немного, т.е общее представление есть. Нет понимания самого процесса программирования, все эти lda, ldy, bne sta и остальное, младший байт, старший байт, что с чем едят. Если в Бейсике мне надо включить магнитофон, я наберу poke 54018,52, отключить poke 54018,60 В MAE инициализирую: PACTL = $0302; В Бейсике это POKE 54018 а как присвоить значение 52 или 60? А что дальше? Что делать с этими семью битами на картинке в столбце слева? Почему 54018,52 - - - Добавлено - - - вот простая задача: напиши бегущую строку, чтоб как на Спектруме. Это просто непосильная для меня задача ))). Немного советов от дядьки JAC!: (разместить код с $2000 и отключить Бейсик) это просто непосильная для меня задача ))) Это просто. Графике отведен ANTIC, для него важен Display List (- - - Добавлено - - - Нет понимания самого процесса программирования, все эти lda, ldy, bne sta и остальное, младший байт, старший байт, что с чем едят. Не нашел на хайпъ топики про 6502, писал я две штуки. Poke 54018,60 lda #60; # непосредственная адресация, т.е. Поместить в А значение 60 sta 54018; поместить значение А по адресу 54018. Зачем младший байт и старший байт? Для хранения информации. Память состоит из байт, которые принимают значения 0-255. Каждая ячейка памяти имеет свой адрес 0-65535. Ясно, что такие числа не втиснешь в рамки 0-255. Поэтому используются LSB-least significant byte, MSB-Most Significant Byte: LSB=NNNN&255 MSB=NNNN/256 Например, нужно хранить в памяти адрес 40000: 40000=64+256*156 Здесь LSB=64,MSB=156. У дядьки генерация квадратов на мой взгляд сомнительная. Мне понадобилась таблица для знаковых и беззнаковых чисел. Это макро команды MACRO COMMANDS The purpose of macro commands is to save time when writing programs and to shorten listings. Macro commands replace commonly used groups of instructions. MVA, MVX, MVY The macro commands MVA, MVX, MVY transfer bytes using the A, X, or Y registers, respectively. OPT R+ can potentially reduce the code size from these macros by removing redundant instructions. Lda src -> mva src dst sta dst -> ldy $10,x -> mvy $10,x $a0,x sty $a0,x -> ldx #$10 -> mvx #$10 dst stx dst -> MWA, MWX, MWY The macro commands MWA, MWX, MWY transfer words using the A, X, or Y registers, respectively. OPT R+ can potentially reduce the code size from these macros by removing redundant instructions. Ldx mwx #adr dst stx dst -> ldx >adr -> stx dst+1 -> mwa #0 $80 -> lda #0 mwy #$3040 $80 -> ldy sta $80 -> sty $80 -> sta $81 -> ldy >$3040 -> sty $81 mwa ($80),y $a000,x -> lda ($80),y -> sta $a000,x -> iny -> lda ($80),y -> sta $a001,x - - - Добавлено - - - с одной стороны это удобнее. Естественно, но я о другом - о форме записи макросов -.macro SetColor val,reg lda:val sta:reg.endm И еще - в хелпе есть ошибки, так что читать, сверять английскую версию с польской и проверять по сырцам. Насчет XASM vs MADS. Кстати в поставке WUDSN есть и XASM и другие асмы. DIFFERENCES AND SIMILARITIES BETWEEN MADS AND XASM Similarities the same syntax the same exit codes the same macro commands Differences and new behaviors small additions to ORG, e.g. MADS INS 'filename'['filename'] [+-value][,+-ofset[,length]] The INS pseudo-command allows inclusion of an external binary file. The included file does not have to be in the same directory as the main file being assembled. Search paths for the file can be configurated using the /i switch (see assembly switches). Additionally, you can perform the following operations on the binary data: * invert bytes +-VALUE increase or decrease each byte by the value of the expression VALUE +OFSET skip OFSET bytes at the beginning of the file (seek to OFSET) -OFSET read OFSET bytes at the end of the file (seek to FileLength-OFSET) LENGTH read LENGTH bytes from the file If the LENGTH value is not specified, the default behavior is to read to the end. XASM INS - insert contents of file Copies every byte of the specified file into the object file and updates the origin counter, as if these bytes were written using DTA. You may specify a range of the file to insert. The syntax is: ins 'file'[,offset[,length]] The first byte in a file has the offset of zero. If the offset is negative, it counts from the end of the file. Examples: ins 'picture.raw' ins 'file',-256 insert last 256 bytes of file ins 'file',10,10 insert bytes 10.19 of file А так же у MADS ICL 'filename'['filename'] The pseudo-command ICL includes an additional source file in the assembly process. The attached file does not have to be in the same directory as the main assembly file. Additional paths are added to the MADS search path using the /i switch (see assembly switches). Писано так, будто сей регистр можно читать, в то время как он WO верно, вечная болезнь при написании опусов. Значение, записанное в PMBASE, умноженное на 256 и есть адрес. Вообще ничего не понял. Можно графически изобразить? В текстовом режиме (GR.0 басика) и в режиме GR.8 разрешение 320х200. Для игрока один пиксель будет шириной 2пикселя, высотой в 1. Для двойного разрешения высота 2х2. На рисунке зеленый и красный.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |