CPCWiki forum

General Category => Programming => Topic started by: santi.ontanon on 02:24, 29 October 23

Title: saving/loading data to tape in assembler
Post by: santi.ontanon on 02:24, 29 October 23
Hi, 

I wanted to play around with the possibility of saving and loading data to tape for an upcoming game we are working on, and was looking for examples of how have people done this in the past in assembler. I was reading through this page that has awesome info ( https://www.cpcwiki.eu/index.php/Cassette_data_information ), but before I go ahead and reinvent the wheel from that low-level info, I was wondering if there are standard ways to do this.

Thanks!
Title: Re: saving/loading data to tape in assembler
Post by: Jean-Marie on 12:28, 29 October 23
You'd start with :
call &BC65          ;CAS INITIALISE
or 1
call &BC6B          ;CAS NOISY : (don't display any messages)

For reading a "monoblock" data stream :
ld hl,data_offset
ld de,length
ld a,&16
call &BCA1

Same for writing, but use call &BC9E instead.
You can read more info on the firmware calls here :
cpcwiki.eu/imgs/e/e1/The_Amstrad_CPC_Firmware_Guide.txt (https://www.cpcwiki.eu/imgs/e/e1/The_Amstrad_CPC_Firmware_Guide.txt)

Title: Re: saving/loading data to tape in assembler
Post by: santi.ontanon on 12:53, 29 October 23
Cool Thanks! One problem we have is that our game uses pretty much ALL the CPC RAM, so the firmware routines are not there anymore, and we need to do all from scratch. But maybe I could look at a disassembly of the firmware functions you mention and reuse that code? (We are going to have to cut down game content to add this already haha, as we are very tight on RAM ;))
Title: Re: saving/loading data to tape in assembler
Post by: Jean-Marie on 14:40, 29 October 23
Have a look at this thread :
https://www.cpcwiki.eu/forum/index.php?msg=222635
Title: Re: saving/loading data to tape in assembler
Post by: santi.ontanon on 23:18, 29 October 23
Ah, interesting! Good to know I could bring back the firmware at some point! I'd still like to understand how to do it directly though hehe. So, I went ahead and pulled the relevant code from the firmware into a small test program. But I am facing some issues that probably are very simple, haha, but I am a bit new to the CPC (I come from developing on the MSX, and although I am quite familiar with the Z80, the CPC hardware, firmware, emulators, etc. are all new to me). My problem now is that I do not even know how to test it:
- I build my assembler file and packaged it into a cdt file using the 2cdt util. 
- I can load it fine in an emulator (I am using RVM2.0), and I was able to set breakpoints to see that my code actually loaded and was executing.
- But when it comes to now testing how to write to the tape, when I pressed the "red" button in the amstrad tape player in the emulator to start recording to tape RVM2.0 told me my tape was "write protected", and I do not see any option in the 2cdt tool to make it not write protected (I also do not know how to create a blank/empty cdt file haha, so, I was just trying to write at the end of my current cdt file).

Any hints appreciated! I understand this is all very basic stuff haha, but I am just starting to learn the CPC side of things, so, thanks in advance for any help! :)
Title: Re: saving/loading data to tape in assembler
Post by: Jean-Marie on 00:39, 30 October 23
If I recall correctly, you need to press the PAUSE button on the tape-deck of RVM : this will display a menu to create a CDT file, and protect/unprotect it. That's not very intuitive, and that's why I don't really like RVM. I'd recommend using WinAPE which has a good old-fashioned menu, a built-in assembler and a tremendous debugger mimicking OllyDBG32 for PC/Intel.
Hey, what kind of game are you working on? I'm curious  ;D
Title: Re: saving/loading data to tape in assembler
Post by: santi.ontanon on 01:11, 30 October 23
Oh my god, that's right! Found it!! Thanks a lot!!! Alright, I can now debug (and it didn't work, haha, but it'd have been a miracle if the code worked first try haha ;) ). But this is great! Now I have all I need to keep working on it. Thanks again!

Ah, we are continuing work on a point-and-click engine we started a while ago (we released a demo a couple of years ago: https://www.youtube.com/watch?v=vnNZu5topag ), and now we want to add the ability to save/load game to tape, so, I started investigating!
Title: Re: saving/loading data to tape in assembler
Post by: Jean-Marie on 01:45, 30 October 23
Oh yes, I remember it ! Congrats :D  I love those escape games, and played a lot of them when Adobe Flash was still alive, on Escapegames24.
If you were to target DSK rather than CDT, there is a tool to program the Disc controller directly, in order to write/read the sectors without using the firmware :  FDC Tools V1.1 (cpcwiki.eu) (https://www.cpcwiki.eu/forum/programming/fdc-tools-v1-1/msg188532/#msg188532)
 And if you're short of memory, you can compress/decompress your data (and even your code) using ZX0 (https://github.com/einar-saukas/ZX0).
Title: Re: saving/loading data to tape in assembler
Post by: santi.ontanon on 12:23, 30 October 23
Oh, thanks a lot for the pointer to FDC tools, I was not aware of that, and might be useful (we would like to have both a tape and a disc version, but I was working on the tape version first). Cool!!

And indeed, we make extensive use of zx0 already, as we are trying to cram as much content as we can for the next demo we want to release. Hopefully soon! :D
Title: Re: saving/loading data to tape in assembler
Post by: z80_1327 on 19:35, 15 November 23
        org &4000

        ; READ TAPE FUNCTION
        ; size bytes to read tape
        csz     equ 16384  ; size image
        mt      equ 13     ; width of square wave

start:
        ; disable for read stability
        di

        ; tape on
        ld      bc,#F610
        out     (c),c

        ; destiny data
        ld      hl,#C000

        ; puerto PPI B bit 7 data tape
        ld      b,#F5

check:
        ; long mesure for check mt
        ld      de,113
bu1:
        call    pGET
        cp      mt
        jp      c,check
        dec     de
        ld      a,d
        or      e
        jp      nz,bu1

check2:
        ld      de,113
bu2:
        call    pGET
        cp      mt
        jp      nc,check2
        dec     de
        ld      a,d
        or      e
        jp      nz,bu2


        ; *** here read data ***
        ld      de,csz
bu0:
        call    pGETbyte

        ld      (hl),a
        inc     hl
        dec     de
        ld      a,d
        or      e
        jp      nz,bu0

        ; tape off
        ld      bc,&f600
        out     (c),c
        ei


pGETbyte:
        exx
        ld      e,1
        ld      bc,#F500
nByte:  call    pGET
cTime:  cp      mt           ; measured time
        ccf
        rl      e
        jp      nc,nByte
        ld      a,e
        exx
        ret  
        ;                               __
        ; get pulse iterations pos neg    __
pGET:
        ld      c,0
pPOS:
        in      a,(c)
        jp      m,pPOS
pNEG:
        inc     c
        in      a,(c)
        jp      p,pNEG
        ld      a,c
        ret                           
       
Powered by SMFPacks Menu Editor Mod