New MEGA CHASE game for CPC+. Problems with ABASC compiler

Hi! As I already commented in a previous post, I’m developing my first game for Amstrad computers (for the CPC Plus series, specifically, as it uses the 4096 color palette and hardware sprites).

I’ve finished the Basic version (which can be downloaded here), and its works well (although slowly), but I’m having lots of problems trying to compile the file “game.bas” with ABASC. Among other things, the compiled file does not show the custom chars, and it seems to completely ignore the ASIC (no sprites, no enhanced images, no fades); the music algo gets partially corrupted, and the computer hangs when finishing a game. I don’t know if I’m doing something wrong or it’s due to the intrinsic limitqations of ABASC. Any help will be much appreciated.

4 Likes

Sounds interesting! Can’t check right now, so - any screens or vid?

It may well be limitations of ABASC. Certainly if you’re accessing ASIC registers then the memory map of compiled code starts to become very important - you’ll run in to all sorts of problems if accessing the ASIC pages out running code etc.

I didn’t know if images could be attached to a post, when I realized that is as simple as dropping them!


It’s a very simple game, made basically to learn Locomotive Basic and how to use some of the advanced functions of the ASIC.

5 Likes

Thanks, I’ll try to contact Fragarco, the creator of ABASC, to ask whether he can throw some light at this.

This looks really lovely in its simplicity​:slightly_smiling_face:

(You can also copy/paste images)

3 Likes

Thanks for the video, although the loader should show the custom chars (at least it does so in WinApe). I’m having lots of trouble trying to compile it with ABASC. The interpreted version is just too slow…

1 Like

Looks really nice :smiling_face_with_sunglasses:

Interested to know what are the major bottlenecks in the interpreted version?

Well, it’s just that in general the game should run faster and more fluidly. Color fades (both the title screen and the sprites when doing a “warp”) seem to be particularly slow. In all other versions (VIC-20, Plus/4, MSX2+, C64…) I achieved 50 FPS after compiling, and in Amiga and Atari ST compilation isn’t even necessary.

I experimented a bit more on how to access the Plus ASIC from BASIC. I created three small routines to stop color flashing, write a value to the ASIC and read a value back. These routines can be anywhere in memory, but not in the ASIC page between &4000 and &7FFF. If you use these routines, there will be no problems with interrupts or BASIC code overlapping the ASIC page.

Here is a small program to demonstrate this. Maybe this solution will reduce the incompatibilities with the BASIC compiler. I did not provide RSX commands to reduce the size of the DATA block.

MODE 2

100 MODE 0 : DEFINT a-z : memBase=&A600 : MEMORY memBase-1
110 ' === Unlock ASIC.
120 DATA &FF,&00,&FF,&77,&B3,&51,&A8,&D4,&62,&39,&9C,&46,&2B,&15,&8A,&CD,&EE
130 FOR i=1 TO 17 : READ a : OUT &BC00,a : NEXT
140 ' === Install assembler routines.
150 DATA &CF,&55,&8D,&F3,&DD,&66,&03,&DD,&6E,&02,&01,&B8,&7F,&ED,&49,&73
160 DATA &0E,&A0,&ED,&49,&FB,&C9,&F3,&DD,&66,&03,&DD,&6E,&02,&01,&B8,&7F
170 DATA &ED,&49,&7E,&0E,&A0,&ED,&49,&12,&FB,&C9
180 FOR i=0 TO 41 : READ a : POKE memBase+i,a : NEXT
190 stopFlashing = memBase+0 : asicPoke = memBase+3 : asicPeek = memBase+22
200 ' === Redefine colors.
210 CALL stopFlashing
220 FOR i=0 TO 15
230   r=i : g=i : b=i
240   CALL asicPoke,&6400+i*2,b+16*r : CALL asicPoke,&6401+i*2,g
250 NEXT
260 ' === Draw color gradient and print color values.
270 FOR x = 0 TO 639 STEP 2 : MOVE x,0 : DRAW x,399,x\40 : NEXT
280 FOR i=0 TO 15
290   a%=0 : CALL asicPeek,&6400+i*2,@a% : CALL asicPeek,&6400+i*2+1,@a%+1
300   LOCATE 1,i+1 : PEN 15 : PRINT HEX$(a%)
310 NEXT
320 ' ==== End (MODE resets colors and restarts flashing).
330 CALL &BB18 : MODE 2

