mirror of https://github.com/zxdos/zxuno.git
Merge pull request #103 from ivan-tat/master
utils: added `dmaplayw` utility
This commit is contained in:
commit
9f9327bee2
|
|
@ -1,8 +1,11 @@
|
|||
; esxdos.def
|
||||
;
|
||||
; SPDX-FileCopyrightText: Copyright (C) 2019, 2021 Antonio Villena
|
||||
; SPDX-FileCopyrightText: Copyright (C) 2017 AZXUNO association
|
||||
;
|
||||
; SPDX-License-Identifier: GPL-3.0-only
|
||||
; SPDX-FileContributor: Copyright (C) 2019, 2021 Antonio Villena
|
||||
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
|
||||
;
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
; Compatible compilers:
|
||||
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
|
||||
|
|
@ -10,19 +13,88 @@
|
|||
ifndef esxdos_def_included
|
||||
define esxdos_def_included
|
||||
|
||||
define FA_READ 0x01
|
||||
define FA_WRITE 0x02
|
||||
define FA_OPEN_AL 0x08
|
||||
define M_GETSETDRV 0x89
|
||||
define F_OPEN 0x9a
|
||||
define F_CLOSE 0x9b
|
||||
define F_READ 0x9d
|
||||
define F_WRITE 0x9e
|
||||
define F_FSTAT 0xa1
|
||||
define HOOK_BASE 128
|
||||
define MISC_BASE HOOK_BASE+8
|
||||
define FSYS_BASE MISC_BASE+16
|
||||
|
||||
macro esxdos dato
|
||||
rst $08
|
||||
defb dato
|
||||
endm
|
||||
define DISK_STATUS HOOK_BASE+0 ; hookcodes for block devices
|
||||
define DISK_READ HOOK_BASE+1
|
||||
define DISK_WRITE HOOK_BASE+2
|
||||
define DISK_IOCTL HOOK_BASE+3
|
||||
define DISK_INFO HOOK_BASE+4
|
||||
|
||||
define M_DOSVERSION MISC_BASE+0
|
||||
define M_GETSETDRV MISC_BASE+1
|
||||
define M_DRIVEINFO MISC_BASE+2
|
||||
define M_TAPEIN MISC_BASE+3
|
||||
define M_TAPEOUT MISC_BASE+4
|
||||
define M_GETHANDLE MISC_BASE+5
|
||||
define M_GETDATE MISC_BASE+6
|
||||
|
||||
define F_MOUNT FSYS_BASE+0
|
||||
define F_UMOUNT FSYS_BASE+1
|
||||
define F_OPEN FSYS_BASE+2
|
||||
define F_CLOSE FSYS_BASE+3
|
||||
define F_SYNC FSYS_BASE+4
|
||||
define F_READ FSYS_BASE+5
|
||||
define F_WRITE FSYS_BASE+6
|
||||
define F_SEEK FSYS_BASE+7
|
||||
define F_FGETPOS FSYS_BASE+8
|
||||
define F_FSTAT FSYS_BASE+9
|
||||
define F_FTRUNCATE FSYS_BASE+10
|
||||
define F_OPENDIR FSYS_BASE+11
|
||||
define F_READDIR FSYS_BASE+12
|
||||
define F_TELLDIR FSYS_BASE+13
|
||||
define F_SEEKDIR FSYS_BASE+14
|
||||
define F_REWINDDIR FSYS_BASE+15
|
||||
define F_GETCWD FSYS_BASE+16
|
||||
define F_CHDIR FSYS_BASE+17
|
||||
define F_MKDIR FSYS_BASE+18
|
||||
define F_RMDIR FSYS_BASE+19
|
||||
define F_STAT FSYS_BASE+20
|
||||
define F_UNLINK FSYS_BASE+21
|
||||
define F_TRUNCATE FSYS_BASE+22
|
||||
define F_CHMOD FSYS_BASE+23
|
||||
define F_RENAME FSYS_BASE+24
|
||||
define F_GETFREE FSYS_BASE+25
|
||||
|
||||
define FA_READ %00000001 ; Read access
|
||||
define FA_WRITE %00000010 ; Write access
|
||||
define FA_OPEN_EX %00000000 ; Open if exists, else error
|
||||
define FA_OPEN_AL %00001000 ; Open if exists, if not create
|
||||
define FA_CREATE_NEW %00000100 ; Create if not exists, if exists error
|
||||
define FA_CREATE_AL %00001100 ; Create if not exists, else open and truncate
|
||||
define FA_USE_HEADER %01000000 ; Use +3DOS header (passed in DE)
|
||||
|
||||
; Errors:
|
||||
define EOK 1
|
||||
define ENONSENSE 2
|
||||
define ESTEND 3
|
||||
define EWRTYPE 4
|
||||
define ENOENT 5 ; No such file or directory
|
||||
define EIO 6 ; I/O error
|
||||
define EINVAL 7 ; Invalid file name
|
||||
define EACCES 8 ; Access Denied
|
||||
define ENOSPC 9 ; No space left on device
|
||||
define ENXIO 10 ; Request beyond the limits of the device
|
||||
define ENODRV 11 ; No such drive
|
||||
define ENFILE 12 ; Too many files open in system
|
||||
define EBADF 13 ; Bad file descriptor
|
||||
define ENODEV 14 ; No such device
|
||||
define EOVERFLOW 15
|
||||
define EISDIR 16
|
||||
define ENOTDIR 17
|
||||
define EEXIST 18
|
||||
define EPATH 19 ; Invalid path
|
||||
define ENOSYS 20
|
||||
define ENAMETOOLONG 21
|
||||
define ENOCMD 22
|
||||
define EINUSE 23
|
||||
define ERDONLY 24
|
||||
|
||||
macro esxdos func
|
||||
rst $08
|
||||
db func
|
||||
endm
|
||||
|
||||
endif ; !esxdos_def_included
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
;
|
||||
; SPDX-FileCopyrightText: Copyright (C) 2019, 2021 Antonio Villena
|
||||
;
|
||||
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
|
||||
;
|
||||
; SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
; Compatible compilers:
|
||||
|
|
@ -10,38 +12,55 @@
|
|||
ifndef zxuno_def_included
|
||||
define zxuno_def_included
|
||||
|
||||
define zxuno_port $fc3b
|
||||
define zxuno_data $fd3b
|
||||
define master_conf 0
|
||||
define master_mapper 1
|
||||
define flash_spi 2
|
||||
define flash_cs 3
|
||||
define scan_code 4
|
||||
define key_stat 5
|
||||
define joy_conf 6
|
||||
define key_map 7
|
||||
define nmi_event 8
|
||||
define mouse_data 9
|
||||
define mouse_status 10
|
||||
define scandbl_ctrl 11
|
||||
define raster_line 12
|
||||
define raster_ctrl 13
|
||||
define dev_control 14
|
||||
define core_addr $fc
|
||||
define core_boot $fd
|
||||
define cold_boot $fe
|
||||
define core_id $ff
|
||||
define zxuno_port $fc3b ; ZX-UNO ZXI register address
|
||||
define zxuno_data $fd3b ; ZX-UNO ZXI register data
|
||||
define master_conf 0
|
||||
define master_mapper 1
|
||||
define flash_spi 2
|
||||
define flash_cs 3
|
||||
define scan_code 4
|
||||
define key_stat 5
|
||||
define joy_conf 6
|
||||
define key_map 7
|
||||
define nmi_event 8
|
||||
define mouse_data 9
|
||||
define mouse_status 10
|
||||
define scandbl_ctrl 11
|
||||
define raster_line 12
|
||||
define raster_ctrl 13
|
||||
define dev_control 14
|
||||
define dev_control2 15
|
||||
define newreg 16
|
||||
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
|
||||
define dma_pre $a3 ; ZX-UNO register to set DMA prescaler
|
||||
define dma_len $a4 ; ZX-UNO register to set DMA length
|
||||
define dma_prob $a5
|
||||
define dma_stat $a6
|
||||
define ad724 $fb
|
||||
define core_addr $fc
|
||||
define core_boot $fd
|
||||
define cold_boot $fe
|
||||
define core_id $ff
|
||||
|
||||
define SPI_PORT $eb
|
||||
define OUT_PORT $e7
|
||||
define MMC_0 $fe ; D0 LOW = SLOT0 active
|
||||
define CMD0 $40
|
||||
define CMD1 $41
|
||||
define CMD8 $48
|
||||
define SET_BLOCKLEN $50
|
||||
define READ_SINGLE $51
|
||||
define CMD41 $69
|
||||
define CMD55 $77
|
||||
define CMD58 $7a
|
||||
; MMC/SDC interface:
|
||||
define SPI_PORT $eb
|
||||
define OUT_PORT $e7
|
||||
define MMC_0 $fe ; D0 LOW = SLOT0 active
|
||||
|
||||
; MMC/SDC commands:
|
||||
define CMD0 $40+0 ; GO_IDLE_STATE
|
||||
define CMD1 $40+1 ; SEND_OP_COND (MMC)
|
||||
define CMD8 $40+8 ; SEND_IF_COND
|
||||
define SET_BLOCKLEN $40+16
|
||||
define READ_SINGLE $40+17 ; READ_SINGLE_BLOCK
|
||||
define WRITE_BLOCK $40+24
|
||||
define CMD41 $40+41 ; SD_SEND_OP_COND (SDC)
|
||||
define CMD55 $40+55 ; APP_CMD
|
||||
define CMD58 $40+58 ; READ_OCR
|
||||
|
||||
; SpecDrum interface:
|
||||
define specdrum_port $ffdf ; Specdrum I/O port in 16-bit format for DMA destination
|
||||
|
||||
endif ; !zxuno_def_included
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ BINS=\
|
|||
BACKUP\
|
||||
CORCLEAN\
|
||||
COREBIOS\
|
||||
DMAPLAYW\
|
||||
ROMSBACK\
|
||||
ROMSUPGR\
|
||||
UPGR16M\
|
||||
|
|
@ -133,6 +134,12 @@ build/COREBIOS: $(srcdir)/corebios.asm\
|
|||
| build
|
||||
$(AS) $(AFLAGS) --raw=$@ $<
|
||||
|
||||
build/DMAPLAYW: $(srcdir)/dmaplayw.asm\
|
||||
$(INCLUDEDIR)/zxuno.def\
|
||||
$(INCLUDEDIR)/esxdos.def\
|
||||
| build
|
||||
$(AS) $(AFLAGS) --raw=$@ $<
|
||||
|
||||
build/ROMSBACK: $(srcdir)/romsback.asm\
|
||||
$(INCLUDEDIR)/zxuno.def\
|
||||
$(INCLUDEDIR)/esxdos.def\
|
||||
|
|
|
|||
|
|
@ -0,0 +1,334 @@
|
|||
; dmaplayw.asm - play an audio file using the SpecDrum and DMA at 15.625 kHz.
|
||||
;
|
||||
; Copyright (C) 2017 AZXUNO association
|
||||
; 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, 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 <https://www.gnu.org/licenses/>.
|
||||
;
|
||||
; SPDX-FileCopyrightText: Copyright (C) 2017 AZXUNO association
|
||||
;
|
||||
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
|
||||
;
|
||||
; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
; Compatible compilers:
|
||||
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
|
||||
|
||||
; output DMAPLAYW
|
||||
|
||||
define PROGRAM "dmaplayw"
|
||||
define VERSION "0.1"
|
||||
|
||||
include "zxuno.def"
|
||||
include "esxdos.def"
|
||||
|
||||
define CPU_FREQ 3500000
|
||||
define SPECDRUM_FREQ 15625
|
||||
|
||||
; Prescaler for timed DMA. The count goes from 0 to 223, that is, 224 cycles
|
||||
define DMA_PRESCALER CPU_FREQ / SPECDRUM_FREQ - 1
|
||||
|
||||
org $2000 ; entry point of ESXDOS program
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Subroutine
|
||||
; In: HL = pointer to the command line arguments string (ASCIIZ)
|
||||
|
||||
Main ld a, h
|
||||
or l
|
||||
jp nz, Init
|
||||
ld hl, aUsage
|
||||
.PrintLoop ld a, (hl)
|
||||
or a
|
||||
ret z ; Return on string end
|
||||
rst $10
|
||||
inc hl
|
||||
jr .PrintLoop
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Subroutine
|
||||
; In: HL = pointer to the command line arguments (filename)
|
||||
|
||||
GetFileName ld de, BufferFileName
|
||||
.CheckCharacter ld a, (hl)
|
||||
or a
|
||||
jr z, .End
|
||||
cp " "
|
||||
jr z, .End
|
||||
cp ":"
|
||||
jr z, .End
|
||||
cp 13
|
||||
jr z, .End
|
||||
ldi
|
||||
jr .CheckCharacter
|
||||
.End xor a
|
||||
ld (de), a
|
||||
inc de ; DE remains pointing to the buffer that is needed in OPEN, I don't know what for
|
||||
ret
|
||||
|
||||
; 01234567890123456789012345678901
|
||||
aUsage db " .", PROGRAM, " audiofile.wav", 13
|
||||
db 13
|
||||
db "Plays an audio file using the", 13
|
||||
db "SpecDrum and DMA at 15.625 kHz", 13, 0
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Subroutine
|
||||
; In: HL = pointer to the command line arguments string (ASCIIZ)
|
||||
|
||||
Init call GetFileName ; results DE = buffer for OPEN
|
||||
xor a
|
||||
esxdos M_GETSETDRV ; A = current unit
|
||||
ld b, FA_READ ; B = opening mode
|
||||
ld hl, BufferFileName ; HL = pointer to file name (ASCIIZ)
|
||||
esxdos F_OPEN
|
||||
ret c ; Return on error
|
||||
ld (FHandle), a
|
||||
ld l, 0 ; SEEK_START
|
||||
ld bc, 0
|
||||
ld de, 44 ; Skip 44 bytes from start (WAV header)
|
||||
esxdos F_SEEK
|
||||
ret c ; Return on error
|
||||
ld hl, ScreenAddr
|
||||
ld de, ScreenAddr+1
|
||||
ld bc, 31
|
||||
ld (hl), 255
|
||||
ldir ; This line will be deleted on the first wave plot
|
||||
|
||||
ld hl, DMABuffer
|
||||
ld de, DMABuffer+1
|
||||
ld bc, DMABuffer_Len-1
|
||||
ld (hl), 0
|
||||
ldir ; Clear DMA buffer
|
||||
|
||||
; Prepare to play
|
||||
di
|
||||
ld hl, DMABuffer
|
||||
ld bc, zxuno_port
|
||||
ld a, dma_src
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_dst
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld hl, specdrum_port
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_pre
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld hl, DMA_PRESCALER
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_len
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld hl, DMABuffer_Len
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_prob
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld hl, DMABuffer
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_ctrl
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld a, %00000111 ; Mem to I/O, redisparable, timed, source address is checked
|
||||
out (c), a
|
||||
dec b ; BC = zxuno_port
|
||||
.PlayLoop ld bc, $7ffe ; SPACE halfrow
|
||||
in a, (c)
|
||||
and %00000001
|
||||
jp z, .ExitPlay
|
||||
ld bc, zxuno_port
|
||||
ld a, dma_stat
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
.StillInSecondHalf
|
||||
in a, (c)
|
||||
bit 7, a
|
||||
jr z, .StillInSecondHalf
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_prob
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld hl, DMABuffer + DMABuffer_Len/2
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_stat
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
in a, (c)
|
||||
|
||||
; Fill second half of buffer with audio data
|
||||
ld hl, DMABuffer + DMABuffer_Len/2
|
||||
ld bc, DMABuffer_Len/2
|
||||
ld a, (FHandle)
|
||||
esxdos F_READ
|
||||
jp c, .ExitPlay ; End read on error
|
||||
ld a, b
|
||||
or c
|
||||
jp z, .ExitPlay ; End read on end of data
|
||||
|
||||
ld hl, DMABuffer + DMABuffer_Len/2
|
||||
call PlotWave
|
||||
|
||||
ld bc, zxuno_port
|
||||
ld a, dma_stat
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
.StillInFirstHalf
|
||||
in a, (c)
|
||||
bit 7, a
|
||||
jr z, .StillInFirstHalf
|
||||
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_prob
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
ld hl, DMABuffer
|
||||
out (c), l
|
||||
out (c), h
|
||||
dec b ; BC = zxuno_port
|
||||
ld a, dma_stat
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
in a, (c)
|
||||
|
||||
; Fill first half of buffer with audio data
|
||||
ld hl, DMABuffer
|
||||
ld bc, DMABuffer_Len/2
|
||||
ld a, (FHandle)
|
||||
esxdos F_READ
|
||||
jp c, .ExitPlay ; End read on error
|
||||
ld a, b
|
||||
or c
|
||||
jp z, .ExitPlay ; End read on end of data
|
||||
|
||||
ld hl, DMABuffer
|
||||
call PlotWave
|
||||
|
||||
jp .PlayLoop
|
||||
|
||||
.ExitPlay ld bc, zxuno_port
|
||||
ld a, dma_ctrl
|
||||
out (c), a
|
||||
inc b ; BC = zxuno_data
|
||||
xor a
|
||||
out (c), a
|
||||
dec b ; BC = zxuno_port
|
||||
|
||||
ld a, (FHandle)
|
||||
esxdos F_CLOSE
|
||||
|
||||
or a ; Clear carry flag
|
||||
ei
|
||||
ret
|
||||
|
||||
FHandle db 0
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Subroutine
|
||||
|
||||
PlotWave ld de, BufferCleared
|
||||
ld c, 0
|
||||
.Loop ld a, (de)
|
||||
ld b, a
|
||||
call Plot
|
||||
ld a, (hl)
|
||||
srl a
|
||||
add a, 24
|
||||
ld b, a
|
||||
call Plot
|
||||
ld a, b
|
||||
ld (de), a
|
||||
inc hl
|
||||
inc de
|
||||
inc c
|
||||
jp nz, .Loop
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Subroutine
|
||||
; In: B = y
|
||||
; C = x
|
||||
|
||||
Plot push bc
|
||||
push de
|
||||
push hl
|
||||
ld e, b
|
||||
ld d, 0 ; DE = y
|
||||
sla e
|
||||
rl d ; DE = DE*2
|
||||
ld hl, DirScan
|
||||
add hl, de ; HL = pointer to the address of the first pixel of Y
|
||||
ld e, (hl)
|
||||
inc hl
|
||||
ld d, (hl)
|
||||
ex de, hl ; HL = dir first pixel row Y
|
||||
ld d, c ; save X coordinate in D
|
||||
ld a, c
|
||||
.3 srl a
|
||||
ld c, a
|
||||
ld b, 0
|
||||
add hl, bc ; HL contains the address to paint the pixel
|
||||
ld a, d ; restore X coordinate
|
||||
and %00000111
|
||||
ld de, DirBits
|
||||
add a, e
|
||||
ld e, a
|
||||
ld a, d
|
||||
adc a, 0
|
||||
ld d, a
|
||||
ld a, (de)
|
||||
xor (hl)
|
||||
ld (hl), a
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
DirBits
|
||||
i = %10000000
|
||||
while i > 0
|
||||
db i
|
||||
i = i / 2
|
||||
endw
|
||||
|
||||
DirScan
|
||||
y = 0
|
||||
while y < 192
|
||||
dw ScreenAddr + (256 * (y & 7)) + (32 * ((y / 8) & 7)) + (64 * 32 * (y / 64))
|
||||
y = y + 1
|
||||
endw
|
||||
|
||||
BufferCleared ds 256
|
||||
|
||||
BufferFileName: equ $ ; Rest of RAM for filename
|
||||
|
||||
ScreenAddr: equ $4000
|
||||
|
||||
DMABuffer: equ $8000 ; DMA buffer start address (circular play buffer)
|
||||
DMABuffer_Len: equ 2048 ; DMA buffer length
|
||||
Loading…
Reference in New Issue