Add a machine code routine to a Basic program

Basic and Machine Language

Moderator: Moderators

Post Reply
CommodoreGeek
Vic 20 Newbie
Posts: 5
Joined: Sat Nov 05, 2022 8:59 am
Location: UK
Occupation: HR

Add a machine code routine to a Basic program

Post by CommodoreGeek »

Hi, I’m trying to have a go at re-learning some “basic” programming on an original Vic-20. I’ve started on a simple horizontal shoot-em-up and have user-defined graphics set up & I'm able to control the main ship with joystick control. Problem is, getting another object on the screen that moves across the screen horizontally without any interrupts from the joystick controlled character. I know a machine coded routine that stops any interrupt is needed here, but don’t know how to do that. Can I add this into a basic program? As it stands, it’s just too jittery in basic form to feel anything like a game.
Any help would be great. Thanks 😊
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Add a machine code routine to a Basic program

Post by tlr »

Sure, you can do any mix of BASIC + ML. For smooth movement you'll need to do an interrupt routine to perform that in the background. Typically you'd set up a timer to fire an IRQ once each vertical blanking, and there handle the positioning. If you are doing this from BASIC you should consider making that routine having a set of memory locations that tells it what to do and when to stop. That way you can start things by just POKEing the right values when the IRQ routine has been installed.
CommodoreGeek
Vic 20 Newbie
Posts: 5
Joined: Sat Nov 05, 2022 8:59 am
Location: UK
Occupation: HR

Re: Add a machine code routine to a Basic program

Post by CommodoreGeek »

Thanks so much tir, only I realise I know little about how do that.
I’ve got the fire button set up to initiate the bullet using ‘STICK’ with a basic command to send the character horizontally across the screen (position depending) using a For…Next loop & Poke whilst the other character scrolls across the screen using a continuous X=X-1 & Poke loop. There stands the problem. The Fire press stops the other character in motion each time it’s initiated. Can a small machine coded interrupt resolve that & how could that be used to replace this method in a basic program? Thanks again.
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Add a machine code routine to a Basic program

Post by tlr »

The actual implementation will be different depending on how you partition what BASIC does and what the ML interrupt does. In general the interrupt will pause the BASIC program very briefly (~1 ms) each 20 ms to perform some task you desire. This could be doing the equivalent of X=X-1 & POKE, once. The result will be that the character moves a step each 20 ms, regardless of what BASIC is doing. This can be extended to quite a few characters at the same time, you just loop through doing one step for each in the ML interrupt routine. You will probably want to set up the ML routine to stop when reaching the edge of the screen so you don't need to actively end the movement from BASIC.
CommodoreGeek
Vic 20 Newbie
Posts: 5
Joined: Sat Nov 05, 2022 8:59 am
Location: UK
Occupation: HR

Re: Add a machine code routine to a Basic program

Post by CommodoreGeek »

Thanks that makes good sense. I just need to work out how to write the ML element in order to do just that and where to assign it in memory 😳 💭
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Add a machine code routine to a Basic program

Post by tlr »

In its simplest form you can just hook your routine in $0314/$0315 and at the end of your routine just call whatever was in $0314/$0315 before (usually $eabf) to finish up. Without fiddling with the timers this will not be in the vertical blanking but good enough for starting out. You can use the tape buffer $0334-$03ff for your code.

Make sure interrupts are temporarily disabled when setting up $0314/$0315, otherwise an interrupt might occur when only one of the bytes have been written, resulting in a crash.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Add a machine code routine to a Basic program

Post by Mike »

CommodoreGeek wrote:I've got the fire button set up to initiate the bullet using 'STICK' with a BASIC command to send the character horizontally across the screen (position depending) using a FOR .. NEXT loop & POKE whilst the other character scrolls across the screen using a continuous X=X-1 & POKE loop. There stands the problem. The Fire press stops the other character in motion each time it's initiated.
It might be useful at this time to stress out, that neither interrupts nor the use of machine code are strictly necessary to achieve concurrent movement of two or more objects on screen.

