A$$emble IT - Programming tutorial

Chapter 6: SPLITTING BITMAP PICTURE DATA, MULTIPLE INTERRUPTS, It's DEMO MAKING TIME

This chapter teaches you how to use more than one interrupt, display pictures, scroll a text message, and also program your own demos.

Splitting bitmaps

People have been asking me if it is possible to display images, which are relocated into different positions. The answer simply is 'Yes'. It is possible to display picture images set in different locations. First of all, what we need to do is plan where to position the pictures. Say you wanted to use the normal bank area which C64 has on normal reset (BANK $03), we can use $0800-$4000 for the memory of the bitmap. The screen can be positioned elsewhere, and the colour. That's right, we can split images and place them into different areas.

How can splitting images be done? Well, it can easily be done. All you need to do is memorise where the image position is. For example 'Vidcom Painter' images' datas are stored in the following default areas:

$5800-$5BE8 - Colour RAM
$5C00-$5FE8 - Screen RAM
$6000-$7F40 - Bitmap

This should be easy to memorise. 'Vidcom' format is the usual format I use for pictures, and split the images into different locations.

The following listing below shows how to display a picture which is split into different memory locations. We are going to read the following into the following memory locations:

Bitmap will be loaded at $2000-$3F40
Screen RAM will be loaded at $4000
Colour RAM will be loaded at $4400

Hopefully you'll be able to understand the code below. If not, I'll explain after the listing. Before we do, he're how you can split your normal VIDCOM images using a M/C monitor like Action Replay or CODE SUCK Monitor/Padua. This is how we do it ;o)

.T 6000 7F40 2000 (Bitmap)
.T 5C00 5FE8 4000 (Screen Data)
.T 5800 5BE8 4400 (Colour Data)

The Listing

* = $0900
SEI
LDA #BORDER COLOR VALUE (Set as 0 - 15 according to colour)
STA $D020
STA $D021
LDA #$18
STA $D018 ;Charset location where Bitmap is
STA $D016 ;Enable char/bitmap multicolour
LDA #$3B
STA $D011
LDX #$00
DISP LDA $4000,X
STA $0400,X
LDA $4100,X
STA $0500,X
LDA $4200,X
STA $0600,X
LDA $42E8,X
STA $06E8,X
LDA $4400,X
STA $D800,X
LDA $4500,X
STA $D900,X
LDA $4600,X
STA $DA00,X
LDA $46E8,X
STA $DAE8,X
INX
BNE DISP
HOLD JMP HOLD

This listing is longer than displaying Vidcom pictures in normal positions, but this routine can be very useful for those who need to know how to display pictures in different locations ;)

Looking at the listing above we set the border/background colours to the colour we want. Next we set $D011 into BITMAP DISPLAY mode. LDA #$18 in $D018 reads ALL the BITMAP DATA into the CHARSET memory and we also use LDA #$18 to tune screen multicolour on, when $D016 is being read. Next we call a control loop, which will read the SCREEN DATA $4000-$43E8 into SCREEN RAM ($0400-$07E8) in bank #$03. We also read the COLOUR DATA $4400-$47E8 into the COLOUR RAM ($D800-$DBE8). We read all these datas 256 times so we can get a full picture. And that's how to display your split picture.

Using more than one IRQ interrupt

People always think to themselves "Ah, so you can only use one IRQ. That is too simple". There are C64 programmers, who like to code more than just one simple IRQ. Why is this you may ask? Well, as you can see. Using only one IRQ is simple enough, and you can only do real simple, but quite unstable things with only one IRQ call. But with more than one IRQ, you can use more rasters,  than with only one IRQ. Not only this. You can also make your program a bit more stable.

You may have remembered a simple IRQ which was done earlier on in the program. Well, now we are going to show you how to do something a bit more advanced. The routine, you're about to see is an example of using more than IRQ. We are going to show you how to create a 3 colour splits using more than one IRQ.

Little example:

;ASSEMBLE IT - USING MULTIPLE
;IRQS TO DISPLAY 3 COLOUR BARS

         * = $0810
         SEI

;1. CLEAR THE WHOLE SCREEN

         LDX #$00
CLEAR    LDA #$20
         STA $0400,X
         STA $0500,X
         STA $0600,X
         STA $06E8,X
         INX
         BNE CLEAR

;2. INITIALIZE INTERRUPT

        LDA #$01
        STA $D01A
        LDA #<IRQ1
        STA $0314
        LDA #>IRQ1
        STA $0315
        LDA #$7F
        STA $DC0D
        STA $DD0D
        LDA #$1B
        STA $D011
        CLI
HOLD    JMP HOLD

;3. INTERRUPTS

IRQ1    INC $D019
        LDA #$00
        STA $D012
        LDA #$06
        STA $D021
        STA $D020
        LDA #<IRQ2
        STA $0314
        LDA #>IRQ2
        STA $0315
        PLA
        TAY
        PLA
        TAX
        PLA
        RTI
       
IRQ2    INC $D019
        LDA #$80
        STA $D012
        LDA #$02
        STA $D021
        STA $D020
        LDA #<IRQ3
        STA $0314
        LDA #>IRQ3
        STA $0315
        PLA
        TAY
        PLA
        TAX
        PLA
        RTI
       
IRQ3    INC $D019
        LDA #$C2
        STA $D012
        LDA #$01
        STA $D021
        STA $D020
        LDA #<IRQ1
        STA $0314
        LDA #>IRQ1
        STA $0315
        PLA
        TAY
        PLA
        TAX
        PLA
        RTI

RESULT:


Now what does this meaty piece of code do then? Well, step by step, here we go. First we clear the screen with the spacebar charset (LDA #$20, STA $0400,x) but do we really need to tell you about this bit by any chance? No of course not. The next thing we do is initialize the IRQ routine (The same way as we have done in an earlier chapter). To engage the IRQ, we set the co-ordinates to IRQ1, which will then run.

However in label IRQ1, you may have noticed that we call for the next IRQ routine, which are (surprise surprise) a couple of bytes at label IRQ2 to $0314 & $0315. Now why have we done, this? Well, basically it is simple. What happens is that we make the second raster interrupt.

In the second IRQ split, we call another two bytes at IRQ3 to display the third split. And to finish it all, we call IRQ1's two bytes to continuously loop our IRQ so that we have 3 splits displayed on screen (red, white, and blue).

There is something which you would need to be aware of when using multiple interrupts. Not only can you display your splits simply, but you can use more and more interrupts. If however you do (IRQ4, etc) remember to call the two bytes to the very first interrupt (IRQ1) at $0314 & $0315 else the routine will just not work correctly.

Although you can use quite a lot of interrupts at one time, remember to not go overboard, especially when it comes to making loads of rasters. Although this kind of routine can save raster time. We don't want you to use it up too much like, else your programs will have a slow-down syndrome.

Building a simple 1x2 scrolling text - with a twist

Here is how to code your very own simple 1x2 intro. You should already be familiar with the things this program does. For example how to position text, roll the colours and flash them. The new thing you will learn in this section is how to work a scrolltext, control its speed and also putting the scrolltext inside a raster split (screen cut). After you have played around a lot with the code, why not try and make an intro yourself.

The intro screen isn't much, but here is what it will consist of. Firstly we will clear the whole screen using a control loop, rather than using JSR $E544, we shall also fill two portions of the screen with #$00 for the character code, so that we have some vertical lines; where the colours will pass through. We'll also be flashing the two 1-liner (2-liner text more like) and also add a flashing raster bar (using splits). There's also going to be a 1x2 scrolltext and also some music playing in the background :o))

Before we start, I would like to show you how a 1x2 charset works. A 1x1 charset is 16x16 pixels long. These are formed, somehow like the diagram below

Example of a 1x1 character (We use rvs on as the char pixel)

As you can see, a 1x1 character works on 8 pixels across to 8 pixels down, but a 1x2 char is different. We use more than 8 pixels down. In fact, we use twice as many pixels, therefore we calculate the area for the 1x2 charset. Considering that the y-axis for a 1x1 charset is half the size of a 1x2 charset, we multiply the y-axis of the 1x1 charset by 2 so, what does 8x2 make? 16 of course. Here's the example below.

Example of a 1x2 character (using rvs on as char pixel).

Also, looking at the 1x2 character, when you try to display the character, you will notice that there are two halves of the charset which has to be used. Therefore, if you wanted to display a 1x2 charset you read the line of text from memory twice and paste to the two lines in the screen RAM. However, if you used this method:

LDX #$00
LOOP LDA MESSAGE,X
STA (Screenlocation),x
STA (Screenlocation on next line),x
INX
CPX #$(How many characters)
BNE LOOP

This will not work properly, because you are only trying to display a 1x1 charset instead. The proper way is by placing ORA #$40 (or depending on where to put the other half of the character set). You need to place ORA #$40 between after the screen location on first line. Just like the example below.

LDX #$00
LOOP LDA MESSAGE,x
STA (Screenlocation),x
ORA #$40
STA (Screenlocation on next line),x
INX
CPX #$(How many characters)
BNE LOOP

...and that is the proper way displaying the 1x2 charset. ORA #$40 displays the second half of the charset in memory.

That is all you really need to learn about displaying a 1x2 charset. You probably find that displaying 1x2 charsets may be tough at first, but it is purely simple :o). Take a look at the code, download the data and source (and tools) and have fun.

SOURCE CODE

D64 WITH CODE AND DATA FILES

RESULT:



Making our first picture demo.

This chapter is mainly a bit of theory on how to put everything together and form a demo. Yeah, like it really is. :D Actually I already done the source code and set up the data to produce a simple Goldfish Demo. What we have in the demo is a bitmap picture, which was ported into a Koalapaint format and then split up using the Picture Splitter V2 utility, where the picture datas get split up and saved to where you wish to place them in memory. The demo consists of a bitmap picture, some moving sprites, a scrolltext, and of course some music.

