Copy Link
Add to Bookmark
Report

Interrupts

Assembler coding - Lesson 9

eZine's profile picture
Published in 
Assembler coding
 · 1 year ago

An Interrupt is a process that INTERRUPTS the processor's operation at that instant in time to execute another piece of code.

For example assume that you were running some software that monitored 100 hotel rooms to see if the fire alarm or something had gone off. If one had you execute some more code to ring the fire department. This type of coding is SLOW, it is termed POLLING. Here we are continually checking each room to see if the alarm has been set (It uses all the processing time, and we can't do anything else).

A better way to do this would be to have the alarms wired to the processors interrupt pin. An Interrupt then occurs which halts processor operation at that point in time (Note that before an Interrupt occurred, the processor could have been doing something else as it was not tied up POLLING). Now the interrupt has occurred and the processor calls an Interrupt Routine, this routine could then check which hotel alarm has been set and act accordingly.

Of course this method is external, i.e. hardwired, we will be generating interrupts internally, but you can see now what an interrupt is.

I mentioned that when an interrupt is generated it executes an Interrupt Routine at that instant in time. This means it leaves whatever code it was doing and jumps to the interrupt routine. When the interrupt routine is finished, you Return from the Interrupt Routine back to where you left the original code. The interrupt routine may well include code that overwrites your values in the accumulator and X & Y registers. You therefore need to place these values in a special place in memory called the STACK. You place these values on the STACK at the very beginning of the interrupt routine, and then the very last thing you do in your interrupt routine is to take the values back out of STACK and place them back into the registers where they came from.

The STACK is 256 bytes long and is located in memory at address 0100 Hex to 01FF Hex. The STACK is termed:

  LIFO - Last In First Out

This means that whatever you place in the stack last, will be taken out first.

For example, here's the beginning and end of a interrupt routine:

  PHA - Here we push the accumulator onto the stack 

TXA - Here we transfer the X reg to Accumulator

PHA - Push accumulator onto stack

TYA - Transfer Y reg to Accumulator

PHA - Push accumulator onto stack

...

...

PLA - Pull value from stack into accumulator

TAY - Transfer accumulator to Y register

PLA - Pull value from stack into accumulator

TAX - Transfer accumulator to X register

PLA - Pull value from stack into accumulator

Can you see that we must do it this way otherwise all the values would be in the wrong registers.

Also remember that this is only needed if you are writing over your original register values. This method can also be used in other parts of your program to keep track of your register values.

Ok, back to actual interrupts.

There are 4 types of interrupts on the C64, these are:

  RASTER - (This is what we are going to be using) 

SPRITE to BACKGROUND collision

SPRITE to SPRITE collision

LIGHT PEN

Each of these interrupts is located at 53273 or $D019.

  Raster - BIT 0 

Sprite to Background - BIT 1

Sprite to Sprite - BIT 2

Light Pen - BIT 4

BIT 7 of $D019 (53273) is the IRQ and is set for all interrupts

The C64 generates an interrupt 60 times a second, this is used to check the keyboard etc., and when an interrupt has occurred the processor checks Bit 4 of the status register which is the BRK flag. If this is set then the program jumps to vector at locations $0316 & $0317. If BIT 4 is not set then the interrupt is an IRQ (Interrupt Request) and then the program jumps to the vector stored at locations $0314 & $0315.

A vector is the location which holds the address of where your Interrupt Routine is located at. You will notice that there are 2 vector addresses. One holds the Low Byte of your interrupt routine, whilst the other holds the high byte.

Where:

$0314 = Low Byte

$0315 = High Byte

Example

The location $0314 Holds the Value 00 (Hex)

The location $0315 Holds the value 10 (Hex)

The location of your interrupt routine would therefore placed at $1000 (Hex) or 4096 (Decimal)

(NOTE - You place the interrupt routine code at this location yourself)

Raster Lines

Your TV or monitor screen is composed of SCAN lines (raster lines). This is the way the picture is produced.

The monitor or TV is really a CRT (Cathode Ray Tube) which has a Phosphorus coated screen. At the back of the screen is an Electron Gun which fires electrons along the Tube to the screen. An electron hitting the phosphorus screen causes visible light (what you see). The gun is fired across your screen and then moves slightly down, across again, then down etc, etc. The gun is firing continuously each place where it fires is one pixel. The amount the gun moves down is 0-262 on PAL TV's and 0-312 on NTSC. This value is greater than 255 and so the register $D012 is used to hold the lower 8 bits, while $D011 holds the 9th bit. All this happens so fast that the screen looks like it does to you.


Ok enough talk lets do an example program. You will learn more by looking and then trying the code for yourself.

This example will split the screen into 3 parts. Each part will have a different background and border colour so you can see whats happened.

  10 ORG 8192 
20 SEI
30 LDA #147
40 JSR $FFD2
50 LDA #$7F
60 STA $DC0D
70 LDA #00
80 STA $D012
90 STA IRQCOUNT
100 LDA (UPARROW)IRQ - YOU JUST TYPE THE UP ARROW
110 STA $0315
120 LDA #IRQ
130 STA $0314
140 LDA $D01A
150 ORA #01
160 STA $D01A
165 CLI
170 LOOP JMP LOOP
180 IRQ LDA #01
190 STA $D019
200 LDA $D011
210 AND #$7F
220 STA $D011
230 LDA IRQCOUNT
240 BEQ INT1
250 CMP #01
260 BEQ INT2
270 JMP RESET
280 INT1 LDA #100
290 STA $D012
300 INC IRQCOUNT
310 LDA #02
320 STA 53280
330 STA 53281
340 JMP $EA31
350 INT2 LDA #200
360 STA $D012
370 INC IRQCOUNT
380 LDA #03
390 STA 53280
400 STA 53281
410 JMP $FEBC
420 RESET LDA #00
430 STA IRQCOUNT
440 STA $D012
450 LDA #05
460 STA 53280
470 STA 53281
480 JMP $FEBC
490 IRQCOUNT DFB 00

Right lets have a look at the explanation:

10 ORG 8192 - Where to place in memory

20 SEI - This disables interrupts until we are ready to accept them by setting up first

30 LDA #147

40 JSR $FFD2 - Clear Screen

50 LDA #$7F

60 STA $DC0D - These turn off CIA interrupts (BIT 7 = 0)

70 LDA #00

80 STA $D012 - Set first raster at 0

90 STA IRQCOUNT - Set a flag to hold count so we know where we are

100 LDA (UPARROW)IRQ

110 STA $0315 - Set the high byte of the interrupt routine called IRQ

120 LDA #IRQ

130 STA $0314 - Set the low byte of the interrupt routine

140 LDA $D01A

150 ORA #01

160 STA $D01A - The last 3 lines enable raster interrupts (BIT 0 = 1)

165 CLI - Enable interrupts again cos we have now got setup (

170 LOOP JMP LOOP - Continuous Loop

This next part is the Interrupt Routine called IRQ (this is the address stored at the vectors $0314 & $0315)

180 IRQ LDA #01

190 STA $D019 - These 2 lines cause the raster interrupt (BIT 0 = 1)

200 LDA $D011

210 AND #$7F

220 STA $D011 - These last 3 clear the 8th BIT of the raster

230 LDA IRQCOUNT - Here we find the position of the program to go to

240 BEQ INT1 - Branch here if IRQCOUNT = 0

250 CMP #01

260 BEQ INT2 - Branch here if IRQCOUNT = 1

270 JMP RESET - If IRQCOUNT is not equal 0 or 1 then jump to RESET

280 INT1 LDA #100 - The first position

290 STA $D012 - We set the raster position to 100 down the screen

300 INC IRQCOUNT - +1 to the flag (now = 1)

310 LDA #02

320 STA 53280

330 STA 53281 - Change the colours of the background and borders to RED

340 JMP $EA31 - Jump to ROM (Main entry IRQ point)

350 INT2 LDA #200 - Position 2

360 STA $D012 - We have set the raster to occur at position 200 down the screen

370 INC IRQCOUNT - +1 to flag again (now = 2)

380 LDA #03

390 STA 53280

400 STA 53281 - Change colours of border & background

410 JMP $FEBC - Jump to ROM (Exit Interrupt)

420 RESET LDA #00 - 3rd position

430 STA IRQCOUNT - And so we now reset the flag to zero as all positions are done

440 STA $D012 - We also set the raster back to zero

450 LDA #05

460 STA 53280

470 STA 53281 - Again we change the colours of the border and background

480 JMP $FEBC - And again jump to ROM (Exit Interrupt)

490 IRQCOUNT DFB 00 - This is the memory location for IRQCOUNT

Well that about raps it up. Now you can see that on each of those positions you could have 8 sprites in each, and different direction scrolls or whatever takes your fancy.

We will do some kind of program like that later, but in the next lesson we will learn how to do raster colour bars.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT