Важная информация

User Tag List

Показано с 1 по 8 из 8

Тема: ПК8000 - Ассемблер

  1. #1
    Member Аватар для scaraby
    Регистрация
    06.06.2015
    Адрес
    г. Раменское, Московская обл.
    Сообщений
    79
    Благодарностей: 75
    Записей в дневнике
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию ПК8000 - Ассемблер

    А кто каким ассемблером пользуется для написания программ для этого компьютера? В детстве я использовал ASSM, который поставлялся на кассете с системными программами. При его запуске упоминался в качестве автора некий товарищ Карабутов. Неудобство состояло в том, что код исполнялся сразу и без вопросов, поэтому любой неверный шаг приводил к зависанию и утомительной загрузке с кассеты среды программирования. Тем не менее, с помощью этой программы можно было заглянуть внутрь игр, что-то даже своё наваять. Однако ассемблер там однопроходной, метки при любом телодвижении нужно править вручную - это ад и израиль!

    В настоящее время пользуюсь следующей технологией для создания готовых wav-файлов, пригодных для загрузки на реале:

    1. Исходник пишу в "Прекрасный ассемблер КР580ВМ80А" онлайн по адресу http://asdasd.rpg.fi/~svo/i8080/ Туда же можно закидывать текстовые исходники, написанные в чём угодно, хоть в блокноте. В сравнении с ASSM - счастье просто! Результаты творческих изысканий отражаются справа в окне "на лету". Результатом работы является бинарник, который можно смело внедрять в память ПК8000 и запускать на выполнение.

    2. В эмуляторе emu загружаю пакет ASSM командой bload"ASSM",r и для удобства сохраняю это состояние, чтобы одним кликом сразу попадать в ASSM. На реале эта процедура занимает несколько минут: поиск на кассете, загрузка, ошибки загрузки, если плохой магнитофон и т.д.

    3. Находясь в ASSM внутри emu выбираю пункт меню View/Start Debugger. Далее в открывшемся окне Ctrl+L (загрузить бинарник), указываю адрес в который грузить содержимое бинарника. Этот адрес является тем же адресом, который указывается директивой .org в "Прекрасном". После выполнения загрузки директивой ASSM-a G - запускаю на выполнение загруженный фрагмент кода.

    4. Чтобы загрузить этот код в реальный ПК8000, использую директиву ASSM-а W ИмяФайла АдресНачала АдресКонца АдресЗапуска. Например W TEST01 4000 4100 4002. Не забываю при этом перед нажатием Enter включить кнопку "Record/Stop" на панели эмулятора emu и выбираю соответствующий wav файл, готовый для загрузки.

    5. Если не нужен wav, а cas, то не использую команду "Record/Stop", директива W обрабатывается эмулятором и создаёт корректный cas.

    Технология получилась вполне рабочая и проверена практикой, однако, несколько громоздкой. Может, у кого-то есть опыт или идеи, как проще пройти путь от текстового исходника до реального wav?

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

    Ну и вдогонку, в качестве примера небольшой исходник, который в графическом режиме зажигает точку на экране в выбранной позиции, ждёт нажатия упр-стоп и выходит в ASSM. На реале в Бейсик.
    Код:
    	;ПК8000
    	;Прекрасный ассемблер КР580ВМ80А
    	;http://asdasd.rpg.fi/~svo/i8080/
    
    	;Программа определяет адрес байта в массиве графики для графического курсора
    	;Массив графики располагается в адресах ОЗУ 0000h-17ffh
    	;Нумерация идёт по принципу знакомест 32х24. Знакоместо (0,0) имеет адреса
    	;0000h-0007h, (0,1) 0008h-000fh, (1,0) 0100h-0107h и т.д.
    	;в hl - искомый адрес видео озу, с - номер бита точки на которую указывает
    	;графический курсор. a - маска для операции с точкой (гашение/свечение)
    
    .binfile GraphCursor.bin
    .org 4000h	;начальный адрес программы в ОЗУ
    
    	;Чтение байта из видеоОЗУ. 004ah hl - адрес, a - байт
    VRAMRead equ 004ah
    
    	;Включение режима экрана. Точка входа в ПЗУ: 006Ah или 286Dh A=режим {0,1,2}
    
    Screen equ 286dh
    
    	;Опрос нажатия Упр+Стоп.3759h Если «Упр+Стоп», то флаг C:=1
    
    CtrlBreak equ 3759h
    
    	;Возврат в СПА
    
    Exit equ 0ea8ah
    
    GraphCursor db 00h,00h	;координаты графического курсора x,y (0-255,0-191)
    
    Start:
    
    	mvi a,02h	;выбор номера режима
    	call Screen	;установка режима 2
    
    	;модуль определения адреса искомого байта в видеоОЗУ
    
    	lhld GraphCursor	;координаты курсора в привычной форме
    	mov a,l		;взяли координату х
    	ani 07h		;в аккумуляторе остаток от деления x/8
    			;это - номер (положение) точки внутри байта в массиве графики
    	inr a		;используется как счётчик при формировании маски
    	mov c,a		;запоминаем его в регистре c
    
    	mov a,l		;взяли повторно координату х
    	ani 0f8h	;отбросили остаток от деления x/8
    			;это - адрес нулевого байта соответствующего знакоместа
    	mov l,a		;запоминаем его в регистре l
    
    	mov a,h 	;взяли координату y
    	ani 07h		;остаток от деления x/8 - номер строки внутри знакоместа
    	add l		;прибавили его к адресу нулевого байта знакоместа
    	mov l,a		;младший полубайт адреса готов.
    
    	mov a,h		;взяли координату y
    	ani 0f8h	;отбросили остаток от деления y/8
    	rrc
    	rrc
    	rrc		;разделили нацело y/8
    	mov h,a		;старший полубайт адреса готов
    
    	;формируем в аккумуляторе маску для видеоОЗУ
    
    	xra a		;инициализация маски. Записываем в аккумулятор 01h
    	inr a
    loop01:
    	rrc		;устанавливаем соответствующий бит маски
    	dcr c		;номер бита, полученный ранее из координаты x
    	jnz loop01
    
    	;зажигаем точку на экране
    
    loop02:
    	mov c,a		;зажигаем одну точку, не изменяя соседние маска в с
    	call VRAMRead	;прочитали байт из массива графики
    	ora c		;добавили точку к прочитанному
    	mov m,a		;сохранили результат
    
    EventLoop:
    	call CtrlBreak	;опрос клавиатуры
    	jnc EventLoop
    
    
    	mvi a,0h	;выбор номера режима
    	call Screen	;установка режима 0
    
    	call Exit	;возврат в СПА

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Activist
    Регистрация
    18.02.2010
    Адрес
    г. Пенза
    Сообщений
    307
    Благодарностей: 164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Пользуюсь макроассемблером M80. Точнее кроссассемблером. Его макроязык похож на привычный TASM и MASM, хотя довольно примитивный. Вместо оболочки использую встроенный редактор файлового менеджера Folder Manager, неплохо справляющийся с подсветкой текста.
    Компилирую либо в CAS, применив соответствующий заголовок, либо в COM. CAS можно сразу загружать в эмулятор по BLOAD (пару секунд по времени занимает), либо конвертировать в WAV и загрузить на реальный. Конвертирую в CAS2COM. Загружаю любым плеером, выставив в настройках режим MONO. COM-файлы в Total Commander можно записать в образ диска/винта, для CP/M.

  4. Этот пользователь поблагодарил DemonId7 за это полезное сообщение:
    scaraby (08.03.2016)

  5. #3
    Member Аватар для scaraby
    Регистрация
    06.06.2015
    Адрес
    г. Раменское, Московская обл.
    Сообщений
    79
    Благодарностей: 75
    Записей в дневнике
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Это речь об вот этом идёт?

    http://www.retroarchive.org/cpm/lang/MACRO-80.PDF

    Если я правильно понял, то он под CP/M работает? Как вы его под Windows запускаете? Через эмулятор или в какой-то среде?

  6. #4
    Activist
    Регистрация
    18.02.2010
    Адрес
    г. Пенза
    Сообщений
    307
    Благодарностей: 164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    О нем. Только под платформу PC: M80
    В аттаче шаблоны для компиляции в CAS и COM.
    К сожалению в свободном доступе только незарегистрированная версия, с серьезными ограничениями.

    Еще могу порекомендовать поискать файлик с макросами к Turbo Assembler. Он вроде поддерживает все команды 8080. Сам наверное на него перейду, надоели ограничения незарегистрированной версии M80, это не считая "родных" ограничений.
    Непонимаю я этих писак - делать ограничения на продукт, которым будут пользоваться лишь десяток-другой любителей? Глупость, по моему. Ну да не мне их судить
    Вложения Вложения
    • Тип файла: zip M80.ZIP (850 байт, Просмотров: 51)
    Последний раз редактировалось DemonId7; 09.03.2016 в 12:01.

  7. #5
    Activist Аватар для hantarex
    Регистрация
    03.08.2010
    Адрес
    Ставрополь
    Сообщений
    286
    Благодарностей: 31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    есть TASM(Telemark Assembler). поддерживает 8080/8085/Z80. правда он под дос. и насчет мнемоник 8080 не уверен.
    ПК8000 "Веста", "Сура". ПК8002 "Эльф". ПК8010,8020 "Корвет".

  8. #6
    Member Аватар для scaraby
    Регистрация
    06.06.2015
    Адрес
    г. Раменское, Московская обл.
    Сообщений
    79
    Благодарностей: 75
    Записей в дневнике
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Продолжаю упражняться в программировании на ассемблере. На этот раз нарисовал сетку на экране, прикрутил клавиатуру, чтобы двигать точку по экрану, не вылезая за пределы. Разумеется, всё это в графическом режиме. Потрясающий размер программы в коде: 240 байт! Массив цвета пока не трогаю. Точка перемещается по экрану с шагом в один пиксель, поддерживается диагональное перемещение при одновременном нажатии двух кнопок. Скорость перемещения такая, что все фазы перемещения точки не успевают отрисовываться на экране. Состояние VRAM изменяется быстрее, чем к ней обращается "видеокарта".

    Код:
    	;ПК8000
    	;Прекрасный ассемблер КР580ВМ80А
    	;http://asdasd.rpg.fi/~svo/i8080/
    
    	;Программа позволяет клавишами управления курсором перемещать точку по
    	;экрану. Процедура определения адреса точки в видео-ОЗУ и маски выделена
    	;в отдельный модуль, который вызывается из процедур "зажигания" и 
    	;"гашения" точки.
    
    .binfile GraphCursor.bin
    .org 4000h	;начальный адрес программы в ОЗУ
    
    ;---------------------------------------------------------------------------------
    ; Константы
    ;---------------------------------------------------------------------------------
    
    	;Включение режима экрана. Точка входа в ПЗУ: 006Ah или 286Dh A=режим {0,1,2}
    Screen equ 286dh
    
    	;Опрос нажатия Упр+Стоп.3759h Если «Упр+Стоп», то флаг C:=1
    CtrlBreak equ 3759h
    
    	;Возврат в СПА
    Exit equ 0ea8ah
    
    ;---------------------------------------------------------------------------------
    ; Переменные
    ;---------------------------------------------------------------------------------
    
    GraphCursor db 0ah,0ah	;координаты графического курсора x,y (0-255,0-191)
    AdressVRAMCursor db 0,0
    BackgroundCursor db 0
    
    	;область в ОЗУ, в которой сохраняется состояние клавиатурной матрицы
    Keyboard db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh
    
    ;---------------------------------------------------------------------------------
    ; Главный модуль
    ;---------------------------------------------------------------------------------
    
    Start:
    
    	mvi a,02h	;выбор номера режима
    	call Screen	;установка режима 2
    
    	call Grid	;рисуем на фоне сетку
    
    Drawing:
    	
    	call GetAdressCursor	;определение адреса и маски точки в массиве графики
    	shld AdressVRAMCursor
    	xra b		;зажигаем точку
    	mov m,a		;кладём её в видео-ОЗУ
    	lxi h,BackgroundCursor
    	mov m,b		;сохраняем состояние
    
    EventLoop:
    	call KeyPress	;опрос клавиатуры
    	jz EventLoop
    
    	lxi h,BackgroundCursor
    	mov b,m		;восстанавливаем видео-ОЗУ
    	lhld AdressVRAMCursor
    	mov m,b
    
    	;нажатие и анализ
    	lxi h, Keyboard+8	;адрес строки с состоянием кнопок управления курсором
    	mov b, m	;запоминаем это состояние, чтобы не дёргать ОЗУ постоянно
    
    	mvi a, 0ffh	;сбросили клавиатуру в исходное состояние
    	mov m, a
    
    	lhld GraphCursor	;помещаем в de координаты графического курсора
    	xchg
    	
    	mvi a, 080h	;нажата стрелка вправо?
    	ana b
    	cz MoveRight
    
    	mvi a, 040h	;нажата стрелка вниз?
    	ana b
    	cz MoveDown
    
    
    	mvi a, 020h	;нажата стрелка вверх?
    	ana b
    	cz MoveUp
    
    	
    	mvi a, 010h	;нажата стрелка влево?
    	ana b
    	cz MoveLeft
    
    	xchg
    	shld GraphCursor
    
    	call CtrlBreak
    	jnc Drawing
    
    
    	mvi a,0h	;выбор номера режима
    	call Screen	;установка режима 0
    
    	call Exit	;возврат в СПА
    
    ;---------------------------------------------------------------------------------
    ; Процедуры
    ;---------------------------------------------------------------------------------
    
    	;изменение координат графического курсора
    
    MoveDown:
    	
    	mvi a, 0c0h	;нижний предел экрана x=192
    	inr d		;координата y:=y+1
    	cmp d
    	rnz		;всё в порядке, мы внутри, штатная ситуация
    	dcr d		;отмена изменения координаты курсора
    	ret
    
    MoveUp:
    	mvi a, 0ffh	;верхний предел экрана y=-1 (логически)
    	dcr d		;координата y:=y-1
    	cmp d
    	rnz		;всё в порядке, мы внутри, штатная ситуация
    	inr d		;отмена изменения координаты курсора
    	ret
    
    
    MoveRight:
    	
    	xra a		;правый предел экрана x=256 (логически)
    	inr e		;координата х:=х+1
    	cmp e
    	rnz		;всё в порядке, мы внутри, штатная ситуация
    	dcr e		;отмена изменения координаты курсора
    	ret
    
    
    MoveLeft:
    	
    	mvi a, 0ffh	;левый предел экрана x=-1 (логически)
    	dcr e		;координата х:=х-1
    	cmp e
    	rnz		;всё в порядке, мы внутри, штатная ситуация
    	inr e		;отмена изменения координаты курсора
    	ret
    ;---------------------------------
    
    
    
    
    	;Процедура опроса клавиатуры и регистрации нажатых клавиш
    	;Идея состоит в том, чтобы опросить состояние строк клавиатурной матрицы
    	;и запомнить его в ОЗУ для дальнейшего анализа
    	;если флаг Z=0, то ничего не нажато
    	;hl - адрес последней строки формируемого массива
    	;b - текущее состояние порта 82h
    	;с - счётчик количества строк клавиатуры (0ah)
    	;d - флаг нажатия. Если ничего не нажато, то 0ffh
    
    KeyPress:
    	di
    	lxi h, Keyboard+9	;адрес ОЗУ, в который сохраняем состояние кнопок
    	mvi c, 0ah	;счётчик количества строк клавиатуры (10)
    	in 82h		;читаем порт, чтобы не потерять его состояние
    	ani 0f0h	;формируем в младшем полубайте номер строки клавиатуры
    	adi 09h		;опрос от 9-й строки к 0-й
    	mvi d, 0ffh	;флаг нажатия. Если нажато, появляются нулевые биты
    
    loop001:	
    	out 82h		;выбираем текущую строку клавиатуры
    	mov b, a	;сохраняем состояние порта 82h
    	in 81h		;читаем состояние текущей строки
    	mov m,a		;сохранили состояние текущей строки в массиве KeyPress
    	ana d		;если есть нажатие, то появятся нулевые биты
    	mov d, a	;запоминаем любые нули, важно их наличие в принципе
    	dcx h		;очередной байт в массиве KeyPress
    	dcr b		;очередная строка клавиатурной матрицы
    	dcr c		;счётчик количества строк
    	mov a,b		;формируем данные для выбора следующей строки
    	jnz loop001
    	
    	mvi a,0ffh	;проверка наличия нажатых клавиш
    	xra d		;флаг Z=0, если имеется хотя бы один нулевой бит
    	ei
    	ret
    ;---------------------------------
    
    
    
    	;Процедура определяет адрес байта в массиве графики для графического курсора
    	;Массив графики располагается в адресах ОЗУ 0000h-17ffh
    	;Нумерация идёт по принципу знакомест 32х24. Знакоместо (0,0) имеет адреса
    	;0000h-0007h, (0,1) 0008h-000fh, (1,0) 0100h-0107h и т.д.
    	;в hl - искомый адрес видео озу, с - счётчик, номер бита точки на которую 		
    	;указывает графический курсор, b - байт, извлечённый из видео-ОЗУ
    	;a - маска для операции с точкой (гашение/свечение)
    	;
    
    	;Временно по найденной координате зажигается точка.
    
    
    GetAdressCursor:
    	lhld GraphCursor	;координаты курсора в привычной форме
    	mov a,l		;взяли координату х
    	ani 07h		;в аккумуляторе остаток от деления x/8
    			;это - номер (положение) точки внутри байта в массиве графики
    	inr a		;используется как счётчик при формировании маски
    	mov c,a		;запоминаем его в регистре c
    
    	mov a,l		;взяли повторно координату х
    	ani 0f8h	;отбросили остаток от деления x/8
    			;это - адрес нулевого байта соответствующего знакоместа
    	mov l,a		;запоминаем его в регистре l
    
    	mov a,h 	;взяли координату y
    	ani 07h		;остаток от деления x/8 - номер строки внутри знакоместа
    	add l		;прибавили его к адресу нулевого байта знакоместа
    	mov l,a		;младший полубайт адреса готов.
    
    	mov a,h		;взяли координату y
    	ani 0f8h	;отбросили остаток от деления y/8
    	rrc
    	rrc
    	rrc		;разделили нацело y/8
    	mov h,a		;старший полубайт адреса готов
    
    	xra a		;формируем в аккумуляторе маску для видеоОЗУ
    	inr a		;инициализация маски. Записываем в аккумулятор 01h
    loop002:
    	rrc		;устанавливаем соответствующий бит маски
    	dcr c		;номер бита, полученный ранее из координаты x
    	jnz loop002
    	mov c,a		;сохранили маску в регистр c
    
    	;извлечение байта данных из видео-ОЗУ, сохраняем в  регистре b
    
    	di		;обработчики прерываний в ПЗУ, поэтому запрещаем прерывания
    	in 80h		;сохраняем состояние порта 80h в регистре d
    	mov d,a
    	mvi a,0ffh	;записываем в порт 80h единицы, тем самым выбирая ОЗУ для
    	out 80h		;всех диапазонов адресов
    	mov b,m		;читаем байт из видеоОЗУ в регистр b
    	mov a,d		;восстанавливаем конфигурацию адресного пространства
    	out 80h
    
    	mov a,c		;кладём маску в аккумулятор
    	ei		;разрешаем прерывания
    	ret
    ;---------------------------------
    
    
    
    
    	;Процедура Grid рисования сетки на экране
    
    Grid:
    
    	lxi h,1800h	;чтобы сработало тело цикла при нулевом значении "+1"
    	mvi c,08h	;считаем попутно байты внутри знакоместа
    Grid001:
    	dcx h
    	mvi m,81h	;рисуем вертикальные линии
    	dcr c
    	jnz Grid002
    	mvi m,0ffh	;в нужных местах вертикальные линии заменяем горизонтальными
    	mvi c,08h
    Grid002:
    	mvi a,07h	;в нижней строке знакоместа тоже горизонтальная линия
    	cmp c
    	jnz Grid003
    	mvi m,0ffh
    Grid003:
    	mov a,l		;проверяем, досчитали до нуля или ещё нет
    	ora h
    	jnz Grid001
    	ret
    Если кому интересно, как это работает в эмуляторе, ниже файл состояния эмулятора EMU. Разархивируем, открываем файл из EMU, попадаем сразу в Debugger, в нём жмём F5, оказываемся в среде ASSM, в которой подаём команду на запуск G 400F. Возврат в ASSM по нажатию Ctrl+F12 (Упр+Стоп).

    GraphCursor.zip

    Следующим шагом хочу сделать плавное перемещение спрайта 8 на 8 пикселей. Что меня всегда бесило в играх на ПК8000 - дискретное "тырканье" по знакоместам. Интересно выяснить, это проблема аппаратной реализации, нехватки быстродействия, чтобы обрабатывать плавную анимацию, или криворукость программистов.

  9. #7
    Veteran Аватар для MacBuster
    Регистрация
    05.07.2010
    Адрес
    Москва
    Сообщений
    1,011
    Благодарностей: 184
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от scaraby Посмотреть сообщение
    Скорость перемещения такая, что все фазы перемещения точки не успевают отрисовываться на экране.
    Насколько я понимаю, здесь скорость перемещения точки никак не регулируется т.к. нет привязки к кадровым прерываниям.

    Как это можно сделать?
    ZX81, ZX-Spectrum 48, ZX-Spectrum +2, Pentagon 128K, Sprinter, ZX Evolution (rev. C), V6Z80P 1.1, БК-0011М-01 + SMK512, УК-НЦ x9, TI99/4A + FlashROM99, Amiga 1230M

  10. #8
    Guru
    Регистрация
    07.08.2008
    Адрес
    г. Уфа
    Сообщений
    3,266
    Благодарностей: 935
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    В данной программе (GraphCursor) проще всего добавить ei до EventLoop: и hlt после.

  11. Этот пользователь поблагодарил ivagor за это полезное сообщение:
    MacBuster (29.05.2018)

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ассемблер для 48к на ленте
    от newart в разделе Программирование
    Ответов: 37
    Последнее: 20.09.2015, 22:48
  2. Переведите на ассемблер
    от Руслан в разделе Программирование
    Ответов: 2
    Последнее: 06.08.2012, 22:41
  3. Ассемблер 8080
    от Kakos_nonos в разделе Утилиты
    Ответов: 0
    Последнее: 21.09.2011, 22:35
  4. Ассемблер Z-80
    от sergey2b в разделе Пресса
    Ответов: 12
    Последнее: 11.07.2011, 22:41
  5. Изучаем Ассемблер с ААА!
    от Addison в разделе Для начинающих
    Ответов: 33
    Последнее: 07.07.2009, 23:52

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •