С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Новые добавления.
1. Сделан 64-битовый математический блок. 10-ть знаков до и 10-ть знаков после запятой. Скорость мат-функций всего в два раза быстрее ВАСИКа. Не очень хорошё работает оптимезатор мат-функций, будет время доделаю. Пример
Вообщем посчитает. Как вы уже поняли VAR откушает 8 байт памяти на числовую операцию. Можете не писать =??? и тогд туда автоматом пропишется 0. Совет, не резервируйте регистры с именем "A", этим вы замените все аккумуляторы на точку памяти.Код:EQU $ASAM.PASS.ERROR=2 INCLUDE "asam-80.inc" ORG 33025 MATH R_A-8*56+R_B/4 - 3*(SIN*R_B) RET VAR R_A=3 VAR R_B=-7 ASAM.MATH.INIT
Так же в мат-модуле есть внутренние регистры. Ежели вы использете хотя бы раз "MATH A=6553H.34", то под регистр "А" будет автоматически зарезервировано место.
Числовой формат: первые четыре байта это значение до запятой, последние четыре байта это значение после запятой.
2. Сделаны числовые метки. Допустим:
В итоге мы получаем метку "POPIK00213"Код:LAB EQU 213 POPIKLAB05 ;Как всегда кодировка винды не поддерживает нужные символы ...
3. Модернезирован макрос:
Ну и теперь у вас есть ифы ... Компилятор будет искать любые вариации разделяя их жёсткими сепараторами из макросов. Как появится время опишу все главные комманды.Код:.IF (<>) THEN√ ;ЧТО-то .. .IF (<=) THEN√ ;ЧТО-то .. .IF (=>) THEN√ ;ЧТО-то .. .IF (<) THEN√ ;ЧТО-то .. .IF (>) THEN√ ;ЧТО-то .. .IF (=) THEN√ ;ЧТО-то ..
4. Сделаны метки с приоритетами:
Как вы заметили оператор EQUID резервирует метку _ASAM_IF_ELSE001. В квадратных скобках указывается приоритет. В "ELSE" он имеет 1, в "END IF" он 2. Ежели вы напишите:Код:.IF (=) THEN√ ASAM_INC_IFC MATH (@.0)-(@.1) JZ _ASAM_IF_ELSE$ASAM.ASAM.IFC03 .. .ELSE EQUID _ASAM_IF_ELSE$ASAM.ASAM.IFC03[1]=$ .. .END IF EQUID _ASAM_IF_ELSE$ASAM.ASAM.IFC03[2]=$ _ASAM_IF_END$ASAM.ASAM.IFC03[2] ASAM_DEC_IFC ..
В данном случае "ELSE" не учавствует в коде, и автоматически _ASAM_IF_ELSE001 будет равен _ASAM_IF_END001 и указывать на конец IF'а. Если:Код:IF 7=7 THEN LD A,1 END IF
То в данном случае _ASAM_IF_ELSE001 будет компилятором встречаться дважды но в "END IF" будет иметь приоритет 2 и игнорироваться.Код:IF 7=7 THEN LD A,1 ELSE LD A,0 END IF
Имея фантазию вы легко сделаете любые операторы.
AAA когда меня режут, я терплю, но когда дополняют, становится нестерпимо.
Роб, респект! Я уж подумал ты на свой компилятор забил давно![]()
Свирепый агрессивно-депрессивный мордовец!
Не уверен - не напрягай!
Не сдавайся. Дыши?
Virtual TR-DOS
Поверьте, то что я сейчас пишу тут это результат новогодних праздников !!! Эта работа просто ужас ... Я пол-года ничего кроме работы не вижу ... По три четыре поекта одновеменно пишу, к домашнему компьютеру вообще не подхожу ...
Зато есть очень серьёзные перспективы в плане Speccy. Возможно скоро будет новый Speccy с новой ОСью, если, конечно, наши еврейские партнёры не обломаюся ... Хоть этот проект и ради меня запустии в жизнь, и прибыли компании он не принесёт, но всё же ...
AAA когда меня режут, я терплю, но когда дополняют, становится нестерпимо.
Набросал пару строк:
Вопрос автору: оно так и задумывалось, чтобы вот такой код транслировался в шесть байтов "ABCDEF", то есть без символа "X" посередине?ORG #10000-(AFTER-BEFORE)
BEFORE:
DB "ABC"
.IF ($ > #8000) THEN
DB "X"
..
DB "DEF"
AFTER:
SaveLabels "labels.txt"
* * *
UPDATE: Гм, впечатление такое, будто у меня .IF не работает вообще. Имеем код:
Получаем для меток BEFORE и AFTER значения #F000 и #F009 соответственно. Гм...ORG #F000
BEFORE:
DB "ABC"
.IF 0<1 THEN
DB "X"
.ELSE
DB "YY"
.END IF
DB "DEF"
AFTER:
SaveLabels "labels.txt"![]()
Последний раз редактировалось Higgins; 29.12.2010 в 23:56.
Higgins ZX Spectrum Emulator 8.10 alpha 3 available
Please write us to report a bug or request a feature.
Ммм ... Как бы более правильно объяснить ... Поскольку практически никто не пользовался ASAM'ом, я не особо расписывал макросы ...
Смотри: "." и ".." Это описание макроса или цикла ...
Всё, что идёт дальше это не особо но умный макрос, который не понимает IF. В данном случае ты попытался компилятору разъяснить что хочешь создать макрос. Когда я расписывал пример некого подобия бейсика, то я приводил пример макросов, которые потом превращается в код, причём код не оптимизированный.
Как я понял ты хочешь получить компиляцию отдельных строк по условию. Я в компиляторе не ставил задачи реализовывать условия, потому что для этого я в компилятор встроил эмулятор ZX-SPECTRUM'а, без видео, конечно.
Если тебя устраивает простой флаг, да нет, то можно сделать так:
Если тебе нужно более сложные операции, то их нужно описать, например:Код:FLAG EQU 1 .FLAG DB "TRUE" .. .1-FLAG DB "FALSE" ..
То есть компилятор рассчитан на то, что программист сам себе создаст любые макросы, которые он считает удобными. Практика показывает, что мне хватает простого флага 0/1 ... Более сложные операции тянут за собой целые системы. Например я пишу текст для скролла и у меня есть шрифт. Зачем мне в памяти хранить графику для буквы, которая никогда не появится на экране ? Я пишу программу которая анализирует весь текст или тексты, и составляет таблицу. И пишу вторую программу которая по таблице сохраняет нужную графику каждой буквы. Далее для компилятора я использую команду SetTextXOR, в которой говорю, что далее всё что будет заключено в кавычки, нужно перекодировать. Например код буквы "A" станет каким-то кодом, который будет в таблице. И ву-а-ля, минимум памяти, и текст компактный.Код:;==================== ;Это макрос описывающий сравнение входящего переметра A с B ;==================== .IF (<) THEN√ ORG 0 EQU $ZX.R.PC=16384 LD A,@.0 ;Параметр макроса А CP @.1 ;Параметр макроса В RLA AND 1 LD C,A ;Запихиваем с ВС результат сравнения LD B,0 EQU $ZX.R.Break=$+$ZX.R.PC MoveMemAZ $ZX.R.PC,$ZX.R.PC,0,$-$ZX.R.PC ;Копируем из памяти компилятора в память эмулятора откомпилированный блок RunEmulZX ;Запускаем откомпилированный код ORG @. EQU IF_FLAG=$ZX.r.BC ;Результат эмулятора ВС передаём во флаг .. ;======================== ; Теперь сама программа которая использует макрос, который в совю очередь использует эмулятор ;======================== IF_FLAG EQU 0 ORG #8000 START IF (7<6) THEN .IF_FLAG DB "A < B" .. .1-IF_FLAG DB "A > B" .. SaveBIN "TEST.BIN",START,$-START
Да, я согласен, что нужно потратить время на эти макросы. Но за-то у тебя появляется возможность в макрос впихнуть целый код, который на уровне компилятора сам за тебя всё разберёт по-полочкам и в конце концов выдаст тебе конфетку, которая уже завёрнута в бумажку.
Сразу хочу предупредить ... RunEmulZX запускает эмулятор не взирая на то, все ли метки собрал компилятор ... Данный пример макроса был написан так, что бы входные параметры требовали только одного прохода. Если код внутри макроса сложный, то нужно использовать RunEmulZXne, то есть без ошибок до данного места. Но опять таки это не выгодно и наилучший способ предварительно, в отдельном файле создать все нужные макросы с внутренними кодами, записать их в отдельный файл. А уже при использовании макросов в программе грузить файл непосредственно в память эмулятора и запускать ... Вообщем я на этом написал кучу boot-loader'ов, скроллов, компрессоров и даже ОС для Speccy. Например в ОСи у меня создаются образы дисков для игры, в которую впихиваются тонны картинок, кода, музыки и лежат линейно, байт за байтом по образам. А в коде у меня это выглядит так:
Макросы ОСи сами добавляют нужный файл в образ, сами пакуют их и сами раздают ID каждому файлу. И в итоге в коде после раскрытия макроса это получается так:Код:LoadInData 'GFX\entire.scr', 18432 LD HL,20480 LD DE,22528+256 LD BC,256 LDIR LD B,50*2 HALT DJNZ $-1 LoadInData 'GFX\rob.scr', 16384 LD B,50*2 HALT DJNZ $-1 LoadInData 'GFX\mellona.scr', 16384 LD B,50*2 HALT DJNZ $-1
Этот ID мне не известен и не нужен, мне главное в тексте видеть, что я гружу. Так же можно создать таблицы из нужных нам файлов и грузить их по номеру ... Для этого я и создавал ASAM, для того, что бы одним нажатием у тебя собирался полностью рабочий проект.Код:LD HL,03765H ;ID файла LD DE,16384 ;адрес куда грузить данный CALL DOS.LOAD.FILEID
В одном из постов, ААА написал, что большинство времени уходит на допиливание лоадера. От этого я давно ушёл, лодаер LATRAX'а, например, трогался только один раз, где-то в августе. Если бы у меня хватило времени на загрузочную картинку, то тронул бы два раза.
AAA когда меня режут, я терплю, но когда дополняют, становится нестерпимо.
Мне, наверное, понадобится еще посидеть над тем, что ты написал.Что-то плохо понимаю что к чему, особенно причем тут эмулятор.
Задача вот какая. Пусть есть две строки текста:
Мне нужно, чтобы в случае, если значение $ после первой строки больше #8000, между этими двумя строками появлялась еще одна строка:DB "ABC"
DB "DEF"
Как это можно оформить?DB "X"
* * *
Снова UPDATE: теперь понимаю, причем здесь эмулятор.
Возникают следующие вопросы:
1) Надо понимать так, что весь макропроцессор написан через вызовы эмулятора? То есть, непосредственно языком поддерживается только сама возможность определения и использования макросов, но не их раскрытия?
2) Эти вызовы эмулятора происходят на каждом проходе? Если да, то с какими значениями меток, в том числе $, если раскрытие макроса зависит от этих значений?
Скажем, если изменить немного твой код:
Как в этом случае будут вычисляться значения меток? Или во время трансляции мы должны получить ошибку?ORG #8000-(END-START)
START
IF ($=#8000-2) THEN
.IF_FLAG
DB "X"
..
.1-IF_FLAG
DB "YY"
..
END
SaveBIN "TEST.BIN",START,$-START
Вообще, что делает ASAM в случае циклических зависимостей по меткам т что считается и не считается им за циклическую зависимость?
Последний раз редактировалось Higgins; 30.12.2010 в 14:41.
Higgins ZX Spectrum Emulator 8.10 alpha 3 available
Please write us to report a bug or request a feature.
Higgins ZX Spectrum Emulator 8.10 alpha 3 available
Please write us to report a bug or request a feature.
Нет ... Макропроцессор написан как простоя подмена входных параметров нужными значениями. Именно поэтому нужно писать 0+LOW(xxx), что бы компиллер понял, что это не макрос а цикл, восприняв первый "0" как число. Вообщем макросы раскрываются только в виде подставляемых в них параметров. Простая замена, а уже потом компилятор разбирает это число или команда или ещё один макрос ...
Да, на каждом проходе ... Отличие только в окончании ne ... RunEmulZX запустит в любом случае, а RunEmulZXne, только если нет ошибок компиляции ...
В этом случае будет зацикливание ... Что бы этого не было, нужно сделать так:
Зацикливание будет только в случае адреса #8003. Поскольку длина кода будет меняться от адреса куда попадает "Х" !!!Код:ORG #8006-(END-START) START DB "ABC" .0+LOW($/#8000) DB "X" .. DB "DEF" EQU END=$ SaveBIN "TEST.BIN",START,END-START
Эта строчка: "EQU END=$", нужна, что бы метка END была удалена после первого прохода. Таким образом ты объясняешь компилятору, что эта метка точно используется в тексте и не нужно её контролировать на наличие использования. В таком случае не будет ошибки и не будет зацикливаний ...
---------- Post added at 14:29 ---------- Previous post was at 14:16 ----------
Да - точно ... Я специально выбрал не использованный символ для входного параметра в макрос. А значёт вконце макроса (галочка в дос кодировке), эозначает, что всякие параметры далее запрещены, и если вдруг строчка вызываемая макрос их содердит, ты получишь ошибку. Так же можно создать макрос без значков и окончания. Тогда компилятор через запятую воспримет 10-ть значений макроса.
Например:
То есть компилятор первый параметр макроса поймёт как NOP, второй POР, третий LDIR, а четвёртый как пустая строчка. Конечно же в этом случае нужно помнить, что нельзя передать, например - "LD HL,16384", поскольку разделитель есть запятая ... Если нужно передавать более сложные параметры макроса, то лучше иначе его описать и придумать другие разделители.Код:.HELLO @.0 @.1 @.2 @.3 .. Далее вызываем макрос: HELLO NOP, POP, LDIR
---------- Post added at 14:37 ---------- Previous post was at 14:29 ----------
Не поддерживает. Чтобы описать 100% IF, тебе нужно писать все вариации IF'ов ... Это не язык высокого уровня и вложенность не поддерживает. То есть в макрос нельзя передать раскрытый макрос прямым путём ! Нелзья сделать макрос ABS(A) и его передать в IF (ABS(A)<0). Отдельно нужно получить значение из ABS и отдельно его передать в IF !
AAA когда меня режут, я терплю, но когда дополняют, становится нестерпимо.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)