Shaos wrote:Да - картинка 64x50 получается, а у тебя реально было прямо 50 FPS?
Нет, конечно!
Если файл проигрывается почти 4 минуты - 240 секунд, то 6,892,800 байтов ROM-Диска делим и получаем примерно 28,720 байтов в секунду.
Один кадр 64x25 - 1600 байтов. Соответственно, получаем 17.95 fps.
Так как половина знакомест кодирует ещё и звук, получаем 800 сэмплов на кадр. Соответственно - 14,360 Гц должно быть.
Исходный код проигрывателяCode: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;
; VHS by Alikberov
;;;;;;;;;;;;;;;;;;;;;;;;;
TEMPY: EQU 00004H
TEMPA: EQU 00005H
DB 031H
PUSH B
PCHL
LXI SP,00000H
LXI SP,00600H
LXI H,V78X30
CALL VIDEO
LXI H,PWM@0
LXI D,AMP@0
MVI B,001H
;;;;;;;;;;;;;;;;;
LOOP: MVI C,020H
MOV A,M
INX H
STAX D
INX D
LOOP@1: PUSH H
LOOP@2: MOV A,M
INX H
ORA A
JNZ LOOP@5
MVI A,0DAH
STAX D
INX D
MOV A,E
ADI 004H
STAX D
INX D
MOV A,D
ACI 000H
STAX D
INX D
JMP LOOP@2
LOOP@5: STAX D
CPI 0C3H
JZ LOOP@3
INX D
JMP LOOP@2
LOOP@3: DCR C
JZ LOOP@4
POP H
JMP LOOP@1
LOOP@4: POP PSW
INX D
MOV A,M
INX H
STAX D
INX D
MOV A,M
INX H
STAX D
INX D
DCR B
JNZ LOOP
XCHG
SHLD KILL+1
MVI M,0C3H
INX H
MVI M,000H
INX H
MVI M,0F8H
MVI A,090H
STA 0A003H
LXI H,00000H
SHLD 0A001H
MVI A,001H
STA TEMPA
LXI H,00000H
SHLD 0A001H
LXI H,0A002H
MVI M,080H
MVI M,000H
MOVIE:
PARTS: LXI SP,036CFH
CALL PUTROM
LXI B,0A000H
LXI SP,03802H
MVI A,019H
FRAME: STA TEMPY
LXI D,0A001H
LXI H,AMP@0
LDAX B
INR A
JZ KILL
;;;;;;;;;;;;;;;;;
SHOW: PCHL
KILL: LXI SP,00600H
LXI H,00001H
MOV B,H
MOV C,H
PCHL
;;;;;;;;;;;;;;;;;
L0: JNZ L1
LDA TEMPA
MOV M,A
INX H
INR M
JP L2
INR A
STA TEMPA
JZ KILL
MVI M,000H
L2: DCX H
MVI M,000H
L1: LXI H,0008EH
DAD SP
SPHL
LDA TEMPY
DCR A
JNZ FRAME
PAUSE: LDA 0C001H
ANI 020H
JZ PAUSE
JMP PARTS
PUTROM: LXI B,03774H
LHLD 0A001H
LDA TEMPA
CALL PUTHEX
MOV A,H
CALL PUTHEX
MOV A,L
PUTHEX: CALL PUTNBL
PUTNBL: RRC
RRC
RRC
RRC
PUSH PSW
ANI 00FH
CPI 00AH
SBI 02FH
DAA
STAX B
INX B
POP PSW
RET
VIDEO: MOV A,M ; Читаем байт с ссылкой на порт УВВ.
ANI 0F0H ; Маскируем старшие биты адреса.
JP DVWAIT ; Если не указатель на УВВ, переходим к финалу.
MOV D,A ; Иначе, сохраняем их в регистре D и
MOV E,M ; вновь читаем байт с ссылкой на порт УВВ в регистр E.
INX H ; Переходим к байту с параметром
MOV A,M ; и читаем его.
STAX D ; Записываем этот параметр в порт УВВ.
INX H ; Переходим к следующему байту с ссылкой на УВВ
JMP VIDEO ; и продолжаем копирование параметров устройств.
DVWAIT: LDAX D ; Первое чтение сбрасывает все флаги.
LDAX D ; Теперь читаем активный статус,
ANA M ; маскируя лишние флаги.
JZ DVWAIT+1; Если бит всё ещё не установлен, продолжаем ждать.
INX H ; Переходим к финальным параметрам.
MOV A,M ; Читаем байт с ссылкой на порт УВВ.
ANI 0F0H ; Маскируем старшие биты адреса.
MOV D,A ; Сохраняем в регистре D и
MOV E,M ; читаем младшие биты адреса.
INX H ; Переходим к параметру запуска ПДП.
MOV A,M ; Читаем байт с командой запуска
STAX D ; и передаём в УВВ.
RET
V78X30: DB 0E8H,080H,0E4H,0D0H,0E4H,036H,0E5H,023H,0E5H,049H
DB 0C1H,000H,0C0H,04DH,0C0H,01DH,0C0H,099H,0C0H,0D3H
DB 0C1H,027H,020H,0E8H,0A4H
PWM@0: XCHG
LDAX B ; 7
RAL ; 4
NOP ; 10
EI ; 4
DB 0FEH ; 7
DI ; 4
ORA A ; 4
RAR ; 4
MOV D,A ; 5
INR M ; 10
LDAX B ; 7
MOV E,A ; 5
INR M ; 10
PUSH D ; 11=82 : 9x32=288
JMP L0 ; 10
;;;;;;;;;;;;;;;;;
AMP@0: DS 292
Как видите, сделать по 50 строк в кадре - правка трёх строчек.
Shaos wrote:Можно попробовать закодировать RLE - там теоретически должно быть быстрее повторяющиеся поля заполнять, чем вычитывать попиксельно с квазидиска (как минимум ненадо инкрементировать и устанавливать адрес на каждый байт)
Не-е, это пусть другие этим занимаются.
Я как-то, на базе .PIC-формата писал декомпрессор и на его базе разрабатывал оптимальный алгоритм, но компрессор - так и не написал.
Относительно формата сжатия для РК - могу предложить следующее:
Так как коды "Стоп ПДП" (F0/F1/F2/F3)
не должны попадаться в потоке, можно все коды C0-FF отдать под компрессию. То есть, закодировать до 64 команд PUSH махом. Что, однако, много, так как на всю строку в 64 знакоместа - 32 PUSH'а достаточно!
Следовательно, можно использовать ШИМ: До 16 PUSH'ей и 4 уровня звука.
Правда, есть нюанс: Мой код сейчас переключает страницу только в конце каждой строки, если адрес достиг 8000. Соответственно, нельзя допускать переполнения!
В конечном итоге, всё взваливается на код генерации ROM-содержимого.
(Сейчас у меня - это простой HTML/JS с тэгом video.)