Saturday, July 15, 2017

New CSpect ZX Spectrum Next emulator

UPDATE:  I've now added register setting, and memory window set/moving. You can also set breakpoints from the input line, and push/pop values.

I've been working away on a new debugger for my CSpect emulator, and it's now ready to use, so here it is along with my assembler (SNasm) and a sample showing how to use it all. Please read the readme and be aware it may go pop at any time. Aside from that -have fun!!

Download: CSpect Emulator



Thursday, July 13, 2017

Z8410 DMA chip for the ZX Spectrum Next

So the ZX Spectrum Next team have added a Z80 DMA chip, the Z8410  chip to be more precise. This was popular add on in Europe ( more info here: http://velesoft.speccy.cz/data-gear.htm ), and has some very cool advantages for future games, especially because it's now a standard part. However information on it is a little thin on the ground, so after some major googling, I've found the info on them.

The DMA port can be 11 or 107, and it can transfer around 865k per second
From the web page above: Max. speed of data transfer on ZX128+ is...

17.3 kB(17727 bytes) / frame = 865.6 kB(886350 bytes) / second.

Or.... 1 byte every 4 T-States.

Now here is the really cool bit, because it's tied to the clock speed, when you speed up the NEXT (as it can go 7Mhz, 14Mhz and 28Mhz), the DMA will also speed up!  This is amazing, as it means you'll be able to transfer 1.73Mb/s, 3.46Mb/s, and an astounding 6.92Mb/s!  At 28Mhz you won't be using Layer 2, and that means you could copy the original Layer 1 screen in just 13.5 scanlines, which is incredible.

The registers are below, and here is the Datasheet



Saturday, July 01, 2017

esxDOS File access

So I was about to start adding some very basic "simulation" support for files into my emulator, and I'd lost track of the API details as they were listed on Facebook. Facebook isn't a great place to have technical discussions as you can't search later to find the stuff you need!

Fortunately I had it saved off, so before I (and everyone else) loses it, I thought I'd put it up here. I'll do a little ASM lib with all this later.
I'll also extend this if/when I discover more commands, as there appears to be very little info about the esxDOS API

;
; NOTE: File paths use the slash character (‘/’) as directory separator (UNIX style)
;

M_GETSETDRV  equ $89
F_OPEN       equ $9a
F_CLOSE      equ $9b
F_READ       equ $9d
F_WRITE      equ $9e
F_SEEK       equ $9f
F_GET_DIR    equ $a8
F_SET_DIR    equ $a9

FA_READ      equ $01
FA_APPEND    equ $06
FA_OVERWRITE equ $0C

; Function: Detect if unit is ready
; Out:      A = default drive (required for all file access)
;           Carry flag will be set if error.
GetSetDrive:
             xor  a               ; A=0, get the default drive
             rst  $08
             db   M_GETSETDRV             
             ld   (DefaultDrive),a
             ret
DefaultDrive db   0



; Function:  Open file
; In:        IX = filename
;            B  = open mode
;            A  = Drive
; Out:       A  = file handle
;            On error: Carry set
;                      A = 5   File not found
;                      A = 7   Name error - not 8.3?
;                      A = 11  Drive not found
;                      
fOpen:
             ld   a, (DefaultDrive)  ; get drive we're on
             ld   b, FA_READ         ; b = open mode
             ld   ix,FileName        ; ix = Pointer to file name (ASCIIZ)
             rst  $08
             db   F_OPEN             ; open read mode
             ret                     ; Returns a file handler in 'A' register.



; Function:  Read bytes from a file
; In:        A  = file handle
;            ix = address to load into
;            bc = number of bytes to read
; Out:       Carry flag is set if read fails.
fRead:
             ld   ix, 16384          ; ix = address where to store what is read
             ld   bc, 6912           ; bc = bytes to read
             ld   a, filehandle      ; a  = the file handler
             rst  $08
             db   F_READ             ; read file
             ret


; Function:  Write bytes to a file
; In:        A  = file handle
;            ix = address to save from 
;            bc = number of bytes to write
; Out:       Carry flag is set if write fails.
fWrite:
             ld   ix, 16384          ; ix = memory address to save from
             ld   bc, 6912           ; bc = bytes to write
             ld   a, handle          ; a  = file handler
             rst  $08
             db   F_WRITE            ; write file
             ret


; Function:  Write bytes to a file
; In:        A  = file handle
; Out:       Carry flag active if error when closing
fClose: 
             ld   a, handle           ; a  = file handler
             rst  $08
             db   F_CLOSE
             ret



; Function:  Seek into file
; In:        A    = file handle
;            L    = mode:  0 - from start of file
;                          1 - forward from current position
;                          2 - back from current position
;            BCDE = bytes to seek
; Out:       BCDE = Current file pointer. (*does not return this yet)
;            
fSeek:   
             ld   a,handle           ; file handle
             or   a                  ; is it zero?
             ret  z                  ; if so return
             ld   l,0
             ld   bc,0
             ld   de,0
             rst  $08           
             db   F_SEEK
             ret



; Function:  SetDirectory
; In:        A    = Drive
;            HL   = pointer to zero terminated path string ("path",0)
; Out:       carry set if error
;            
SetDir:
             ld   a,(DefaultDrive)   ; drive to change directory on
             ld   hl,Path            ; point to "path",0 to set
             rst  $08           
             db   F_SET_DIR  
             ret



; Function:  Get Directory
; In:        A    = Drive
;            HL   = pointer to where to STORE zero terminated path string
; Out:       carry set if error
;            
GetDir:     
             ld   a,(DefaultDrive)   ; drive to get current directory from
             ld   hl,Path            ; location to store path string in
             rst  $08           
             db   F_GET_DIR  
             ret