Tank-v-UFO, Killer Comet and Rocket Command from the VIC-20 User's Manual already show this feat is possible with pure BASIC code. All it needs is a clever interleaving of the relevant statements so not a single one of them "stops" the main loop of the game. I once wrote an own version of Moon Patrol, which exactly took that step from firing rockets that overtly stopped the rest of the game (and made shooting down the UFOs more akin to a stand-off duel) to rockets that now fly alongside the other animation. BASIC still has its limits though, and trying to move a lot of objects leads to a noticable slowdown.

I packed all the four games I mentioned above into my "Type-In Games Collection", Moon Patrol additionally has an own longer post highlighting its development. You can easily load and list the games as BASIC programs to see how it's done.

Machine code allows for more and possibly also finer (i.e. pixel-wise) movements on screen. Interrupts or timers then allow for controlled timing - say, once per frame or once every several frames. Ultimately there is only one CPU in the VIC-20 and then it is interleaving all relevant code what gives you concurrent movements or other actions. That method applies regardless in which language (or combinations thereof) the game is written.

You also might want to check out my translation of Killer Comet from pure BASIC to machine language, done in VICMON. :)
CommodoreGeek
Vic 20 Newbie
Posts: 5
Joined: Sat Nov 05, 2022 8:59 am
Location: UK
Occupation: HR

Re: Add a machine code routine to a Basic program

Post by CommodoreGeek »

tlr wrote: Mon Sep 18, 2023 8:32 am In its simplest form you can just hook your routine in $0314/$0315 and at the end of your routine just call whatever was in $0314/$0315 before (usually $eabf) to finish up. Without fiddling with the timers this will not be in the vertical blanking but good enough for starting out. You can use the tape buffer $0334-$03ff for your code.

Make sure interrupts are temporarily disabled when setting up $0314/$0315, otherwise an interrupt might occur when only one of the bytes have been written, resulting in a crash.
Thank you. ML is very new to me. I was thinking of a routine (in data format) that I could insert into a basic program for that particular instruction until I can learn programming using assembly. I need to get my head around it though 🤔 👍🏻
CommodoreGeek
Vic 20 Newbie
Posts: 5
Joined: Sat Nov 05, 2022 8:59 am
Location: UK
Occupation: HR

Re: Add a machine code routine to a Basic program

Post by CommodoreGeek »

Mike wrote: Mon Sep 18, 2023 10:34 am
CommodoreGeek wrote:I've got the fire button set up to initiate the bullet using 'STICK' with a BASIC command to send the character horizontally across the screen (position depending) using a FOR .. NEXT loop & POKE whilst the other character scrolls across the screen using a continuous X=X-1 & POKE loop. There stands the problem. The Fire press stops the other character in motion each time it's initiated.
It might be useful at this time to stress out, that neither interrupts nor the use of machine code are strictly necessary to achieve concurrent movement of two or more objects on screen.

Tank-v-UFO, Killer Comet and Rocket Command from the VIC-20 User's Manual already show this feat is possible with pure BASIC code. All it needs is a clever interleaving of the relevant statements so not a single one of them "stops" the main loop of the game. I once wrote an own version of Moon Patrol, which exactly took that step from firing rockets that overtly stopped the rest of the game (and made shooting down the UFOs more akin to a stand-off duel) to rockets that now fly alongside the other animation. BASIC still has its limits though, and trying to move a lot of objects leads to a noticable slowdown.

I packed all the four games I mentioned above into my "Type-In Games Collection", Moon Patrol additionally has an own longer post highlighting its development. You can easily load and list the games as BASIC programs to see how it's done.

Machine code allows for more and possibly also finer (i.e. pixel-wise) movements on screen. Interrupts or timers then allow for controlled timing - say, once per frame or once every several frames. Ultimately there is only one CPU in the VIC-20 and then it is interleaving all relevant code what gives you concurrent movements or other actions. That method applies regardless in which language (or combinations thereof) the game is written.

You also might want to check out my translation of Killer Comet from pure BASIC to machine language, done in VICMON. :)
Thanks Mike, that’s really encouraging! I’ll definitely take a look at your links. I’m getting pretty proficient again at the basic language, I just wanted to improve the mechanics of how alternative programming might work to do the same actions but with better speed & precision. That’s all very helpful. Thanks guys 👍🏻
Post Reply