    ; 🐟 для Апогея БК-01
    .project test_screen_apg.rk
    .tape rk-bin ; формат ленты 
    .org 0

; test_screen_output

;-----------------------------------------------------------------------------------------

screen_adr   equ  $1000   ; адрес экранной области (можно переназначить в другое место)

; параметры горизонтальной строки (в символах)
h_back       equ  8   ; отступ слева
h_act        equ  64  ; видимых символов в строке
h_front      equ  6   ; отступ справа
h_sync       equ  8   ; строчный синхроимпульс (2..32)
h_total      equ  h_back + h_act + h_front  ; общее количество символов в строке без учёта синхроимпульса (1..80)

; параметры кадра (в строках)
v_back       equ  4   ; отступ сверху
v_act        equ  36  ; видимых строк в кадре
v_front      equ  3   ; отступ снизу
v_sync       equ  1   ; кадровый синхроимпульс (1..4)
v_total      equ  v_back + v_act + v_front  ; общее количество строк в кадре без учёта синхроимпульса (1..64)

row_lines    equ  7  ; линий в строке (1..16)
under_line   equ  8  ; позиция линии подчёркивания в строке (1..16) если этот параметр больше 8, то верхняя и нижняя линии в строке гасятся
spaced_row   equ  0   ; пропущенные строки (0..1) если 1, то каждая вторая строка гасится (соответственно и строк в кадре надо указывать в два раза меньше, и память под экран занимает в два раза меньше)
line_offset  equ  0   ; смещение для первой линии в строке символов (0..1) если 1, то первая линия строки будет отображаться второй (для псевдографики нужно ставить 0)
spaced_atr   equ  1   ; отображаемые атрибуты (0..1) если 1, то атрибут отображается как пустой символ и занимает место в видеопамяти
cursor_type  equ  1   ; тип курсора (1..4)

; команды и параметры для инициализации контроллера дисплея
disp_port_param  equ  $ef00  ; адрес порта параметров контроллера дисплея
disp_port_cmd    equ  $ef01  ; адрес порта команд контроллера дисплея
disp_cmd_reset   equ  0      ; команда Сброс Дисплея
disp_init_1      equ  spaced_row*128 + h_total-1
disp_init_2      equ  (v_sync-1)*64 + v_total-1
disp_init_3      equ  (under_line-1)*16 + row_lines-1
disp_init_4      equ  line_offset*128 + spaced_atr*64 + cursor_type*16 + h_sync/2-1
disp_cmd_cursor  equ  $80    ; команда Установка Курсора
disp_cmd_start   equ  $27    ; команда Запуск Дисплея
disp_flag_ir     equ  $20    ; константа для проверки флага Запрос Прерывания

; команды и параметры для инициализации контроллера ПДП
dma_port_cmd     equ  $f008  ; адрес команд контроллера ПДП
dma_cmd_reset    equ  $80    ; команда Сброс ПДП
dma_init_1       equ  screen_adr & $00ff
dma_init_2       equ  screen_adr >> 8
dma_init_3       equ  ($4000 + h_total*v_total - 1) & 0x00ff
dma_init_4       equ  ($4000 + h_total*v_total - 1) >> 8
dma_cmd_start    equ  $A4    ; команда Запуск ПДП

; подпрограммы Монитора
wait_any_key     equ  $f803   ; ожидание нажатия клавиши
display_restart  equ  $f82d   ; инициализация экранной области Монитора
call_cmd_line    equ  $f875   ; возврат управления в командную строку

;-----------------------------------------------------------------------

program_begin:

	lxi	h, screen_adr
	lxi	d, 0x3030
	lxi	b, 0
	
fill_screen:

  mvi  m, 0          ; очищаем знакоместо
  mov  a, b          ; берём счётчик строк
  cpi  v_back        ; проверяем отступ сверху
  jc   inc_c         ; если меньше, то увеличиваем счётчик знакомест
  cpi  v_back+v_act  ; проверяем отступ снизу
  jnc  inc_c         ; если не меньше, то увеличиваем счётчик знакомест
  
  mov  a, c          ; берём счётчик знакомест
  cpi  h_back        ; проверяем отступ слева
  jc   inc_c         ; если меньше, то увеличиваем счётчик знакомест

  cpi  h_back+h_act  ; проверяем отступ справа
  jz   inc_d         ; если равно, то увеличиваем счётчик символов
  jnc  inc_c         ; если больше, то увеличиваем счётчик знакомест
  mov  a, e          ; иначе берём символ
  ani  0x7f          ; применяем маску
  mov  m, a          ; и выводим на экран
  inr  e             ; устанавливаем следующий символ
  jmp  inc_c         ; увеличиваем счётчик знакомест

inc_d:
  inr  d
  mov  e, d

inc_c:
  inx  h
  inr  c
  mov  a, c
  cpi  h_total
  jc   fill_screen
  mvi  c, 0
  inr  b
  mov  a, b
  cpi  v_total
  jc   fill_screen

init_display:
	lxi	h, disp_port_cmd
	mvi	m, disp_cmd_reset
	dcr	l
	mvi	m, disp_init_1
	mvi	m, disp_init_2
	mvi	m, disp_init_3
	mvi	m, disp_init_4
	inr	l
	mvi	m, disp_cmd_cursor
	dcr	l
	mvi	m, $ff
	mvi	m, $ff
	inr	l
	mvi	m, disp_cmd_start
	mov	a, m

vsync_wait:
	mov	a, m
	ani	disp_flag_ir
	jz	vsync_wait
	
init_dma:
	lxi	h, dma_port_cmd
	mvi	m, dma_cmd_reset
	mvi	l, 4
	mvi	m, dma_init_1
	mvi	m, dma_init_2
	inr	l
	mvi	m, dma_init_3
	mvi	m, dma_init_4
	mvi	l, 8
	mvi	m, dma_cmd_start


program_end:
	call	wait_any_key
	call	display_restart
	jmp	call_cmd_line

;-------------------------------------------------------------------
