diff --git a/sdk/include/zxuno.def b/sdk/include/zxuno.def index b8d8908..71fe832 100644 --- a/sdk/include/zxuno.def +++ b/sdk/include/zxuno.def @@ -31,6 +31,7 @@ define dev_control 14 define dev_control2 15 define newreg 16 + define radas_ctrl $40 ; ZX-UNO register to activate Radastan mode define dma_ctrl $a0 ; ZX-UNO register to start/stop DMA define dma_src $a1 ; ZX-UNO register to set DMA source define dma_dst $a2 ; ZX-UNO register to set DMA destination @@ -47,6 +48,7 @@ ; Aliases ZXUNOADDR: equ zxuno_port ZXUNODATA: equ zxuno_data +RADASCTRL: equ radas_ctrl ; MMC/SDC interface: define SPI_PORT $eb diff --git a/software/Makefile b/software/Makefile index 603b388..3df1e9a 100644 --- a/software/Makefile +++ b/software/Makefile @@ -33,7 +33,8 @@ SUBDIRS=\ iwconfig\ joyconf\ keymap\ - loadpzx + loadpzx\ + playrmov .PHONY: all all: build diff --git a/software/playrmov/.gitignore b/software/playrmov/.gitignore new file mode 100644 index 0000000..82e29a6 --- /dev/null +++ b/software/playrmov/.gitignore @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2021 Ivan Tatarinov +# +# SPDX-License-Identifier: CC0-1.0 + +build diff --git a/software/playrmov/Makefile b/software/playrmov/Makefile new file mode 100644 index 0000000..7a52781 --- /dev/null +++ b/software/playrmov/Makefile @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2021 Ivan Tatarinov +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Supported environments: +# * GNU on Linux, FreeBSD etc. +# * GNU on Windows NT (using MinGW/MSYS/Cygwin/WSL) +# +# Build: +# make [ ...] +# Install / Uninstall: +# make [prefix=] install | uninstall +# Clean: +# make clean | distclean +# +# where: +# is one of values for `BINS' variable prefixed with "build/" +# (see target `all' below). +# is a prefix directory to install files into. + +include ../../sdk/common.mk + +srcdir = . +# Use uppercase for FAT filesystem +prefix ?= . +exec_prefix ?= $(prefix) +bindir ?= $(exec_prefix)/BIN + +INSTALL ?= install +INSTALL_PROGRAM ?= $(INSTALL) +RM = rm -f + +INCLUDEDIR = ../../sdk/include +AS = sjasmplus +ifeq ($(USE_SJASMPLUS_VERSION),sjasmplus) +AFLAGS = --nobanner +else ifeq ($(USE_SJASMPLUS_VERSION),z00m128) +AFLAGS = --nologo +else +AFLAGS = +endif +AFLAGS += -I$(INCLUDEDIR) + +BINS=\ + PLAYRMOV + +.PHONY: all +all: $(foreach t,$(BINS),build/$(t)) + +build\ +$(DESTDIR)$(bindir): + mkdir -p $@ + +build/PLAYRMOV: $(srcdir)/playrmov.asm\ + $(INCLUDEDIR)/zxuno.def\ + $(INCLUDEDIR)/esxdos.def\ + $(INCLUDEDIR)/regs.mac\ + | build + $(AS) $(AFLAGS) --raw=$@ $< + +# $1 = target +# No need in execution mode for FAT filesystem +define install_bin_rule = +$$(DESTDIR)$$(bindir)/$1: build/$1 | $$(DESTDIR)$$(bindir) + $$(INSTALL_PROGRAM) -m 644 $$< $$@ +endef + +$(foreach t,$(BINS),$(eval $(call install_bin_rule,$(t)))) + +.PHONY: install +install: $(foreach t,$(BINS),$(DESTDIR)$(bindir)/$(t)) + +.PHONY: uninstall +uninstall: + $(RM) $(foreach t,$(BINS),$(DESTDIR)$(bindir)/$(t)) + +.PHONY: clean +clean: + rm -f $(foreach t,$(BINS),build/$(t)) + +.PHONY: distclean +distclean: + rm -rf build diff --git a/software/playrmov/playrmov.asm b/software/playrmov/playrmov.asm index cc972cc..59488a3 100644 --- a/software/playrmov/playrmov.asm +++ b/software/playrmov/playrmov.asm @@ -1,225 +1,264 @@ -; API de ESXDOS. -include "esxdos.inc" -include "errors.inc" - -; PLAYRMOV : un comando para ESXDOS 0.8.5 que permite reproducir videos en formato -; Radastaniano (ficheros .RDM) usando DIVMMC en el ZX-Uno. - -; Video: secuencia lineal de frames. -; Cada frame: 6144 bytes con el bitmap en el formato radastaniano + -; 16 bytes para la paleta (entradas 0-15) - -; Version 0.2 : arreglado el problema del stack. Gracias a Miguel Ângelo Guerreiro -; Se borra la pantalla al terminar la reproducción -; Version 0.1 : necesita que el stack esté por debajo de 49152 -; (ej. CLEAR 49151 antes de ejecutar el comando) - -;Para ensamblar con PASMO como archivo binario (no TAP) - -BORDERCLR equ 23624 -PAPERCOLOR equ 23693 -ULAPLUSADDR equ 0bf3bh -ULAPLUSDATA equ 0ff3bh -ZXUNOADDR equ 0fc3bh -ZXUNODATA equ 0fd3bh -RADASCTRL equ 40h -BANKM equ 7ffdh -PILA equ 3deah ;valor sugerido por Miguel Ângelo para poner la pila en el área de comando - - org 2000h ;comienzo de la ejecución de los comandos ESXDOS. - -Main proc - ld a,h - or l - jr z,PrintUso ;si no se ha especificado nombre de fichero, imprimir uso - call RecogerNFile - - di - ld (BackupSP),sp - ld sp,PILA - ei - call PlayFichero - call Cls - - ld sp,(BackupSP) - ret - -PrintUso ld hl,Uso -BucPrintMsg ld a,(hl) - or a - ret z - rst 10h - inc hl - jr BucPrintMsg - endp - - -RecogerNFile proc ;HL apunta a los argumentos (nombre del fichero) - ld de,BufferNFich -CheckCaracter ld a,(hl) - or a - jr z,FinRecoger - cp " " - jr z,FinRecoger - cp ":" - jr z,FinRecoger - cp 13 - jr z,FinRecoger - ldi - jr CheckCaracter -FinRecoger xor a - ld (de),a - inc de ;DE queda apuntando al buffer este que se necesita en OPEN, no sé pa qué. - ret - endp - - -PlayFichero proc - xor a - rst 08h - db M_GETSETDRV ;A = unidad actual - ld b,FA_READ ;B = modo de apertura - ld hl,BufferNFich ;HL = Puntero al nombre del fichero (ASCIIZ) - rst 08h - db F_OPEN - ret c ;Volver si hay error - ld (FHandle),a - - call SetupVideoMemory - -BucPlayVideo ld hl,0c000h - ld bc,6144+16 ;Bitmap + paleta - ld a,(FHandle) - rst 08h - db F_READ - jr c,FinPlay ;si error, fin de lectura - ld a,b - or c - jr z,FinPlay ;si no hay más que leer, fin de lectura - - call SwitchScreens - ld bc,7ffeh - in a,(c) ;Detectar si se ha pulsado SPACE - and 1 - jr z,FinPlay - - jr BucPlayVideo - -FinPlay ld a,(FHandle) - rst 08h - db F_CLOSE - - call RestoreVideoMemory - - or a ;Volver sin errores a ESXDOS - ret - endp - - -SetupVideoMemory proc - di - - ld bc,ZXUNOADDR - ld a,RADASCTRL - out (c),a - ld bc,ZXUNODATA - ld a,3 ;modo radastaniano - out (c),a - - ld bc,BANKM - ld a,00010111b ;banco 7, pantalla normal, ROM 3 - ld (Banco),a - out (c),a - ei - ret - endp - - -RestoreVideoMemory proc - di - ld bc,BANKM - ld a,00010000b ;banco 0, pantalla normal, ROM 3 - out (c),a - - ld bc,ZXUNOADDR - ld a,RADASCTRL - out (c),a - ld bc,ZXUNODATA - ld a,0 ;modo ULA normal - out (c),a - - ei - ret - endp - - -SwitchScreens proc - halt - - ld ix,0c000h + 6144 ;apuntamos a donde está la paleta - ld d,0 ;D es el indice a la paleta que se está escribiendo - ld h,0ffh ;H contiene el color más oscuro, para poner en el borde después - ld l,0 ;L contiene el índice al color más oscuro -BucUpdPaleta ld bc,ULAPLUSADDR - out (c),d - ld b,0ffh - ld a,(ix) - out (c),a - ld a,d - cp 8 ;Solo hacemos el test para los indices 0-7 - jr nc,NoTestColorOscuro - ld a,(ix) - cp h - jr nc,NoTestColorOscuro - ld h,a - ld l,d -NoTestColorOscuro inc ix - inc d - ld a,16 - cp d - jr nz,BucUpdPaleta - - ld a,l - out (254),a ;El borde lo más oscuro posible - - ld a,(Banco) - xor 00001010b ;conmutamos de la pantalla normal a la shadow y de la 7 a la 5 - ld (Banco),a - ld bc,BANKM - out (c),a - ret - endp - - -Cls proc - ld a,(BORDERCLR) - sra a - sra a - sra a - and 7 - out (254),a - ld hl,16384 - ld de,16385 - ld bc,6143 - ld (hl),l - ldir - inc hl - inc de - ld bc,767 - ld a,(PAPERCOLOR) - ld (hl),a - ldir - ret - endp - - - ; 01234567890123456789012345678901 -Uso db " playrmov moviefile.rdm",13,13 - db "Plays a video file encoded for",13 - db "the ",34,"Radastan",34," video mode.",13,0 - -FHandle db 0 -Banco db 0 -BackupSP dw 0 - -BufferNFich equ $ ;resto de la RAM para el nombre del fichero \ No newline at end of file +; playrmov - a command for ESXDOS 0.8.5 and above that allows playing videos +; in Radastan format (.RDM files) using DivMMC on the ZX-Uno. +; +; Copyright (C) 2016-2021 Antonio Villena +; Contributors: +; Miguel Ângelo Guerreiro (fixed the stack problem) +; 2021 Ivan Tatarinov +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . +; +; SPDX-FileCopyrightText: Copyright (C) 2016-2021 Antonio Villena +; +; SPDX-FileContributor: Miguel Ângelo Guerreiro +; SPDX-FileContributor: 2021 Ivan Tatarinov +; +; SPDX-License-Identifier: GPL-3.0-only + +; Video: linear sequence of frames. +; Frame: 6144 bytes with the bitmap in Radastan format + +; 16 bytes for the palette (inputs 0-15) + +; output PLAYRMOV + + define PROGRAM "playrmov" + define VERSION "0.2" + define DESCRIPTION "Plays a video file encoded for", 13, "the ", 34, "Radastan", 34, " video mode." + define COPYRIGHT 127, " 2016-2021 Antonio Villena" + define LICENSE "License: GNU GPL 3.0" + + include zxuno.def + include esxdos.def + include regs.mac + +BORDERCLR: equ 23624 +PAPERCOLOR: equ 23693 +ULAPLUSADDR: equ $bf3b +ULAPLUSDATA: equ $ff3b +BANKM: equ $7ffd +PILA: equ $3dea ; value suggested by Miguel Ângelo to + ; put the stack in the command area + + org $2000 ; entry point of ESXDOS program + +;----------------------------------------------------------------------------- +; Subroutine +; In: HL = pointer to the command line arguments string (ASCIIZ) + +Main: ld a, h + or l + jr nz, Init ; If no filename specified, show usage +; jr ShowUsage ; No need, it follows + +;----------------------------------------------------------------------------- +; Subroutine + +ShowUsage: ld hl, aUsage +; jr Print ; No need, it follows + +;----------------------------------------------------------------------------- +; Subroutine +; In: HL = pointer to an ASCIIZ string + +Print: ld a, (hl) + or a + ret z ; Return on string end + rst $10 + inc hl + jr Print + +;----------------------------------------------------------------------------- +; Subroutine +; In: HL = pointer to the command line arguments string (ASCIIZ) + +Init: ld de, FileName +; call GetFileName ; inline + +;----------------------------------------------------------------------------- +; Subroutine +; In: HL = pointer to the command line arguments (filename) +; DE = pointer to the output ASCIIZ string (filename) +; Out: DE = pointer to terminating 0 character of output string + +.GetFileName: ld a, (hl) + or a + jr z, .End + cp " " + jr z, .End + cp ":" + jr z, .End + cp 13 + jr z, .End + ldi + jr .GetFileName +.End: xor a + ld (de), a +; ret ; skipped + +; continue Init() + inc de ; DE remains pointing to the buffer that is + ; needed in OPEN, I don't know what for + di + ld (BackupSP), sp + ld sp, PILA + ei + + call PlayFile + call Cls + + ld sp, (BackupSP) + ret + +;----------------------------------------------------------------------------- +; Subroutine + +PlayFile: xor a + esxdos M_GETSETDRV ; A = current drive + ld b, FA_READ ; B = file open mode + ld hl, FileName ; HL = pointer to file name (ASCIIZ) + esxdos F_OPEN + ret c ; Return on error + ld (FileHandle), a + + call SetupVideoMemory + +.Loop: ld hl, $c000 + ld bc, 6144 + 16 ; Bitmap + palette + ld a, (FileHandle) + esxdos F_READ + jr c, .Stop ; Stop on error + ld a,b + or c + jr z, .Stop ; Stop on end of data + call SwitchScreens + ld bc, $7ffe + in a, (c) ; Detect if SPACE has been pressed + and %00000001 + jr nz, .Loop +.Stop: ld a, (FileHandle) + esxdos F_CLOSE + + call RestoreVideoMemory + + or a ; Return to ESXDOS without errors (CY=0) + ret + +;----------------------------------------------------------------------------- +; Subroutine + +SetupVideoMemory: + di + ld_bc ZXUNOADDR + ld_a RADASCTRL + out (c), a + chg_bc ZXUNODATA + chg_a 3 ; "Radastan" mode + out (c), a + chg_bc BANKM + chg_a %00010111 ; Bank 7, normal display, ROM 3 + ld (Bank), a + out (c), a + ei + ret + +;----------------------------------------------------------------------------- +; Subroutine + +RestoreVideoMemory: + di + ld_bc BANKM + ld_a %00010000 ; Bank 0, normal display, ROM 3 + out (c), a + chg_bc ZXUNOADDR + chg_a RADASCTRL + out (c), a + chg_bc ZXUNODATA + chg_a 0 ; Normal ULA mode + out (c),a + ei + ret + +;----------------------------------------------------------------------------- +; Subroutine + +SwitchScreens: halt + + ld ix, $c000 + 6144 ; IX = pointer to palette + ld d, 0 ; D = index to the palette that is being written + ld h, $ff ; H = darkest color, to put on the edge afterwards + ld l, 0 ; L = index to the darkest color +PaletteUpdate: + ld_bc ULAPLUSADDR + out (c), d + chg_bc ULAPLUSDATA + ld a, (ix) + out (c), a + ld a, d + cp 8 ; Only do the test for indices 0-7 + jr nc, .NoDarkColor + ld a, (ix) + cp h + jr nc, .NoDarkColor + ld h, a + ld l, d +.NoDarkColor: inc ix + inc d + ld a, 16 + cp d + jr nz, PaletteUpdate + + ld a, l ; The edge is as dark as possible + out (254), a ; + + ld a, (Bank) ; Switch from the normal screen to + xor %00001010 ; the shadow screen and from 7 to 5 + ld (Bank), a ; + ld bc, BANKM ; + out (c), a ; + ret + +;----------------------------------------------------------------------------- +; Subroutine + +Cls: ld a, (BORDERCLR) + .3 sra a + and %00000111 + out (254), a + ld hl, ScreenAddr ; L = 0 + ld de, ScreenAddr+1 + ld bc, 6144-1 + ld (hl), l + ldir + inc hl + inc de + ld bc, 768-1 + ld a, (PAPERCOLOR) + ld (hl), a + ldir + ret + +; 01234567890123456789012345678901 +aUsage: db PROGRAM, " version ", VERSION, 13 + db DESCRIPTION, 13 + db COPYRIGHT, 13 + db LICENSE, 13 + db 13 + db "Usage:", 13 + db " .", PROGRAM, " moviefile.rdm", 13, 0 + +FileHandle db 0 +Bank db 0 +BackupSP dw 0 +FileName: ; Rest of RAM for filename +ScreenAddr: equ $4000 diff --git a/software/playrmov/playrmov.changelog b/software/playrmov/playrmov.changelog new file mode 100644 index 0000000..9bb1fe1 --- /dev/null +++ b/software/playrmov/playrmov.changelog @@ -0,0 +1,7 @@ +Version 0.2 + Fixed the stack problem. Thanks to Miguel Ângelo Guerreiro. + Screen clears when playback ends. + +Version 0.1 + Needs the stack to be below 49152. Ex. "CLEAR 49151" before executing the + command.