Files
2026-08-31 21:04:48 +03:00

723 lines
14 KiB
NASM

;---------------------------------------
; CLi² (Command Line Interface)
; 2013,2015 © breeze/fishbone crew
;---------------------------------------
; SXG file loader
;---------------------------------------
sxgBufferSize equ 16 ; 16*512 = 8192 Размер буфера в блоках по (512кб)
org #c000-4
include "system/constants.asm" ; Константы
include "system/api.h.asm" ; Список комманд CLi² API
include "system/errorcodes.asm" ; коды ошибок
include "drivers/drivers.h.asm" ; Список комманд Drivers API
appStart
db #7f,"CLA" ; Command Line Application
;---------------------------------------------
xor a
ld (sxgFileCheck+1),a
ld (setViewerMode+1),a
ld a,#02
ld (widthLoop+2),a
ld a,#10
ld (setVBank+1),a
ex de,hl
ld a,eatSpaces
call cliKernel
ex de,hl
ld a,(hl)
cp #00
jp z,sxgShowInfo ; Выход. Вывод информации о программе
ex de,hl
ld a,eatSpaces
call cliKernel
ex de,hl
ld de,keyTable
ld a,checkCallKeys
call cliKernel
cp #ff
jp z,sxgShowInfo ; Выход. Вывод информации о программе
ld a,(hl)
cp #00
jp nz,sxgContinue
sxgFileCheck ld a,#00
cp #01
jp z,setViewerMode
jp fileNotSet ; Выход. Не задан файл
sxgContinue ex de,hl
ld a,eatSpaces
call cliKernel
ld hl,fileNotFound_1+1
ld (hl),de
ex de,hl
ld de,sxgBuffer
ld b,sxgBufferSize
ld a,loadFileParts ; Загружаем первую часть в буфер
call cliKernel
cp #ff ; Если на выходе #ff = ошибка
jp z,fileNotFound
;---------------
ld hl,sxgBuffer
ld a,(hl)
cp #7f ; Сигнатура #7f + SXG
jp nz,wrongFile
inc hl
ld a,(hl)
cp "S"
jp nz,wrongFile
inc hl
ld a,(hl)
cp "X"
jp nz,wrongFile
inc hl
ld a,(hl)
cp "G"
jp nz,wrongFile
;---------------
push hl
ld hl,sxgFormatMsg
call sxgPrint
pop hl
;---------------
inc hl ; версия формата SXG
ld a,(hl)
push af
push hl
push af
ld hl,sxgVerMsg
call sxgPrint
pop af
ld de,sxgNumberMsg
ld h,#00
ld l,a
ld a,fourbit2str
call cliKernel
ld hl,sxgNumberMsg
call sxgPrint
pop hl
pop af ; TODO: Сделать проверку!!
;---------------
inc hl ; цвет фона для очистки
ld a,(hl)
; push af
ld (clrColor+1),a
push hl
push af
ld hl,sxgBgMsg
call sxgPrint
pop af
ld de,sxgNumberMsg
ld h,#00
ld l,a
ld a,fourbit2str
call cliKernel
ld hl,sxgNumberMsg
call sxgPrint
pop hl
;---------------
inc hl ; Тип упаковки данных (#00 - не пакованы)
ld a,(hl)
push af
push hl
push af
ld hl,sxgPackMsg
call sxgPrint
pop af
ld de,sxgNumberMsg
ld h,#00
ld l,a
ld a,fourbit2str
call cliKernel
ld hl,sxgNumberMsg
call sxgPrint
pop hl
pop af
; TODO: Сделать проверку!!
;---------------
push hl
ld hl,sxgTypeMsg
call sxgPrint
pop hl
inc hl
ld a,(hl)
ld (imageMode),a
push hl
call setImageMode
pop hl
cp #ff ; error -> exit
ret z
;---------------
sxgVMem ld b,#01
; pop af
; ld c,a
clrColor ld c,#00 ; номер цвета
ld a,clearGfxMemory ; Очищаем видеопамять
push hl
call cliKernel
pop hl
;---------------
push hl
ld hl,sxgWidthMsg
call sxgPrint
pop hl
;---------------
inc hl
ld c,(hl) ; Width 0-512
inc hl
ld b,(hl)
call sxgAlignX
;---------------
push hl
push bc
push bc
pop hl
ld de,sxgWidthMsg0
ld a,int2str
call cliKernel
ld hl,sxgWidthMsg0
call sxgPrint
ld hl,sxgHeigthMsg
call sxgPrint
pop bc
pop hl
;---------------
ld a,(imageMode) ; TODO: ZX Mode(?)
cp #01 ; 16c
jr nz,skipImageDec
ld a,#01
ld (widthLoop+2),a
xor a ; длина/2 = 4 бита на точку
srl b
rr c
jr c,skipImageDec
; dec c
; inc c
skipImageDec
ld (imageWidth),bc
ld (countWidth),bc
inc hl
ld c,(hl) ; Height 0-512
inc hl
ld b,(hl)
ld (imageHeight),bc
ld (countHeight),bc
call sxgAlignY
;---------------
push hl
push bc
pop hl
ld de,sxgHeigthMsg0
ld a,int2str
call cliKernel
ld hl,sxgHeigthMsg0
call sxgPrint
ld hl,sxgScreenMsg
call sxgPrint
ld hl,sxgLoadingMsg
call sxgPrint
pop hl
;---------------
inc hl
ld c,(hl) ; Указатель (смещение) на начало данных палитры
inc hl
ld b,(hl)
inc hl
push hl
add hl,bc ; Начало данных палитры
gPalNum ld b,#01 ; Номер экрана для кого грузить палитру
ld a,setGfxPalette
call cliKernel
pop hl
ld c,(hl) ; Указатель (смещение) на начало данных bitmap
inc hl
ld b,(hl)
inc hl
add hl,bc ; Начало данных bitmap
;---------------
call setVBank
ld de,#0000 ; Начало экрана
loadSxgLoop ld a,(hl)
ld (de),a
inc de
inc hl
ld bc,(countWidth)
dec bc ; Уменьшаем счётчик ширины
ld (countWidth),bc
ld a,b
or c
jr nz,nextWidth ; Если счётчик ширины ещё не 0, пропускаем nextWidth
ld bc,(imageWidth)
ld (countWidth),bc
widthLoop ld a,b ; Добиваем линию до 512
cp #02
jr z,noNeedWidth
inc bc
inc de
jr widthLoop
noNeedWidth ld bc,(countHeight)
dec bc
ld (countHeight),bc
ld a,b
or c
jr z,loadSxgStop
;--------
nextWidth ld a,d
cp #40 ; Проверяем, а не заполнили ли мы уже целую банку #4000
jr nz,skipIncBank ; Если нет, то пропускаем skipIncBank
ld a,(setVBank+1)
inc a
ld (setVBank+1),a
call setVBank
; ld de,#0000
ld d,#00
skipIncBank ld a,h ; Проверяем, а не закончились ли данные ?
or l
jr nz,loadSxgLoop ; Если нет, то на новый круг loadSxgLoop
ld (sxgStoreDe+1),de
ld a,loadNextPart ; Загрузить следующую часть в буфер
call cliKernel
cp #ff ; конец файла?
jr z,loadSxgEnd
sxgStoreDe ld de,#0000
call setVBank
ld hl,sxgBuffer
jp loadSxgLoop
loadSxgEnd ex af,af'
cp eFileEnd
jr nz,loadSxgLoop
loadSxgStop ld a,restoreWcBank
call cliKernel
;---------------------------------------------
setViewerMode ld a,#00
cp #01
jr nz,loadSxgExit ; если не задан режим вьювера - просто выход
ld hl,viewerModeMsg
ld a,printOkString
call cliKernel
ld b,50
halt
djnz $-1
vmMode ld b,#01
ld a,switchGfxMode
call cliKernel
viewerModeLoop halt
ld a,getKeyWithShift
call cliKernel
cp aCurLeft
jp z,sxgLeftKey
cp aCurRight
jp z,sxgRightKey
cp aCurUp
jp z,sxgUpKey
cp aCurDown
jp z,sxgDownKey
cp aEsc
jp z,viewerModeEnd
jr viewerModeLoop
viewerModeEnd ld a,switchTxtMode
call cliKernel
loadSxgExit ld a,#00
cp #01
ret z
ld a,printRestore
jp cliKernel
;---------------------------------------------
sxgUpKey ld a,moveScreenUp
jr sxgMoveNow
sxgDownKey ld a,moveScreenDown
jr sxgMoveNow
sxgLeftKey ld a,moveScreenLeft
jr sxgMoveNow
sxgRightKey ld a,moveScreenRight
sxgMoveNow push af
ld a,(moveStep)
ex af,af'
pop af
call cliKernel
jp viewerModeLoop
;---------------------------------------------
setVBank ld a,#10 ; #10-#1F - страницы из 2го видео буфера
ex af,af'
ld a,setRamPage0
jp cliKernel
;---------------------------------------------
sxgShowInfo call sxgLoaderVer ; Вывод информации о программе
call sxgLoaderHelp
jp loadSxgExit
sxgLoaderVer ld hl,sxgVersionMsg
ld a,printAppNameString
call cliKernel
ld hl,sxgCopyRMsg
ld a,printCopyrightString
call cliKernel
ld a,#01 ; Просто выйти если файл не задан
ld (sxgFileCheck+1),a
ret
sxgLoaderHelp ld hl,sxgUsageMsg
ld a,printString
call cliKernel
ld a,#01 ; Просто выйти если файл не задан
ld (sxgFileCheck+1),a
ret
;---------------------------------------------
sxgViewerMode ld a,#01 ; Включить режим вьювера после загрузки
ld (setViewerMode+1),a
ld (sxgFileCheck+1),a
xor a ; Обязательно должно быть 0!!!
ret
;---------------------------------------------
fileNotSet ld hl,noFileMsg
ld a,printErrorString
jp cliKernel
;---------------------------------------------
fileNotFound ld a,printFileNotFound
fileNotFound_1 ld hl,#0000
jp cliKernel
;---------------------------------------------
wrongFile ld hl,wrongFileMsg
ld a,printErrorString
call cliKernel
ld a,#ff ; error
ret
;---------------------------------------------
setImageMode ; Неправильный формат -> выход
push af
ex af,af'
sxgType ld b,#01
ld a,setGfxColorMode ; на входе в A = цветовой режим: %00-ZX, %01-16c, %10-256c, %11 - txt
call cliKernel
pop af
ld hl,sxgTypeZXMsg
cp #00
jr z,setImageMode_0
ld hl,sxgType16Msg
cp #01
jr z,setImageMode_0
ld hl,sxgType256Msg
cp #02
jr z,setImageMode_0
ld hl,sxgTypeWrongMsg
call setImageMode_0
jp wrongFile ; Неправильный формат -> выход
setImageMode_0 call sxgPrint
xor a ; ok
ret
;---------------------------------------------
sxgSetSpeed ld a,getNumberFromParams
call cliKernel
cp #ff
jp z,wrongParams
ld a,l
ld (moveStep),a
ld a,#fe ; Пропустить следующее значение
ret
;---------------------------------------------
sxgSetScreen ld a,getNumberFromParams
call cliKernel
cp #ff
jp z,wrongParams
ld a,h
cp #00
jp nz,wrongParams
ld a,l
cp #04
jr c,sxgSetScreen_0
jp wrongParams
sxgSetScreen_0 ld a,l
ld (sxgVMem+1),a
ld (sxgOffX+1),a
ld (sxgOffY+1),a
ld (sxgType+1),a
ld (vmMode+1),a
ld (gPalNum+1),a
push af
sla a
sla a
sla a
sla a
ld (setVBank+1),a
pop af
push hl,de
ld de,sxgScreenMsg0
ld h,#00
ld l,a
ld a,fourbit2str
call cliKernel
pop de,hl
ld a,#fe ; Пропустить следующее значение
ret
;---------------------------------------------
sxgAlignX ld a,#00
cp #00
ret z
ld a,b
cp #00
jr z,sxgAlignX_0
ld a,c
cp #68 ; #0168 = 360
jr c,sxgAlignX_0
push hl,de,bc
ld hl,#0000
jr sxgOffX
sxgAlignX_0 push hl,de,bc
ld hl,360
sbc hl,bc
ld de,2
ld a,divide16_16
call cliKernel ; bc,hl
ld hl,512
sbc hl,bc
sxgOffX ld b,#01
ld a,setScreenOffsetX
call cliKernel
pop bc,de,hl
ret
; ---------------------------------------------
sxgAlignY ld a,#00
cp #00
ret z
ld a,b
cp #00
jr z,sxgAlignY_0
ld a,c
cp #20 ; #0120 = 288
jr c,sxgAlignY_0
push hl,de,bc
ld hl,#0000
jr sxgOffY
sxgAlignY_0 push hl,de,bc
ld hl,288
sbc hl,bc
ld de,2
ld a,divide16_16
call cliKernel ; bc,hl
ld hl,512
sbc hl,bc
sxgOffY ld b,#01
ld a,setScreenOffsetY
call cliKernel
pop bc,de,hl
ret
; ---------------------------------------------
sxgSetAlignX ld a,#01
ld (sxgAlignX+1),a
xor a ; Обязательно должно быть 0!!!
ret
sxgSetAlignY ld a,#01
ld (sxgAlignY+1),a
xor a ; Обязательно должно быть 0!!!
ret
;---------------------------------------------
wrongParams ld hl,wrongParamsMsg
ld a,printErrorString
call cliKernel
ret
;---------------------------------------------
sxgPrint ld a,#00
cp #01
ret z
ld a,printString
jp cliKernel
setSilentMode ld a,#01
ld (sxgPrint+1),a
ld (loadSxgExit+1),a
xor a ; Обязательно должно быть 0!!!
ret
;---------------------------------------------
moveStep db #02 ; скорость перемещение для рещима вьювера в px
imageMode db #00
imageWidth dw #0000
imageHeight dw #0000
countWidth dw #0000
countHeight dw #0000
sxgVersionMsg db "SXG (Spectrum eXtended Graphics) file loader v0.06",#00
sxgCopyRMsg db "2013,2015 ",127," Breeze\\\\Fishbone Crew",#00
sxgUsageMsg db #0d,15,5,"Usage: loadsxg [switches] filename.sxg",#0d
db 16,16," -vm ",15,15,"\tviewer mode. activate viewer mode after image has loaded",#0d
db 16,16," -sp n",15,15,"\tspeed. set move speed in viewer mode (default 2px)",#0d
db 16,16," -g n",15,15,"\tgraphics screen. select screen to load (default 1)",#0d
db 16,16," -v ",15,15,"\tversion. show application's version and copyrights",#0d
db 16,16," -cx ",15,15,"\talign centers vertically (if width less than 360)",#0d
db 16,16," -cy ",15,15,"\talign centers horizontally (if heigth less than 288)",#0d
db 16,16," -s ",15,15,"\tsilent mode. additional information is not displayed",#0d
db 16,16," -h ",15,15,"\thelp. show this info"
db 16,16,#0d,#00
noFileMsg db "Error: Incorrect file name.",#0d,#0d,#00
wrongFileMsg db "Error: Incorrect file format.",#0d,#0d,#00
viewerModeMsg db "Viewer mode. Use ",24,25,26,27," to navigate. Press ",20, " ESC ",20," to exit.",#0d,#0d,#00
wrongParamsMsg db "Error: Wrong parametrs.",#0d,#0d,#00
sxgFormatMsg db " ",249," Image format: SXG detected!",#0d,#00
sxgVerMsg db " ",249," SXG Header Version: ",#00
sxgBgMsg db " ",249," BackGround color: ",#00
sxgPackMsg db " ",249," Pack Type: ",#00
sxgNumberMsg db "--",#0d,#00
sxgTypeMsg db " ",249," Image type: ",#00
sxgTypeZXMsg db "SCR (6912)",#0d,#00
sxgType16Msg db "16 colors",#0d,#00
sxgType256Msg db "256 colors",#0d,#00
sxgTypeWrongMsg db 16,10,"Unknown!",16,16,#0d,#00
sxgWidthMsg db " ",249," Image width: ",#00
sxgWidthMsg0 db "-----px",#0d,#00
sxgHeigthMsg db " ",249," Image heigth: ",#00
sxgHeigthMsg0 db "-----px",#0d,#00
sxgScreenMsg db " ",249," Screen selected: "
sxgScreenMsg0 db "01",#0d,#00
sxgLoadingMsg db #0d,"Loading...",#0d,#00
;---------------------------------------------
; Key's table for params
;---------------------------------------------
keyTable
db "-s" ; s должно быть выше чем sp
db "*"
dw setSilentMode
db "-h"
db "*"
dw sxgShowInfo
db "-v"
db "*"
dw sxgLoaderVer
db "-vm"
db "*"
dw sxgViewerMode
db "-sp"
db "*"
dw sxgSetSpeed
db "-g"
db "*"
dw sxgSetScreen
db "-cx"
db "*"
dw sxgSetAlignX
db "-cy"
db "*"
dw sxgSetAlignY
;--- table end marker ---
db #00
;---------------------------------------------
appEnd nop
org #e000
sxgBuffer nop
SAVEBIN "install/bin/loadsxg", appStart, appEnd-appStart
DISPLAY "loadSxgLoop",/A,loadSxgLoop
;DISPLAY "skipImageDec",/A,skipImageDec
;DISPLAY "skipIncBank",/A,skipIncBank