I won't mention much about this section, but I do of course have the code ready for you to browse at :) You can download the example disk (All source, code and tools provided) and try doing some demo making yourself. You should already be familiar with all those routines, as they have been explained in the past few chapters. 

SOURCE CODE

DISK WITH DATA, SOURCE CODE



Result:


Demo 2 - The Assemble IT Demo

So then, how would you like to try something real fun and exciting. Something very oldschool. In our previous chapter, I talked about using more than one IRQ interrupt. So now, we are going to go even more practical and create a real old school demo, using more than one IRQ raster interrupt. We're even going to use splits to create a couple of scrolltexts. We'll also blend in some effects behind the bitmap, known as a waving effect. Anyway, rather than me type in a load of text, here is what binaries we'll need to use.

* Bitmap/logo (Split into segments - bitmap, videoram, colour ram)
* Sprites (Animated balls borrowed from an Enigma intro)
* 1x1 Charset (Any)
* Music (From HVSC)
* 2 Scroll texts. (Type your own)



Ok. here's the listing below to to get you going with the demo.

SOURCE CODE


D64 WITH CODE AND DATA FILES


Swinging a multicoloured logo:

Many classic C64 intros or demos in the demo scene in the 1980's and early 1990's, onwards used to use an effect known as the swinging logo. Many demo coders today would be pretty familiar with swinging logos in their intros.

So then, how does this work? Well, it is really hard for me to explain it properly but I can vaguely know what happens. Well, if you remember the smooth scroll method that triggers $D016 then you should hopefully be familiar with that. Actually the logo swing sort of works a similar kind of way, except that instead of reading a scroll text, you're actually reading the logo data instead. This data is called the MATRIX.

The source for the logo swing will be coming up shortly, but first a logo will need to be drawn. A logo can only be 3 colours. So I recommend that you download a painting program, and then use Charwandler by Johnnie Walker to convert your hires picture into logo format. Logo format is of course 2 separate files: Char + Screen. Oh, and don't forget to make a sinus using a Sinus Calculator

Secondly before you can actually swing your logo, it is recommended that you use the SHAKE IT logo swing converter utility by Paramount. This program will convert your original logo matrix into a swinging logo matrix. It should hopefully do the trick :) A very good program.

Now then, you'll want to do some logo swinging, so below is the ACME source. What this does is calculate the value of the sinus (movement) of the logo and also the position of the matrix, so that you can see the logo swinging forwards and backwards.

SOURCE CODE:

;Logo swing routine

swingpointer = $02
swingstore = $03
!to "logoswing.prg"
* = $0810
sei
jsr $ff81 ;Init screen
lda #$18
sta $d018 ;Logo font at $2000
lda #$00
sta $d020
sta $d021

;Fill the whole screen colours to cyan multicolour as we are using
;the most popular blue scheme.

ldx #$00
shadeitcyan lda #$0b
sta $d800,x
sta $d900,x
sta $da00,x
sta $dae8,x
inx
bne shadeitcyan
lda #$06
ldx #$0e
sta $d022
stx $d023

;Now for the IRQ init routine


lda #<irq
ldx #>irq
sta $0314
stx $0315
lda #$31
ldx #$7f
sta $d012
stx $dc0d
lda #$1b
sta $d011
lda #$01
sta $d01a
cli
loop lda #$00
sta $06
synchronize cmp $06
beq synchronize
jsr logoswing
jmp loop

;Main IRQ routine for the logo swing

irq inc $d019
lda #$32
sta $d012
lda swingstore
sta $d016
jmp $ea7e
swinglogo lda #$ff
sec
ldx swingpointer
sbc $3800,x ;Value of sinus (Which I made in Bonzai's sinus calculator)
lsr
lsr
lsr
tax
ldy #$00
screen lda $3000+0 ;Matrix to read from
sta $0400,y ;Screen loc. to write to
lda $3000+64,x
sta $0400+40,y
lda $3000+64*2,x
sta $0400+80,y
lda $3000+64*3,x
sta $0400+120,y
lda $3000+64*4,x
sta $0400+160,y
lda $3000+64*5,x
sta $0400+200,y
lda $3000+64*6,x
sta $0400+240,y
inx ;Read X 256 times
iny
cpy #$27 ;Read y 39 times
bne screen
ldx swingpointer
lda $3800,x
and #$07
ora #$d0 ;Kill this if your logo is not multicolour
sta swingstore ;The value to put into $D016
inc swingpointer ;Add 1 to the swing pointer
rts

;Binaries for the source.

* = $2000-2
!binary "logochar.prg"
* = $3000-2
!binary "logomatrix.prg"
* = $3800-2
!binary "sinusdata.prg"


 Previous Page / Back to Contents Page