Да...
Потеря подсветки синтаксиса - это оплата за единообразие подхода к написанию...
Это вполне приемлемая плата.
Почему простой .iclude *.asm не подходит - у разных компиляторов разное к ним отношение, а предпочтительно иметь однотипные оформления текстов и установок обработки. Чтоб меньше излишней мозготрепки...
Уже не помню на чем в прошлом облом получил - когда удалось получить удачное работоспособное решение просто копать глубже не стал.
Вопросы многофайловых проектов под ассемблером достаточно редко и слабо рассматриваются... Как только до этого доходит - сразу начинается миграция на ЯВУ.
Именно "слэнг" , причем с применением некоторых ограничений по директивам и подборке компиляторов/IDE и позволил получить практически одинаковую методику написания проектов как для MCS51, так и для AVR и PIC10/12/16.
Да и написание текстовок можно выполнять в одном редакторе с последующей подстановкой в конкретный проект.
Ограничения получают директивы имеющие различное толкование.
Основа - три распечатки с "заметками на полях".
Собственно расширение *.txt помимо прочего не нервирует автоматику мастера проектов IDE.
Результат меня весьма удовлетворяет.
Решил малость повыделываться над прожкой, что ранее (
https://radiokot.ru/forum/download/file.php?id=345868 ) выложил...
Попробуем изменить содержимое файла trd2812_m таким образом, чтобы он стал "частично перемещаемым" - там разве что "дырка" от 1 до 256 слов возникнуть может.
И сделаем это СРЕДСТВАМИ ПРЕПРОЦЕССОРА компилятора ассемблера.
Итак подрихтуем:
в начале файла поставим опорную метку
далее вычисляемое препроцессором относительно данной точки смещение для начала размещения табличного декодера
Код: Выделить всё
.org (bptr0 + (256 - (bptr0 & 0x00FF)))
slot0:
позиционку в самой программе делаем также как адрес начала предыдущего фрагмента +16...
И заменяем в slot 7
на
теперь вроде бы у нас стартовое значение slot0 должно быть всегда 0хNN00
....
Спойлер
Код: Выделить всё
;
;
; trd2812_ma.txt
;
; файл обработчика передачи массива
; из буфера вывода в линейку на основе WS2812B
; базовый МК из линейки АТМЕЛ при тактовой частоте
; от 16 Мегагерц ( 0,000000062 S)
;
; требуемые интервалы по даташиту WS2812B
;
;Data transfer time( TH+TL=1.25µs±600ns)
; T0H 0 code ,high voltage time 0.4us ±150ns
; T1H 1 code ,high voltage time 0.8us ±150ns
; T0L 0 code ,low voltage time 0.85us ±150ns
; T1L 1 code ,low voltage time 0.45us ±150ns
; RES low voltage time Above 50µs
; исходный уровень линии связи = 0
; данные передаются пакетами из трех байт на точку
; старшими битами вперед в последовательности
; соответствующей G - R - B цветам точки
; количество блоков должно соответствовать
; количеству точек в ленте
;
; реальные данные согласно тест - отладки дебаггером (версия1!)
; авр-студио 4.19
;
; Data transfer time( TH+TL=1.38µs -10ns)
; T0H 0 code ,high voltage time 0.44us ±10ns
; T1H 1 code ,high voltage time 0.88us ±10ns
; T0L 0 code ,low voltage time 0.94us ±10ns
; T1L 1 code ,low voltage time 0.50us ±10ns
; RES low voltage time 192,88uS (Above 50µs)
;
; длина прерывания с пакетом загрузки (x60*3) = 2175uS (0.002175)
; интервал между прерываниями (irq t/c0) = 0.004S (4000uS)
;
; define datas
; .equ port_out = PORTB ; порт вывода (по усмотрению)
; .equ out_line = 0 ; линия вывода данных
; .equ bufout = SRAM_START ; начальный адрес буфера вывода
; .equ pixel = 60 ; количество точек в линейке/ленте
; .equ bufout_size = (pixel * 3) ; не может быть более объема ОЗУ - стек!!!
;таблица обьявленных имен - переназначение регистров РОН
;
; .def name = r31 ; ZH регистр (полный)
; .def name = r30 ; ZL регистр (полный)
; .def name = r29 ; YH регистр (полный)
; .def name = r28 ; YL регистр (полный)
; .def name = r27 ; XH регистр (полный) указатель текущей ячейки массива bufout
; .def name = r26 ; XL регистр (полный) указатель текущей ячейки массива bufout
; .def name = r25 ; регистр (полный) BH
; .def name = r24 ; регистр (полный) BL
; .def name = r23 ; регистр (полный)
; .def name = r22 ; регистр (полный)
; .def name = r21 ; регистр (полный)
; .def name = r20 ; регистр (полный)
; .def name = r19 ; регистр (полный)
; .def name = r18 ; регистр (полный)
; .def tmp1 = r17 ; регистр (полный) счетчик байт вывода
; .def tmp0 = r16 ; регистр (полный) буфер выводимого байта
; .def regn = r15 ; регистр (урезан)
; .def regn = r14 ; регистр (урезан)
; .def regn = r11 ; регистр (урезан)
; .def regn = r10 ; регистр (урезан)
; .def regn = r9 ; регистр (урезан)
; .def regn = r8 ; регистр (урезан)
; .def regn = r7 ; регистр (урезан)
; .def regn = r6 ; регистр (урезан)
; .def regn = r5 ; регистр (урезан)
; .def regn = r4 ; регистр (урезан)
; .def regn = r3 ; регистр (урезан)
; .def regn = r2 ; регистр (урезан)
; .def matr = r1 ; регистр (урезан) r1 по возможности не использовать!!!
; .def madr = r0 ; регистр (урезан) r0 по возможности не использовать!!!
;
;-----------------------------------------
; .macro ;; ввод и предобработка данных
;
;
; .endmacro
;
;-----------------------------------------
;
; определение буфера вывода в области данных
; .dseg
; .org bufout
;point0: .byte 3 ; g:r:b
;point1: .byte 3 ; g:r:b
;point2: .byte 3 ; g:r:b
;point3: .byte 3 ; g:r:b
;point4: .byte 3 ; g:r:b
;point5: .byte 3 ; g:r:b
;point6: .byte 3 ; g:r:b
;point7: .byte 3 ; g:r:b
;point8: .byte 3 ; g:r:b
;point9: .byte 3 ; g:r:b
;point10: .byte 3 ; g:r:b
;point11: .byte 3 ; g:r:b
;point12: .byte 3 ; g:r:b
;point13: .byte 3 ; g:r:b
;point14: .byte 3 ; g:r:b
;point15: .byte 3 ; g:r:b
;point16: .byte 3 ; g:r:b
;point17: .byte 3 ; g:r:b
;point18: .byte 3 ; g:r:b
;point19: .byte 3 ; g:r:b
;point20: .byte 3 ; g:r:b
;point21: .byte 3 ; g:r:b
;point22: .byte 3 ; g:r:b
;point23: .byte 3 ; g:r:b
;point24: .byte 3 ; g:r:b
;point25: .byte 3 ; g:r:b
;point26: .byte 3 ; g:r:b
;point27: .byte 3 ; g:r:b
;point28: .byte 3 ; g:r:b
;point29: .byte 3 ; g:r:b
;point30: .byte 3 ; g:r:b
;point31: .byte 3 ; g:r:b
;point32: .byte 3 ; g:r:b
;point33: .byte 3 ; g:r:b
;point34: .byte 3 ; g:r:b
;point35: .byte 3 ; g:r:b
;point36: .byte 3 ; g:r:b
;point37: .byte 3 ; g:r:b
;point38: .byte 3 ; g:r:b
;point39: .byte 3 ; g:r:b
;point40: .byte 3 ; g:r:b
;point41: .byte 3 ; g:r:b
;point42: .byte 3 ; g:r:b
;point43: .byte 3 ; g:r:b
;point44: .byte 3 ; g:r:b
;point45: .byte 3 ; g:r:b
;point46: .byte 3 ; g:r:b
;point47: .byte 3 ; g:r:b
;point48: .byte 3 ; g:r:b
;point49: .byte 3 ; g:r:b
;point50: .byte 3 ; g:r:b
;point51: .byte 3 ; g:r:b
;point52: .byte 3 ; g:r:b
;point53: .byte 3 ; g:r:b
;point54: .byte 3 ; g:r:b
;point55: .byte 3 ; g:r:b
;point56: .byte 3 ; g:r:b
;point57: .byte 3 ; g:r:b
;point58: .byte 3 ; g:r:b
;point59: .byte 3 ; g:r:b
;
;-----------------------------------------
.cseg
bptr0:
nop
.org (bptr0 + (256 - (bptr0 & 0x00FF)))
slot0:
; 6/14 (6-4=2 посему роль остатка выполняет CBI)
cbi port_out,out_line ; 2 цикла
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret ; 4 цикла
.org (slot0+16)
slot1:
nop ; 13/7 (13-4=9)
nop
nop
nop
nop
nop
nop
cbi port_out,out_line ; 2 цикла
nop
nop
ret ; 4 цикла
;.org 0x0060
.org (slot1+16)
xslot0:
; 6/14 (6-5=1 посему роль остатка выполняет CBI с избытком в 1 nop)
cbi port_out,out_line ; 2 цикла
cbr zl,(1<<6) ; модификация указателя 1 цикл
nop
nop
nop
nop
nop
nop ; -2 цикла на ld tmp0,x+
dec tmp1 ; 1 цикл
brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле)
rjmp trasstt ; 2 цикла
.org (xslot0+16)
xslot1:
nop ; 13/7 (13-5=8)
cbr zl,(1<<6) ; модификация указателя 1 цикл
nop
nop
nop
nop
nop
cbi port_out,out_line ; 2 цикла
; -2 цикла на ld tmp0,x+
dec tmp1 ; 1 цикл
brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле)
rjmp trasstt ; 2 цикла
;
ends_trd:
pop tmp0
pop tmp1
pop xl
pop xh
pop zl
pop zh ; восстановить рабочую область из стека
ret
;-----------------------------------------
;
; предварительно:
; линия out_line настроена на вывод
; исходный уровень out_line =0
; указатель стека усатновлен на RAMEND
; массив данных (bufout:bufout_size) предварительно загружен
; флаг готовности массива данных установлен
;
mass_trm:
push zh
push zl
push xh
push xl
push tmp1
push tmp0 ; храним рабочую область в стеке
res_line:
ldi tmp0,4
ser tmp1
cbi port_out,out_line
res_time:
dec tmp1
brne res_time
dec tmp0
brne res_time ; =>50uS time out
ldi xh,high (bufout)
ldi xl,low (bufout) ; загрузка начального адреса массива
; в указатель
ldi tmp1,bufout_size
ldiw z,slot0 ; адрес начала таблицы в указателе
;-----------------------------------------
trasstt:
ld tmp0,x+ ; 2 цикла
slot_0:
sbi port_out,out_line ; 2 цикла реально до установки 3 цикла
bst tmp0,7 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла = 4 цикла от out_line=1
;----------------
slot_1:
sbi port_out,out_line
bst tmp0,6 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла
;----------------
slot_2:
sbi port_out,out_line
bst tmp0,5 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла
;----------------
slot_3:
sbi port_out,out_line
bst tmp0,4 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла
;----------------
slot_4:
sbi port_out,out_line
bst tmp0,3 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла
;----------------
slot_5:
sbi port_out,out_line
bst tmp0,2 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла
;----------------
slot_6:
sbi port_out,out_line
bst tmp0,1 ; 1 цикл
bld zl,4 ; 1 цикл
icall ; 3 цикла
;----------------
slot_7:
sbi port_out,out_line
;sbr zl,(1<<6) ; модификация указателя под завершающий фрагмент
sbr zl,(1<<5)
; 1 цикл
bst tmp0,0 ; 1 цикл
bld zl,4 ; 1 цикл
ijmp ; 3 цикла
;----------------
Только вот... при создании "перемещаемой таблицы" потребовалось введение опорной контрольной точки
внутри файла...
Да размер окна задать не в 32 слова, а в 256... (размер "компонентов" задан как 16 слов)
