Merge pull request #110 from ivan-tat/master

software/playzxm: added `Makefile`
This commit is contained in:
Ivan Tatarinov 2021-06-13 14:12:34 +03:00 committed by GitHub
commit 4a944cf74b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 848 additions and 307 deletions

35
sdk/include/filezxm.def Normal file
View File

@ -0,0 +1,35 @@
; filezxm.def - definitions for ZXM file.
;
; Video: header + linear sequence of frames.
;
; Each frame:
; Black and white: 6144 bytes in Spectrum display format.
; If a pixel bit is set to 1 it is displayed as black, blank otherwise.
; Color: 256 bytes of padding + 6912 bytes in Spectrum display format.
; Note:
; Each frame is padded to occupy an integer number of sectors.
; The fill value is whatever you want, it is ignored.
;
; SPDX-FileCopyrightText: Copyright (C) 2016-2021 Antonio Villena
;
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
;
; SPDX-License-Identifier: GPL-3.0-only
; Compatible compilers:
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
ifndef filezxm_def_included
define filezxm_def_included
struct file_zxm_header_t ; 256 bytes
a_magic ds 3 ; "ZXM"
a_reserved_0 ds 13 ; Unused
w_total_frames ds 2 ; Total number of video frames
b_sectors_per_frame ds 1 ; Number of sectors (512 bytes) that
; each frame occupies (12 for BW, 14
; for color)
a_reserved_1 ds 237 ; Unused
ends
endif ; !filezxm_def_included

View File