' ORG #A600
'
' stop_flashing:
'     RST #0008 : DEFW #8D55        ;; LO_JUMP #0D55
'
' asic_poke: PRINT $-#A600
'    DI                             ;; Disable interrupts.
'        LD H,(IX+3) : LD L,(IX+2)  ;; Get first parameter with address.
'        LD BC,#7FB8 : OUT (C),C    ;; Blend in ASIC page.
'            LD (HL),E              ;; Store second parameter value at address.
'        LD C,#A0 : OUT (C),C       ;; Blend out ASIC page.
'    EI : RET                       ;; Enable interrupts and return to BASIC.
'
' asic_peek: PRINT $-#A600
'     DI                            ;; Disable interrupts.
'         LD H,(IX+3) : LD L,(IX+2) ;; Get first parameter with address.
'         LD BC,#7FB8 : OUT (C),C   ;; Blend in ASIC page.
'             LD A,(HL)             ;; Load value from address.
'         LD C,#A0 : OUT (C),C      ;; Blend out ASIC page.
'         LD (DE),A                 ;; Store value at second parameter.
'     EI : RET                      ;; Enable interrupts and return to BASIC.
3 Likes

@lightforce6128 I tried your code in ABASC, and it compiled and worked!

However, I had to modify the assembly routines a little because it looks like you are expecting the last parameter passed to the CALL to be not only on the stack (available at IX+0 and IX+1), but also loaded into register DE. However, the compiler does not follow that convention, and parameters are available only on the stack through IX.

After that, I started looking more carefully at @shad0wfax’s code and discovered that the music engine he is using (a binary loaded into memory) is also relying on the same trick and assuming that DE contains the value of the last parameter. I guess this was one of the main reasons why the code wasn’t working as expected when compiled.

Now that I’ve seen this behaviour in two different places, I’m wondering whether this is actually a hack or something that was officially documented. I can’t find any reference to it in the books I own, so maybe you can shed some light on the topic (no pun intended).

Anyway, I think I’ll try to use all of this to build a library for ABASC, so that it makes working with the ASIC easier.

1 Like

I had a look in a ROM listing (“ROM-Listing CPC 464/664/6128” from German publisher “Markt & Technik Verlag”, 1985). Using an RSX command is more or less the same as using CALL. The former only has to look up which address is stored for the RSX command name. As soon as the address is known, both use the same code to read in additional parameters and to execute the routine. If there is an additional parameter, a helper routine is called to extract it and return it in register DE. Because there could be more than one parameter, the found parameters are stored on the stack with register IX used as base pointer. But the last read parameter also remains in register DE. Between extracting the last parameter and executing the routine, register DE is not changed. This is why it is stored in DE and in (IX).

464 664 6128/Plus description
F1A0 F24A F245 RSX command
F1BA F261 F25C CALL command
CE91 CEF8 CEF5 get an integer

Answering the question, if this behavior is only a side effect or should be considered being a part of the official interface is difficult / a bit philosophical. But it seems there is a difference between the original firmware routine and the code compiled by ABASC.

1 Like

After some time working on it, I have added a library to ABASC to access the CPC+ features. As an example, I rewrote the original MCHASE game. Many thanks to @shad0wfax, who sent me the original code and allowed me to work on it.

Attached you can find the final result and the current source code. I used Locomotive BASIC 2 Plus syntax, as it makes it easier to work with complex projects.

main.bas (30,2 KB)

mchase.dsk (190,3 KB)

Edit: I forgot to mention that player 1 now uses keys (Q, A, O, P) while player 2 uses joystick 1.

1 Like

I really like this as a simple, quick arcade game!

Could I be annoying and ask if you could update it to read the 2 joypads for GX4000 so I could play it 2 players with my wife? It’s easy to convert to cart as long as it only uses the joypad commands.

@slider271 here you are (I hope). Now the second joystick can be used instead of keys.

@Gryzor the feature of running the CPC 6128 emulator inside the forum is really nice! Is there any way to select a CPC+ as the machine to emulate?

mchase.dsk (190,3 KB)

1 Like

No unfortunately RVM Player doesn’t support it (yet)…

1 Like