User Tag List

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

Тема: Начал программировать для Вектора

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    Регистрация
    15.02.2015
    Адрес
    г. Могилёв, Беларусь
    Сообщений
    939
    Спасибо Благодарностей отдано 
    16
    Спасибо Благодарностей получено 
    122
    Поблагодарили
    76 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Начал программировать для Вектора

    Начал программировать и написал техническое демо вывода спрайта, которым можно управлять курсором.
    Текст программы:
    Код:
    ;=======================================================================
    include "8085.inc"
    ;=======================================================================
    
    ORG 100h
    START:
    	DI               ; Запретить прерывания (т.к. пока не ясно какой вектор прерывания по адресу 0038h)
    	LXI  SP,0BFFFh	 ; установка стека
            MVI  A,0C3h      ; установить код команды JMP в
            STA  0000h       ; нулевой адрес и
            STA  0038h       ; адрес вызова прерывания.
            LXI  H,PROGRM    ; Установить адрес перехода по "БЛК","СБРОС"
            SHLD 0001h       ; (сразу после кода команды JMP)
            LXI  H,INIT ; Установить адрес перехода на обработку прерывания
            SHLD 0039h       ; (также после JMP)
            XRA  A           ; Этой командой проще всего записать в аккумультор ноль
            OUT  10h         ; и пересылкой кода 00h в порт 10h отключить квазидиск
            EI               ; Резрешить прерывания, т.к. переходы установлены
    		HLT	 ; Ждем вызова INIT
            JMP PROGRM       ; Перейти на начало программы
    
    ;Блок начальной установки
    ;выполняется один раз
    INIT:
    	DI
    	MVI  A,88h       ;Установить режимы портов: 02 - вывод, 03 - вывод
            OUT  00          ;мл.4 бита порта 01 - вывод, старшие 4 бита - ввод
            LXI  H,COLR15    ;в пару "HL" - адрес последнего цвета таблицы цветов
            MVI  D,16        ;в "D" - счетчик колич. устанавл. цветов (размер табл)
            MVI  E,15        ;в "E" - адрес для записи в ОЗУ цветогенератора
    INCOL_LOOP:
    	MOV  A,E         ;установить адрес ОЗУ цвета через
            OUT  02          ;порт 02
            MOV  A,M         ;взять в "A" байт (физический код) цвета из таблицы цветов
            OUT  0Ch         ;записать этот байт в ОЗУ цветогенератора и повторить
            OUT  0Ch         ;несколько раз для надежной записи по одному адресу,
            OUT  0Ch         ;т.к. в некоторых "Векорах" наблюдается очень плохая
            OUT  0Ch         ;запись в ОЗУ цветогенератора и лучше подстраховаться.
            OUT  0Ch         ;
            DCX  H           ;уменьшить адрес-указатель в таблице цветов
            OUT  0Ch         ;
            DCR  E           ;уменьшить адрес для ОЗУ цветогенератора
            OUT  0Ch         ;
            DCR  D           ;уменьшить счетчик байт в таблице цветов
            OUT  0Ch         ;
            JNZ  INCOL_LOOP  
    	MVI  A,88h       ;установить режимы портов 02-вывод, 03-вывод
            OUT  00          ;мл. 4 бита порта 01 - вывод, старшие 4 бита - ввод
            LDA  Border      ;взять цвет бордюра ячейки "Border" (матем. код) и
            OUT  02          ;установить цвет бордюра на 4-х младших битах порта 02
    	MVI A,0ffh       ;вертикальное положение экрана
            OUT  03          ;и установить в порт 03
    	LXI  H,VBLANK    ;Установить новый адрес перехода на обработку прерывания
            SHLD 0039h       ;(также после JMP)
    	EI		 ;разрешить прерывание
    	RET
    
    ;Обработчик кадрового прерывания
    VBLANK:
    	DI
    	PUSH H           ;Сохранить все регистры в стеке
            PUSH B           ;
            PUSH D           ;
            PUSH PSW         ;
    		
            MVI  A,8Ah       ;установить режимы портов 02-ввод, 03-вывод
            OUT  00          ;мл. 4 бита порта 01 - вывод, старшие 4 бита - ввод
            MVI  A,0FEh      ;установить в младшем разряде порта 03 нулевой потенциал
            OUT  03          ;чтобы опросить 1-ую линейку клавиатуры (курсоры)
            IN   02          ;взять из порта 02 физич. код нажатия клавиш линейки
    	CMA		 ;Инвертируем значение, чтобы биты нажатых клавиш
    			 ;соответствовали единицам
    	ANI 0f0h	 ;Отсекаем маской ненужное
            STA  control_state      ;поместить этот код в ячейку "control_state"
    		
    	MVI  A,88h       ;установить режимы портов 02-вывод, 03-вывод
            OUT  00          ;мл. 4 бита порта 01 - вывод, старшие 4 бита - ввод
            LDA  Border      ;взять цвет бордюра ячейки "Border" (матем. код) и
            OUT  02          ;установить цвет бордюра на 4-х младших битах порта 02
    	MVI A,0ffh       ;вертикальное положение экрана
            OUT  03          ;и установить в порт 03
    		
    	POP  PSW         ;вернуть все регистры из стека
            POP  D           ;
            POP  B           ;
            POP  H           ;
            EI               ;разрешить прерывание (иначе оно будет только один раз)
    	RET
    ;=======================================================================
    
    ;Переменные и константы
    
    xmax 			equ 30		;Максимум для переменной  xpos
    ymax 			equ 30		;Максимум для переменной  ypos
    
    left_key_mask 		equ 10h		;Маски бит клавиш курсора
    right_key_mask 		equ 40h
    up_key_mask 		equ 20h
    down_key_mask 		equ 80h
    
    left_key 		equ 1		;Логические коды клавиш курсора
    right_key 		equ 2
    up_key 			equ 3
    down_key 		equ 4
    no_key			equ 0		;Логический код "клавиша не нажата"
    
    
    control_state:				;Хранит инверсию линейки битов для клавиш курсора
    db 0
    
    hkey:					;Хранит логический код клавиш курсора горизонтальных стрелок,
    db 0					;либо no_key
    
    vkey:					;Хранит логический код клавиш курсора вертикальных стрелок,
    db 0					;либо no_key
    
    xpos:					;Горизонтальная координата спрайта
    db 14
    
    ypos:					;Вертикальная координата спрайта
    db 14
    
    oxpos:					;Копия старого значения xpos
    db 14
    
    oypos:					;Копия старого значения ypos
    db 14
    
    PROGRM:					;Начало программы
    
    	CALL CLEAR_SCREEN		;Очищаем экран
    
    
    PR_CYCLE:				;Главный цикл
    		
    	lda control_state		;Получаем линейку бит клавиш
    	ora a				;Если линейка пуста, то
    	jz RENDER			;переход на отображение спрайта
    	mov b,a				;Сохраним значение линейки в регистре b
    	mvi a, no_key			;Предварительно сбросим переменные hkey и vkey
    	sta hkey			;
    	sta vkey
    H_CHECK:				;Проверка нажатия клавиш курсора горизонтальных стрелок
    LEFT:					;Проверка кл. "Влево"
    	mov a,b				;Загружаем линейку бит клавиш
    	ani left_key_mask		;Проверяем линейку на бит соответствующий кл. "Влево"
    	jz RIGHT			;Если бит не установлен, то переход на проверку кл. "Вправо",
    	mvi a, left_key			;иначе сохраняем логический код клавиши "Стрелка влево" в
    	sta hkey			;переменную hkey
    	jmp V_CHECK			;Переход на проверку нажатия клавиш курсора вертикальных стрелок
    RIGHT:					;Проверка кл. "Вправо".	Делаем аналогично проверке кл. "Влево"
    	mov a,b
    	ani right_key_mask		
    	jz V_CHECK
    	mvi a, right_key
    	sta hkey
    V_CHECK:				;Проверка нажатия клавиш курсора вертикальных стрелок
    UP:					;Проверку кл. "Вверх" делаем аналогично предыдущим проверкам 
    	mov a,b
    	ani up_key_mask
    	jz  DOWN			;Переход на проверку кл. "Вниз" 
    	mvi a, up_key
    	sta vkey
    	jmp EXIT_FROM_CHECK		;Выход из проверок нажатий клавиш
    DOWN:					;Проверку кл. "Вниз" делаем аналогично предыдущим проверкам 
    	mov a,b
    	ani down_key_mask		
    	jz EXIT_FROM_CHECK		;Выход из проверок нажатий клавиш
    	mvi a, down_key
    	sta vkey
    		
    EXIT_FROM_CHECK:
    					;Блок обновления позиции спрайта
    H_POS:					;Обновление координаты x( переменная xpos)
    LEFT_DIRECTION_CHECK:			;Проверяем движение влево по нажатию кл. "Влево"
    	lda hkey			;Загружаем значение переменной hkey
    	cpi left_key			;Если клавиша не нажата,то
    	jnz RIGHT_DIRECTION_CHECK	;то переход на проверку движения вправо по нажатию кл. "Вправо"
    	lda xpos			;Загружаем значение переменной xpos
    	ora a				;Если значение переменной равно нулю (минимальное значение), то
    	jz V_POS			;переменную не изменяем, и уходим на обновление координаты y (переменная ypos),
    	dcr a				;иначе уменшаем значение переменной xpos
    	sta xpos			;и обновляем переменную  xpos
    	jmp V_POS			;Уходим на обновление координаты y (переменная ypos)
    RIGHT_DIRECTION_CHECK:			;Проверяем движение вправо по нажатию кл. "Вправо"
    	lda hkey			;Загружаем значение переменной hkey		
    	cpi right_key			;Если клавиша не нажата,то
    	jnz V_POS			;уходим на обновление координаты y (переменная ypos),
    	lda xpos			;Загружаем значение переменной xpos
    	cpi xmax			;Если значение переменной равна максимуму, то
    	jz V_POS			;переменную не изменяем, и уходим на обновление координаты y (переменная ypos),
    	inr a				;иначе увеличим значение переменной xpos
    	sta xpos			;и обновляем переменную  xpos
    V_POS:					;Обновление координаты y (переменная ypos),						
    UP_DIRECTION_CHECK:			;Проверяем движение вверх по нажатию кл. "Вверх"
    					;Делаем аналогично проверке двежения вправо
    	lda vkey
    	cpi up_key
    	jnz DOWN_DIRECTION_CHECK	;Переход на проверку движения вниз по нажатию кл. "Вниз"
    	lda ypos
    	cpi ymax
    	jz EXIT_FROM_DIRECTION_CHECK	;Выход из блока обновления
    	inr a
    	sta ypos
    DOWN_DIRECTION_CHECK:			;Проверяем движение вниз по нажатию кл. "Вниз"
    					;Делаем аналогично проверке двежения влево
    	lda vkey						
    	cpi down_key
    	jnz EXIT_FROM_DIRECTION_CHECK	;Выход из блока обновления
    	lda ypos
    	ora a
    	jz EXIT_FROM_DIRECTION_CHECK	;Выход из блока обновления
    	dcr a
    	sta ypos
    		
    EXIT_FROM_DIRECTION_CHECK:
    RENDER:					;Блок отображения спрайта на экране
    
    		
    	lda ypos			;Вычисляем экранный адрес вывода спрайта по координатам ypos и xpos
    	add a
    	add a
    	add a
    	mov l,a
    	lda xpos
    	adi 0e0h
    	mov h,a
    	push h				;Сохраняем экранный адрес вывода спрайта в стеке
    		
    	lda oypos			;Вычисляем экранный адрес области очистки по oypos и oxpos
    	add a
    	add a
    	add a
    	mov l,a
    	lda oxpos
    	adi 0e0h
    	mov h,a
    		
    	hlt				;Ждем начала нового кадра
    		
    	call CLEAR_AREA			;Очищаем область на экране со старым изображением спрайта
    	pop h				;Восстанавливаем экранный адрес вывода спрайта из стека
    	lxi b,SPRITE			;Заносим адрес данных спрайта в пару BC		
    	call SPR_OUT			;Выводим спрайт на экран
    		
    	lda xpos			;Сохраняем координаты спрайта как устаревшие
    	sta oxpos
    	lda ypos
    	sta oypos
    	jmp PR_CYCLE			;Переход на начало главного цикла
    
    
    	
    PR_END:					;Конец программы
    	JMP PR_END
    ;===================================================================================
    ;ПРОЦЕДУРЫ
    ;===================================================================================
    
    ;Очистка экрана
    
    CLEAR_SCREEN:
    	LXI  H,0C000h    ;Адрес начала экранного ОЗУ поместить в "HL"
    Pro:    MVI  M,0         ;Записать нули по адресу "HL"
            INX  H           ;Следующий адрес
            MOV  A,H         ;Проверить конец экранного ОЗУ:
            ORA  A           ;старший байт адреса = 00? - значит предыдущий
            JNZ  Pro         ;адрес был FFFFh - т.е. конец экр.ОЗУ, если нет - продолжение
    	RET
    ;--------------------------------------------------------------------------------
    
    ;Заполнение плоскостей
    
    SET_PLANE:
    	; вх a - номер плоскости 0..1
    	; вх b - значение заполнения
    	ora a		;Проверим номер плоскости
    	jnz SPL1	;Если не нулевая - прыгаем дальше
    	LXI  H,0E000h	;Заносим адрес нулевой плоскости в пару HL
    SP_LOOP1:
    	mov a,b		;Записать значение заполнения в аккумулятор
    	MOV  M,a	;Записать значение  по адресу "HL"
            INX  H          ;Следующий адрес
            MOV  A,H        ;Проверить конец экранного ОЗУ:
            ORA  A          ;старший байт адреса = 00? - значит предыдущий
            JNZ  SP_LOOP1   ;адрес был FFFFh - т.е. конец экр.ОЗУ и плоскости 0, если нет - продолжение
    	RET
    SPL1:
    	cpi 1		;Проверим номер плоскости
    	rnz		;Если не первая - выходим  из процедуры
    	LXI  H,0C000h	;Заносим адрес первой плоскости в пару HL
    SP_LOOP2:
    	mov a,b		;Записать значение заполнения в аккумулятор
    	MOV  M,a        ;Записать значение  по адресу "HL"
            INX  H          ;Следующий адрес
    	MOV  A,H        ;Проверить конец первой страницы экранного ОЗУ:
            cpi 0E0h        ;старший байт адреса <> ef( старший байт адреса предыдущей страницы)  - значит продолжение
    	jnz SP_LOOP2
    	ret
    ;------------------------------------------------
    
    ;Вывод спрайта
    
    SPR_OUT:
    
    	; вх HL - адрес на экране( 0 пл.)
    	; вх BC - адрес спрайта
    	mov a,l
    	adi 15		;Увеличваем вертикальную позицию спрайта на его высоту-1, так как спрайт выводится сверху вниз
    	mov l,a	
    	push h		;Сохраняем адрес спрайта на экране (плоскость 0)
    
    		
    REPEAT 15		;Выводим первый столбик для плоскости 0
    	ldax b
    	mov m,a
    	inx b
    	dcr l
    END REPEAT
    	ldax b
    	mov m,a
    	inx b
    		
    	pop h		;Востанавливаем адрес спрайта на экране (плоскость 0),
    	push h		;и снова сохраняем его
    	mov a,H		;Переходим в плоскость 1
    	sui 20h
    	mov h,a
    		
    REPEAT 15		;Выводим первый столбик для плоскости 1
    	ldax b
    	mov m,a
    	inx b
    	dcr l
    END REPEAT
    	ldax b
    	mov m,a
    	inx b
    		
    	pop h		;Востанавливаем адрес спрайта на экране (плоскость 0)
    	inr h		;Переход на столбец вправо 
    	push h		;Сохраняем  новый адрес спрайта на экране (плоскость 0)
    		
    REPEAT 15		;Выводим второй столбик для плоскости 0
    	ldax b
    	mov m,a
    	inx b
    	dcr l
    END REPEAT
    	ldax b
    	mov m,a
    	inx b
    		
    	pop h		;Востанавливаем адрес спрайта на экране (плоскость 0)
    	mov a,H		;Переходим в плоскость 1
    	sui 20h
    	mov h,a
    		
    REPEAT 15		;Выводим второй столбик для плоскости 1
    	ldax b
    	mov m,a
    	inx b
    	dcr l
    END REPEAT
    	ldax b
    	mov m,a
    	
    	ret
    ;------------------------------------------------
    		
    ;Очистка области 16 на 16 пикселей
    
    CLEAR_AREA:
    		
    	; вх HL - адрес области на экране( 0 пл.)
    	push h		;Сохраняем адрес области на экране (плоскость 0)
    	xra a   	;Получаем ноль в аккумуляторе
    REPEAT 7 		;Очищаем данные плоскости 0 "столбиком" по две строки за раз снизу вверх
    	mov m,a
    	inr h
    	mov m,a
    	inr l
    	mov m,a
    	dcr h
    	mov m,a
    	inr l
    END REPEAT
    	mov m,a
    	inr h
    	mov m,a
    	inr l
    	mov m,a
    	dcr h
    	mov m,a
    		
    	pop h		;Востанавливаем адрес области на экране (плоскость 0)
    	mov a,H		;Переходим в плоскость 1
    	sui 20h
    	mov h,a
    		
    	xra a		;Получаем ноль в аккумуляторе
    REPEAT 7		;Очищаем данные плоскости 1 "столбиком" по две строки за раз снизу вверх
    	mov m,a
    	inr h
    	mov m,a
    	inr l
    	mov m,a
    	dcr h
    	mov m,a
    	inr l
    END REPEAT
    	mov m,a
    	inr h
    	mov m,a
    	inr l
    	mov m,a
    	dcr h
    	mov m,a
    
    ret
    ;----------------------------------------------------------------------------------
    
    
    Border: DB 0           ;Цвет бордюра (сейчас соответствует цвету 0)
    
    COLR0:  DB 00h         ;Палитра цветов  
    COLR1:  DB 04h           
    COLR2:  DB 18h           
    COLR3:  DB 0c9h           
    COLR4:  DB 00h         ;Повтор цветов для отключения плоскостей 2 и 3 
    COLR5:  DB 04h           
    COLR6:  DB 18h           
    COLR7:  DB 0c9h         
    COLR8:  DB 00h           
    COLR9:  DB 04h           
    COLR10: DB 18h           
    COLR11: DB 0c9h            
    COLR12: DB 00h           
    COLR13: DB 04h           
    COLR14: DB 18h           
    COLR15: DB 0c9h                  
    
    ;Данные спрайта
    SPRITE:
    ;Первый столбик для плоскости 0
    DB 00000001b
    DB 00000001b
    DB 00000001b
    DB 00000000b
    DB 00000000b
    DB 00000000b
    DB 00000101b
    DB 00000010b
    DB 00000100b
    DB 00001001b
    DB 00000010b
    DB 00000100b
    DB 00001001b
    DB 00010010b
    DB 00000100b
    DB 00001001b
    ;Первый столбик для плоскости 1
    DB 00000001b
    DB 00000001b
    DB 00000001b
    DB 00000001b
    DB 00000011b
    DB 00000011b
    DB 00000110b
    DB 00000111b
    DB 00000011b
    DB 00000110b
    DB 00001111b
    DB 00001111b
    DB 00010110b
    DB 00011101b
    DB 00111111b
    DB 00010111b
    ;Второй столбик для плоскости 0
    DB 00000000b
    DB 00000000b
    DB 00000000b
    DB 00000000b
    DB 00000000b
    DB 10000000b
    DB 00000000b
    DB 01000000b
    DB 10000000b
    DB 00100000b
    DB 01000000b
    DB 10010000b
    DB 00100000b
    DB 01001000b
    DB 10010000b
    DB 00100000b
    ;Второй столбик для плоскости 1
    DB 00000000b
    DB 00000000b
    DB 00000000b
    DB 00000000b
    DB 10000000b
    DB 00000000b
    DB 11000000b
    DB 11000000b
    DB 11000000b
    DB 11000000b
    DB 10100000b
    DB 11110000b
    DB 11110000b
    DB 10110000b
    DB 11101000b
    DB 11110000b
    - - - Добавлено - - -

    В архиве исходный код, готовый ром и Ассемблер для сборки с библиотекой макросов от shoorick.
    VTEST.zip
    Кто какие процедуры использует для вывода строк и в какой кодировке?
    Последний раз редактировалось Smalovsky; 30.12.2025 в 16:55.
    ¡Un momento, señor fiscal!

    Этот пользователь поблагодарил Smalovsky за это полезное сообщение:

    Improver(30.12.2025)

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

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

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

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

Похожие темы

  1. Ответов: 123
    Последнее: 03.11.2025, 15:55
  2. Ответов: 111
    Последнее: 02.10.2025, 15:44
  3. Ответов: 11
    Последнее: 13.07.2021, 16:06
  4. Ответов: 3
    Последнее: 21.09.2018, 18:28
  5. Ответов: 45
    Последнее: 04.10.2007, 18:57

Ваши права

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