@ -10,67 +10,438 @@
ifndef regs_mac_included
define regs_mac_included
; Load (initialize) A register
; A register -----------------------------------------------------------------
; Undefine a value in A register
macro undef_a
___a=-1
endm
; Assume a value in A register
macro assume_a value
___a=value & $ff
endm
; Load a value into A register
macro ld_a value
if 0 = value
xor a ; 1 byte
if 0 = (value & $ff)
xor a ; 1 byte
else
ld a, value ; 2 bytes
ld a, value ; 2 bytes
endif
___a=value
assume_a value
endm
; Change A register
; Change a value in A register
macro chg_a value
if ___a != value
if ___a < 0
ld_a value ; A == ?
elseif ___a != (value & $ff)
if 0 = (value & $ff)
xor a ; 1 byte
xor a ; 1 byte
elseif ((___a + 1) & $ff) = (value & $ff)
inc a ; 1 byte
inc a ; 1 byte
elseif ((___a - 1) & $ff) = (value & $ff)
dec a ; 1 byte
dec a ; 1 byte
elseif ((___a & $7f) << 1) = (value & $ff)
add a, a ; 1 byte
elseif (((___a & $7f) << 1) + ((___a & $80) >> 7)) = (value & $ff)
rlca ; 1 byte
rlca ; 1 byte
elseif (((___a & $fe) >> 1) + ((___a & $01) << 7)) = (value & $ff)
rrca ; 1 byte
rrca ; 1 byte
elseif ((___a ^ $ff) & $ff) = (value & $ff)
cpl ; 1 byte
cpl ; 1 byte
else
ld a, value & $ff ; 2 bytes
ld a, value ; 2 bytes
endif
___a=value
assume_a value
endif
endm
; Load (initialize) BC register
macro ld_bc value
ld bc, value
___bc=value
; B register -----------------------------------------------------------------
; Undefine a value in B register
macro undef_b
___b=-1
endm
; Change BC register
macro chg_bc value
if (___bc & $ffff) != (value & $ffff)
if (___bc & $ff) = (value & $ff)
if (((___bc >> 8) + 1) & $ff) = ((value >> 8) & $ff)
inc b
elseif (((___bc >> 8) - 1) & $ff) = ((value >> 8) & $ff)
dec b
else
ld b, value >> 8
endif
elseif ((___bc >> 8) & $ff) = ((value >> 8) & $ff)
if (((___bc & $ff) + 1) & $ff) = (value & $ff)
inc c
elseif (((___bc & $ff) - 1) & $ff) = (value & $ff)
dec c
else
ld c, value & $ff
endif
; Assume a value in B register
macro assume_b value
___b=value & $ff
endm
; Load a value into B register
macro ld_b value
ld b, value
assume_b value
endm
; Change a value in B register
macro chg_b value
if ___b < 0
ld_b value ; B == ?
elseif ___b != (value & $ff)
if ((___b + 1) & $ff) = (value & $ff)
inc b ; 1 byte
elseif ((___b - 1) & $ff) = (value & $ff)
dec b ; 1 byte
else
ld bc, value
ld b, value ; 2 bytes
endif
assume_b value
endif
endm
; C register -----------------------------------------------------------------
; Undefine a value in C register
macro undef_c
___c=-1
endm
; Assume a value in C register
macro assume_c value
___c=value & $ff
endm
; Load a value into C register
macro ld_c value
ld c, value
assume_c value
endm
; Change a value in C register
macro chg_c value
if ___c < 0
ld_c value ; C == ?
elseif ___c != (value & $ff)
if ((___c + 1) & $ff) = (value & $ff)
inc c ; 1 byte
elseif ((___c - 1) & $ff) = (value & $ff)
dec c ; 1 byte
else
ld c, value ; 2 bytes
endif
assume_c value
endif
endm
; BC register ----------------------------------------------------------------
; Undefine a value in BC register
macro undef_bc
___b=-1
___c=-1
endm
; Assume a value in BC register
macro assume_bc value
___b=(value >> 8) & $ff
___c=value & $ff
endm
; Load a value into BC register
macro ld_bc value
ld bc, value
assume_bc value
endm
; Change a value in BC register
macro chg_bc value
if ___b < 0
if ___c = (value & $ff)
ld_b value >> 8 ; B == ?, C == LSB
else
ld_bc value ; B == ?, C != LSB || C == ?
endif
elseif ___c < 0
if ___b = ((value >> 8) & $ff)
ld_c value & $ff ; B == MSB, C == ?
else
ld_bc value ; B != MSB || B == ?, C == ?
endif
else
___bc=(___b << 8) + ___c
if ___bc != (value & $ffff)
if ___c = (value & $ff)
if ((___b + 1) & $ff) = ((value >> 8) & $ff)
inc b ; 1 byte
elseif ((___b - 1) & $ff) = ((value >> 8) & $ff)
dec b ; 1 byte
else
ld b, value >> 8 ; 2 bytes
endif
elseif ___b = ((value >> 8) & $ff)
if ((___c + 1) & $ff) = (value & $ff)
inc c ; 1 byte
elseif ((___c - 1) & $ff) = (value & $ff)
dec c ; 1 byte
else
ld c, value & $ff ; 2 bytes
endif
else
ld bc, value
endif
assume_bc value
endif
endif
endm
; D register -----------------------------------------------------------------
; Undefine a value in D register
macro undef_d
___d=-1
endm
; Assume a value in D register
macro assume_d value
___d=value & $ff
endm
; Load a value into D register
macro ld_d value
ld d, value
assume_d value
endm
; Change a value in D register
macro chg_d value
if ___d < 0
ld_d value ; D == ?
elseif ___d != (value & $ff)
if ((___d + 1) & $ff) = (value & $ff)
inc d ; 1 byte
elseif ((___d - 1) & $ff) = (value & $ff)
dec d ; 1 byte
else
ld d, value ; 2 bytes
endif
assume_d value
endif
endm
; E register -----------------------------------------------------------------
; Undefine a value in E register
macro undef_e
___e=-1
endm
; Assume a value in E register
macro assume_e value
___e=value & $ff
endm
; Load a value into E register
macro ld_e value
ld e, value
assume_e value
endm
; Change a value in E register
macro chg_e value
if ___e < 0
ld_e value ; E == ?
elseif ___e != (value & $ff)
if ((___e + 1) & $ff) = (value & $ff)
inc e ; 1 byte
elseif ((___e - 1) & $ff) = (value & $ff)
dec e ; 1 byte
else
ld e, value ; 2 bytes
endif
assume_e value
endif
endm
; DE register ----------------------------------------------------------------
; Undefine a value in DE register
macro undef_de
___d=-1
___e=-1
endm
; Assume a value in DE register
macro assume_de value
___d=(value >> 8) & $ff
___e=value & $ff
endm
; Load a value into DE register
macro ld_de value
ld de, value
assume_de value
endm
; Change a value in DE register
macro chg_de value
if ___d < 0
if ___e = (value & $ff)
ld_d value >> 8 ; D == ?, E == LSB
else
ld_de value ; D == ?, E != LSB || E == ?
endif
elseif ___e < 0
if ___d = ((value >> 8) & $ff)
ld_e value & $ff ; D == MSB, E == ?
else
ld_de value ; D != MSB || D == ?, E == ?
endif
else
___de=(___d << 8) + ___e
if ___de != (value & $ffff)
if ___e = (value & $ff)
if ((___d + 1) & $ff) = ((value >> 8) & $ff)
inc d ; 1 byte
elseif ((___d - 1) & $ff) = ((value >> 8) & $ff)
dec d ; 1 byte
else
ld d, value >> 8 ; 2 bytes
endif
elseif ___d = ((value >> 8) & $ff)
if ((___e + 1) & $ff) = (value & $ff)
inc e ; 1 byte
elseif ((___e - 1) & $ff) = (value & $ff)
dec e ; 1 byte
else
ld e, value & $ff ; 2 bytes
endif
else
ld de, value
endif
assume_de value
endif
endif
endm
; H register -----------------------------------------------------------------
; Undefine a value in H register
macro undef_h
___h=-1
endm
; Assume a value in H register
macro assume_h value
___h=value & $ff
endm
; Load a value into H register
macro ld_h value
ld h, value
assume_h value
endm
; Change a value in H register
macro chg_h value
if ___h < 0
ld_h value ; H == ?
elseif ___h != (value & $ff)
if ((___h + 1) & $ff) = (value & $ff)
inc h ; 1 byte
elseif ((___h - 1) & $ff) = (value & $ff)
dec h ; 1 byte
else
ld h, value ; 2 bytes
endif
assume_h value
endif
endm
; L register -----------------------------------------------------------------
; Undefine a value in L register
macro undef_l
___l=-1
endm
; Assume a value in L register
macro assume_l value
___l=value & $ff
endm
; Load a value into L register
macro ld_l value
ld l, value
assume_l value
endm
; Change a value in L register
macro chg_l value
if ___l < 0
ld_l value ; L == ?
elseif ___l != (value & $ff)
if ((___l + 1) & $ff) = (value & $ff)
inc l ; 1 byte
elseif ((___l - 1) & $ff) = (value & $ff)
dec l ; 1 byte
else
ld l, value ; 2 bytes
endif
assume_l value
endif
endm
; HL register ----------------------------------------------------------------
; Undefine a value in HL register
macro undef_hl
___h=-1
___l=-1
endm
; Assume a value in HL register
macro assume_hl value
___h=(value >> 8) & $ff
___l=value & $ff
endm
; Load a value into HL register
macro ld_hl value
ld hl, value
assume_hl value
endm
; Change a value in HL register
macro chg_hl value
if ___h < 0
if ___l = (value & $ff)
ld_h value >> 8 ; H == ?, L == LSB
else
ld_hl value ; H == ?, L != LSB || L == ?
endif
elseif ___l < 0
if ___h = ((value >> 8) & $ff)
ld_l value & $ff ; H == MSB, L == ?
else
ld_hl value ; H != MSB || H == ?, L == ?
endif
else
___hl=(___h << 8) + ___l
if ___hl != (value & $ffff)
if ___l = (value & $ff)
if ((___h + 1) & $ff) = ((value >> 8) & $ff)
inc h ; 1 byte
elseif ((___h - 1) & $ff) = ((value >> 8) & $ff)
dec h ; 1 byte
else
ld h, (value >> 8) $ ff ; 2 bytes
endif
elseif ___h = ((value >> 8) & $ff)
if ((___l + 1) & $ff) = (value & $ff)
inc l ; 1 byte
elseif ((___l - 1) & $ff) = (value & $ff)
dec l ; 1 byte
else
ld l, value & $ff ; 2 bytes
endif
else
ld hl, value
endif
assume_hl value
endif
___bc=value
endif
endm

View File

@ -34,7 +34,8 @@ SUBDIRS=\
joyconf\
keymap\
loadpzx\
playrmov
playrmov\
playzxm
.PHONY: all
all: build

5
software/playzxm/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
#
# SPDX-License-Identifier: CC0-1.0
build

84
software/playzxm/Makefile Normal file
View File

@ -0,0 +1,84 @@
# SPDX-FileCopyrightText: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
#
# 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 [<TARGET> ...]
# Install / Uninstall:
# make [prefix=<PREFIX>] install | uninstall
# Clean:
# make clean | distclean
#
# where:
# <TARGET> is one of values for `BINS' variable prefixed with "build/"
# (see target `all' below).
# <PREFIX> 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=\
PLAYZXM
.PHONY: all
all: $(foreach t,$(BINS),build/$(t))
build\
$(DESTDIR)$(bindir):
mkdir -p $@
build/PLAYZXM: $(srcdir)/playzxm.asm\
$(INCLUDEDIR)/zxuno.def\
$(INCLUDEDIR)/esxdos.def\
$(INCLUDEDIR)/regs.mac\
$(INCLUDEDIR)/filezxm.def\
| 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

View File

@ -1,266 +1,311 @@
; API de ESXDOS.
include "esxdos.inc"
include "errors.inc"
; PLAYZXM : un comando para ESXDOS 0.8.5 que permite reproducir videos en formato
; ZXM en blanco y negro y color.
; Video: cabecera + secuencia lineal de frames.
; Cabecera (256 bytes):
; Offset Contenido
; 0 'Z'
; 1 'X'
; 2 'M'
; 16-17 Numero de frames que tiene el video (no usado en esta rutina)
; 18 Numero de sectores (de 512 bytes) que ocupa cada frame: 12 para BW, 14 para color
; Resto de posiciones: reservado
; Cada frame: en blanco y negro, 6144 bytes en formato pantalla de Spectrum. Un pixel a 1 se muestra en negro. A 0, en blanco.
; en color, 256 bytes de relleno + 6912 bytes en formato pantalla de Spectrum
; NOTA: el relleno es simplemente para que cada frame ocupe un número entero de sectores. El relleno se pone a 0
; o a lo que se quiera, ya que no se hace nada con él.
;Para ensamblar con PASMO como archivo binario (no TAP)
BORDERCLR equ 23624
PAPERCOLOR equ 23693
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
push af
call Cls
pop af
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
call ReadHeader
jr c,FinPlay
BucPlayVideo ld hl,(StartScreen)
ld bc,(LFrame)
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
ReadHeader proc
ld a,(FHandle)
ld bc,256
ld hl,32768
rst 08h
db F_READ
ret c
ld hl,32768
ld a,'Z'
cpi
jr nz,NoZXM
ld a,'X'
cpi
jr nz,NoZXM
ld a,'M'
cpi
jr nz,NoZXM
ld hl,32768+18
ld a,(hl)
add a,a
ld b,a
ld c,0
ld (LFrame),bc
ld bc,49152 ;Principio buffer pantalla para BW
ld (StartScreen),bc
ld a,(hl)
cp 12 ;B/W ?
jr z,ZXMOk
ld bc,49152-256 ;Principio buffer pantalla para color
ld (StartScreen),bc
ZXMOk or a
ret
NoZXM scf
ret
endp
SetupVideoMemory proc
di
ld bc,BANKM
ld a,00010111b ;banco 7, pantalla normal, ROM 3
ld (Banco),a
out (c),a
ld hl,0c000h + 6144
ld de,04000h + 6144
ld bc,768
SetAttr ld a,64+56
ld (hl),a
ld (de),a
inc hl
inc de
dec bc
ld a,b
or c
jr nz,SetAttr
xor a
ld bc,0fc3bh
out (c),a
inc b
in a,(c)
ld (BackupConfig),a
or 20h
out (c),a
xor a
out (254),a
ei
ret
endp
RestoreVideoMemory proc
di
xor a
ld bc,0fc3bh
out (c),a
inc b
ld a,(BackupConfig)
out (c),a
ld bc,BANKM
ld a,00010000b ;banco 0, pantalla normal, ROM 3
out (c),a
ei
ret
endp
SwitchScreens proc
halt
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 " playzxm moviefile.zxm",13,13
db "Plays a video file encoded in",13
db "ZXM (colour/BW) format.",13,0
FHandle db 0
Banco db 0
BackupSP dw 0
BackupConfig db 0
StartScreen dw 0
LFrame dw 0
BufferNFich equ $ ;resto de la RAM para el nombre del fichero
; playzxm - a command for ESXDOS 0.8.5 that allows to play videos in ZXM
; format in Black&White and Color.
;
; Copyright (C) 2016-2021 Antonio Villena
; Contributors:
; 2021 Ivan Tatarinov <ivan-tat@ya.ru>
;
; 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, version 3.
;
; 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 <https://www.gnu.org/licenses/>.
;
; SPDX-FileCopyrightText: Copyright (C) 2016-2021 Antonio Villena
;
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
;
; SPDX-License-Identifier: GPL-3.0-only
; Compatible compilers:
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
define PROGRAM "playzxm"
define VERSION "0.1"
define DESCRIPTION "Plays a video file encoded in", 13, "ZXM (colour/BW) format."
define COPYRIGHT 127, " 2016-2021 Antonio Villena"
define LICENSE "License: GNU GPL 3.0"
include "zxuno.def"
include "esxdos.def"
include "regs.mac"
include "filezxm.def"
BORDERCLR: equ 23624
PAPERCOLOR: equ 23693
BANKM: equ $7ffd
STACK_TOP: equ $3dea ; Value suggested by Miguel Ângelo to
; put the stack in the command area
ScreenAddr: equ $4000
FileBuffer: equ $8000
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
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, STACK_TOP
ei
call PlayFile
push af
call Cls
pop af
ld sp, (BackupSP)
ret
;-----------------------------------------------------------------------------
; Subroutine
PlayFile: ld_a 0
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
call ReadHeader
jr c, .Stop ; Stop on error
.Loop: ld hl, (StartScreen)
ld bc, (FrameLength)
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 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
ReadHeader: ld a, (FileHandle)
ld bc, file_zxm_header_t
ld hl, FileBuffer
esxdos F_READ
ret c ; Return on error
ld hl, FileBuffer + file_zxm_header_t.a_magic
ld a, 'Z'
cpi
jr nz, BadFormat
ld a, 'X'
cpi
jr nz, BadFormat
ld a, 'M'
cpi
jr nz, BadFormat
assume_hl FileBuffer + file_zxm_header_t.a_reserved_0
chg_hl FileBuffer + file_zxm_header_t.b_sectors_per_frame
ld a, (hl)
add a, a ; BC = b_sectors_per_frame * 512
ld b, a ;
undef_b ;
ld_c 0 ;
ld (FrameLength), bc
chg_bc $c000 ; Screen buffer for BW
ld (StartScreen), bc
ld a, (hl) ; A = b_sectors_per_frame
cp 12 ; B/W ?
jr z, ReadOK
chg_bc $c000 - 256 ; Screen buffer for color
ld (StartScreen), bc
ReadOK: or a ; Success
ret
BadFormat: scf ; Error
ret
;-----------------------------------------------------------------------------
; Subroutine
SetupVideoMemory:
di
ld_bc BANKM
ld_a %00010111 ; Bank 7, normal display, ROM 3
ld (Bank), a
out (c), a
ld hl, $c000 + 6144
ld de, ScreenAddr + 6144
chg_bc 768
.Loop: ld a, 64+56
ld (hl), a
ld (de), a
inc hl
inc de
dec bc
ld a, b
or c
jr nz, .Loop
assume_a 0
assume_bc 0
chg_bc zxuno_port
chg_a 0
out (c), a
chg_bc zxuno_data
in a, (c)
undef_a
ld (BackupConfig), a
or %00100000
out (c), a
chg_a 0
out (254), a
ei
ret
;-----------------------------------------------------------------------------
; Subroutine
RestoreVideoMemory:
di
ld_bc zxuno_port
ld_a 0
out (c), a
chg_bc zxuno_data
ld a, (BackupConfig)
undef_a
out (c), a
chg_bc BANKM
chg_a %00010000 ; Bank 0, normal display, ROM 3
out (c), a
ei
ret
;-----------------------------------------------------------------------------
; Subroutine
SwitchScreens:
halt
ld a, (Bank)
xor %00001010 ; Switch from the normal screen to the
ld (Bank), a ; shadow screen and from 7 to 5
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
assume_bc 0
inc hl
inc de
chg_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.zxm", 13, 0
FileHandle: db 0
Bank: db 0
BackupSP: dw 0
BackupConfig: db 0
StartScreen: dw 0
FrameLength: dw 0
FileName: ; Rest of RAM for filename