1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-01-24 17:31:46 +00:00

Add SixtyPical translations of Ribos and "The PETulant Cursor".

This commit is contained in:
Chris Pressey 2018-03-15 10:56:09 +00:00
parent ed917566ea
commit 42864bf125
17 changed files with 825 additions and 0 deletions

View File

@ -11,6 +11,8 @@ History of SixtyPical
insisting that `goto` only appears in it.
* Fixed bug when `--prelude` option was missing.
* Fixed bug when reporting line numbers of scanner-level syntax errors.
* Translated the small demo project Ribos and "The PETulant Cursor"
to SixtyPical and added them to the `eg/c64/` section of the repo.
0.13
----

14
eg/c64/README.md Normal file
View File

@ -0,0 +1,14 @@
This directory contains SixtyPical example programs
specifically for the Commodore 64.
Subdirectories of note:
* [demo-game](demo-game/): a little game-like program written as a
"can we write something you'd see in practice?" test case for SixtyPical.
* [ribos](ribos/): a well-commented example of a C64 raster interrupt
routine. Originally written with the P65 assembler (now Ophis).
The second version of it has been translated to SixtyPical.
* [petulant](petulant/) -- "The PETulant Cursor", a tiny (44 bytes)
"display hack". Originally written in the late 80's. Rewritten with
the P65 assembler (now Ophis) and re-released April 1, 2008 (a
hint as to its nature). Translated to SixtyPical, it's 48 bytes.

9
eg/c64/petulant/build.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
sixtypical --output-format=prg --origin=0x02a7 petulant.60p > petulant-60p.prg
if [ "x$COMPARE" != "x" ]; then
dcc6502 petulant.prg > petulant.prg.disasm.txt
dcc6502 petulant-60p.prg > petulant-60p.prg.disasm.txt
paste petulant.prg.disasm.txt petulant-60p.prg.disasm.txt | pr -t -e24
rm -f *.disasm.txt
fi

Binary file not shown.

View File

@ -0,0 +1,54 @@
// petulant.60p - The PETulant Cursor, a "display hack" for the Commodore 64
// Originally written by Chris Pressey sometime in the late 1980's
// Rewritten in P65 assembly and released March 2008
// Rewritten in SixtyPical in March 2018
// This work is part of the public domain.
// ----- Types -----
typedef routine
inputs border, blnon, color, background
outputs border
trashes a, z, n
irq_handler
// ----- Addresses -----
vector irq_handler cinv @ $314 // hw irq interrupt, 60x per second
byte blnon @ $cf // was last cursor blink on or off?
byte color @ $286 // current foreground colour for text
byte border @ $d020 // colour of border of the screen
byte background @ $d021 // colour of background of the screen
// ----- Variables -----
vector irq_handler save_cinv
// ----- Interrupt Handler -----
define our_cinv irq_handler
{
ld a, blnon
if not z {
ld a, color
} else {
ld a, background
}
st a, border
goto save_cinv
}
// ----- Main Program -----
define main routine
inputs cinv
outputs cinv, save_cinv
trashes a, n, z
{
with interrupts off {
copy cinv, save_cinv
copy our_cinv, cinv
}
}

View File

@ -0,0 +1,52 @@
; petulant.p65 - The PETulant Cursor, a "display hack" for the Commodore 64
; Originally written by Chris Pressey sometime in the late 1980's
; Rewritten in P65 assembly and released March 2008
; This work is part of the public domain.
; ----- BEGIN petulant.p65 -----
; PRG file header
.org 0
.word $02a7
.org $02a7
; ----- Constants -----
.alias cinv $0314 ; hw irq interrupt, 60x per second
.alias blnon $cf ; was last cursor blink on or off?
.alias color $286 ; current foreground colour for text
.alias vic $d000 ; base address of VIC-II chip
.alias border vic+$20 ; colour of border of the screen
.alias background vic+$21 ; colour of background of the screen
; ----- Start of Program -----
start: sei ; disable interrupts
lda cinv ; save low byte of existing handler
sta savecinv
lda cinv+1 ; save high byte
sta savecinv+1
lda #<newcinv ; install new interrupt handler
sta cinv
lda #>newcinv
sta cinv+1
cli ; re-enable interrupts
rts
newcinv: lda blnon ; is the cursor on?
beq cursor_off
cursor_on: lda color ; yes, get its colour
jmp egress
cursor_off: lda background ; no, get the background colour
egress: sta border ; colour the border
jmp (savecinv) ; continue pre-existing interrupt handler
; ----- Uninitialized Data -----
.space savecinv 2
; ----- END of petulant.p65 -----

View File

@ -0,0 +1 @@
§x­<03>Ó­<03>Ô©À<C2A9>©<02>X`¥Ïð­†­<> ÐlÓ

View File

@ -0,0 +1,32 @@
The PETulant Cursor
===================
This is a tiny (44 bytes long) machine-language demo for the Commodore 64,
somewhat in the style of later "display hacks" for the Amiga -- surprising
and silly ways to play with the user interface.
So as not to not spoil the fun, try running it before reading the source.
To run it, make the file PETULANT.PRG accessible to your favourite Commodore
64 (or Commodore 64 emulator) in your favourite way, then
LOAD "PETULANT.PRG",8,1
SYS 679
For further fun, try changing the text colour (hold the C= or CTRL key while
pressing a number) or the background colour (POKE 53281 with a number from
0 to 15) while it is running.
I must have originally wrote this sometime in the late 80's. I disassembled
and rewrote it (to make it play more nicely with existing interrupt handlers)
in 2008.
Who knows -- this could actually be useful, in a ridiculously minor way: it
makes it much more obvious when control has returned to BASIC immediate mode
(e.g., when a program has finished loading.)
Enjoy!
-Chris Pressey
April 1, 2008
Chicago, IL

9
eg/c64/ribos/build.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
sixtypical --output-format=prg --origin=0xc000 ribos2.60p > ribos2-60p.prg
if [ "x$COMPARE" != "x" ]; then
dcc6502 ribos2.prg > ribos2.prg.disasm.txt
dcc6502 ribos2-60p.prg > ribos2-60p.prg.disasm.txt
paste ribos2.prg.disasm.txt ribos2-60p.prg.disasm.txt | pr -t -e24
rm -f *.disasm.txt
fi

79
eg/c64/ribos/readme.txt Normal file
View File

@ -0,0 +1,79 @@
Ribos
=====
This little demo is intended to be a well-commented example of how to
program a raster interrupt in 6502 assembly language on a Commodore 64.
This (r)aster (i)nterrupt changes the colour of a region of the
(bo)rder of the C64 (s)creen; thus, RIBOS. Also, it's the name of a
planet from Dr. Who, if that means anything.
How to Run the Demo (using the VICE C64 emulator, x64)
------------------------------------------------------
0. Obtain VICE from http://www.viceteam.org/, install it,
and run x64
1. Mount this project's directory as drive 8:
Make sure
Peripheral settings > Device #8 > Enable IEC Device
is checked, then select
Peripheral settings > Device #8 > File system directory...
and enter the path to the project directory.
2. LOAD "RIBOS.PRG",8,1
3. SYS 49152
4. You should see the colour of the middle of the border change
while you get a READY. prompt and can continue working.
How to Assemble the Program (using the p65 assembler)
-----------------------------------------------------
0. Obtain p65 from http://hkn.berkeley.edu/~mcmartin/P65/
(I used p65-Perl version 1.1) and install it somewhere
on your path. If your Perl interpreter isn't located at
/usr/bin/perl, change the first line of p65 appropriately.
1. p65 -v -t -b ribos.p65 ribos.prg
The switches aren't necessary, but they make it feel like
p65 is doing something difficult and important. It also
isn't necessary to add the '.prg' extension on the end of
the binary object's filename, since it will appear as a
PRG file to VICE anyway, but it's nice as a reminder when
you're working in a modern operating system.
2. Follow the steps under 'How to Run this Demo' to see that
it worked.
How it Works
------------
Read the source! I've tried to make it very well-commented,
including what happens when you leave out some steps.
I wrote this demo because it was a long time since I had done any C64
programming, and, having just obtained a copy of the 'Commodore 64
Programmer's Reference Guide,' I wanted to code something challenging,
yet not too involved. I remembered raster interrupts as one of those
quintessential C64 low-level graphics tricks, so I decided to try my
hand at that. Looking around on the Internet, I found this page:
http://everything2.com/index.pl?node_id=79254
Although it's a fairly detailed description, it took me a couple of
frustrating hours to implement it successfully - both the everything2
article and the Reference Guide were pretty muddy on a couple of
points. What I learned in the process is written into the comments.
Happy raster-interrupting!
-Chris Pressey
April 10, 2007
Vancouver, BC

291
eg/c64/ribos/ribos.p65 Normal file
View File

@ -0,0 +1,291 @@
; ribos.p65 - p65 assembly source for RIBOS:
; Demonstration of the VIC-II raster interrupt on the Commodore 64:
; Alter the border colour in the middle part of the screen only.
; Original (hardware IRQ vector) version.
; By Chris Pressey, Cat's Eye Technologies.
; This work has been placed in the public domain.
; ----- BEGIN ribos.p65 -----
; This source file is intented to be assembled to produce a PRG file
; which can be loaded into the C64's memory from a peripheral device.
; All C64 PRG files start with a 16-bit word which represents the
; location in memory to which they will be loaded. We can provide this
; using p65 directives as follows:
.org 0
.word $C000
; Now the actual assembly starts (at memory location 49152.)
.org $C000
; ----- Constants -----
; We first define some symbolic constants to add some clarity to our
; references to hardware registers and other locations in memory.
; Descriptions of the registers follow those given in the 'Commodore 64
; Programmer's Reference Guide'.
; The CIA #1 chip.
.alias cia1 $dc00 ; pp. 328-331
.alias intr_ctrl cia1+$d ; "CIA Interrupt Control Register
; (Read IRQs/Write Mask)"
; The VIC-II chip.
.alias vic $d000 ; Appendix G:
.alias vic_ctrl vic+$11 ; "Y SCROLL MODE"
.alias vic_raster vic+$12 ; "RASTER"
.alias vic_intr vic+$19 ; "Interrupt Request's" (sic)
.alias vic_intr_enable vic+$1a ; "Interrupt Request MASKS"
.alias border_color vic+$20 ; "BORDER COLOR"
; The address at which the IRQ vector is stored.
.alias irq_vec $fffe ; p. 411
; The zero-page address of the 6510's I/O register.
.alias io_ctrl $01 ; p. 310, "6510 On-Chip 8-Bit
; Input/Output Register"
; KERNAL and BASIC ROMs, p. 320
.alias kernal $e000
.alias basic $a000
; Zero-page addresses that the memory-copy routine uses for
; scratch space: "FREKZP", p. 316
.alias zp $fb
.alias stop_at $fd
; ----- Main Routine -----
; This routine is intended to be called by the user (by, e.g., SYS 49152).
; It installs the raster interrupt handler and returns to the caller.
; Key to installing the interrupt handler is altering the IRQ service
; vector. However, under normal circumstances, the address at which
; this vector is stored ($ffffe) maps to the C64's KERNAL ROM, which
; cannot be changed. So, in order to alter the vector, we must enable
; the RAM that underlies the ROM (i.e. the RAM that maps to the same
; address space as the KERNAL ROM.) If we were writing a bare-metal
; game, and didn't need any KERNAL routines or support, we could just
; switch it off. But for this demo, we'd like the raster effect to
; occur in the background as we use BASIC and whatnot, so we need to
; continue to have access to the KERNAL ROM. So what we do is copy the
; KERNAL ROM to the underlying RAM, then switch the RAM for the ROM.
jsr copy_rom_to_ram
; Interrupts can occur at any time. If one were to occur while we were
; changing the interrupt vector - for example, after we have stored the
; low byte of the address but before we have stored the high byte -
; unpredictable behaviour would result. To be safe, we disable interrupts
; with the 'sei' instruction before changing anything.
sei
; We obtain the address of the current IRQ service routine and save it
; in the variable 'saved_irq_vec'.
lda irq_vec ; save low byte
sta saved_irq_vec
lda irq_vec+1 ; save high byte
sta saved_irq_vec+1
; We then store the address of our IRQ service routine in its place.
lda #<our_service_routine
sta irq_vec
lda #>our_service_routine
sta irq_vec+1
; Now we must specify the raster line at which the interrupt gets called.
lda scanline
sta vic_raster
; Note that the position of the raster line is given by a 9-bit value,
; and we can't just assume that, because the raster line we want is less
; than 256, that the high bit will automatically be set to zero, because
; it won't. We have to explicitly set it high or low. It is found as
; the most significant bit of a VIC-II control register which has many
; different functions, so we must be careful to preserve all other bits.
lda vic_ctrl
and #%01111111
sta vic_ctrl
; Then we enable the raster interrupt on the VIC-II chip.
lda #$01
sta vic_intr_enable
; The article at everything2 suggests that we read the interrupt control
; port of the CIA #1 chip, presumably to acknowledge any pending IRQ and
; avoid the problem of having some sort of lockup due to a spurious IRQ.
; I've tested leaving this out, and the interrupt handler still seems get
; installed alright. But, I haven't tested it very demandingly, and it's
; likely to open up a race condition that I just haven't encountered (much
; like if we were to forget to execute the 'sei' instruction, above.)
; So, to play it safe, we read the port here.
lda intr_ctrl
; We re-enable interrupts to resume normal operation - normal, that is,
; except that our raster interrupt service routine will be called the next
; time the raster reaches the line stored in the 'vic_raster' register of
; the VIC-II chip.
cli
; Finally, we return to the caller.
rts
; ----- Raster Interrupt Service Routine ------
our_service_routine:
; This is an interrupt service routine (a.k.a. interrupt handler,) and as
; such, it can be called from anywhere. Since the code that was interrupted
; likely cares deeply about the values in its registers, we must be careful
; to save any that we change, and restore them before switching back to it.
; In this case, we only affect the processor flags and the accumulator, so
; we push them onto the stack.
php
pha
; The interrupt service routine on the Commodore 64 is very general-purpose,
; and may be invoked by any number of different kinds of interrupts. We,
; however, only care about a certain kind - the VIC-II's raster interrupt.
; We check to see if the current interrupt was caused by the raster by
; looking at the low bit of the VIC-II interrupt register. Note that we
; immediately store back the value found there before testing it. This is
; to acknowledge to the VIC-II chip that we got the interrupt. If we don't
; do this, it won't send us another interrupt next time.
lda vic_intr
sta vic_intr
and #$01
cmp #$01
beq we_handle_it
; If the interrupt was not caused by the raster, we restore the values
; of the registers from the stack, and continue execution as normal with
; the existing interrupt service routine.
pla
plp
jmp (saved_irq_vec)
we_handle_it:
; If we got here, the interrupt _was_ caused by the raster. So, we get
; to do our thing. To keep things simple, we just invert the border colour.
lda border_color
eor #$ff
sta border_color
; Now, we make the interrupt trigger on a different scan line so that we'll
; invert the colour back to normal lower down on the screen.
lda scanline
eor #$ff
sta scanline
sta vic_raster
; Restore the registers that we saved at the beginning of this routine.
pla
plp
; Return to normal operation. Note that we must issue an 'rti' instruction
; here, not 'rts', as we are returning from an interrupt.
rti
; ----- Utility Routine: copy KERNAL ROM to underlying RAM -----
copy_rom_to_ram:
; This is somewhat more involved than I let on above. The memory mapping
; facilities of the C64 are a bit convoluted. The Programmer's Reference
; Guide states on page 261 that the way to map out the KERNAL ROM, and
; map in the RAM underlying it, is to set the HIRAM signal on the 6510's
; I/O line (which is memory-mapped to address $0001) to 0. This is true.
; However, it is not the whole story: setting HIRAM to 0 *also* maps out
; BASIC ROM and maps in the RAM underlying *it*. I suppose this makes
; sense from a design point of view; after all, BASIC uses the KERNAL, so
; there wouldn't be much sense leaving it mapped when the KERNAL is mapped
; out. Anyway, what this means for us is that we must copy both of these
; ROMs to their respective underlying RAMs if we want to survive returning
; to BASIC.
ldx #>basic
ldy #$c0
jsr copy_block
ldx #>kernal
ldy #$00
jsr copy_block
; To actually substitute the RAM for the ROM in the memory map, we
; set HIRAM (the second least significant bit) to 0.
lda io_ctrl
and #%11111101
sta io_ctrl
rts
; ----- Utility Routine: copy a ROM memory block to the underlying RAM -----
; Input: x register = high byte of start address (low byte = #$00)
; y register = high byte of end address (stops at address $yy00 - 1)
; This subroutine is a fairly straightforward memory copy loop. A somewhat
; counter-intuitive feature is that we immediately store each byte in the
; same location where we just read it from. We can do this because, even
; when the KERNAL or BASIC ROM is mapped in, writes to those locations still
; go to the underlying RAM.
copy_block: stx zp+1
sty stop_at
ldy #$00
sty zp
copy_loop: lda (zp), y
sta (zp), y
iny
cpy #$00
bne copy_loop
ldx zp+1
inx
stx zp+1
cpx stop_at
bne copy_loop
rts
; ----- Variables -----
; 'scanline' stores the raster line that we want the interrupt to trigger
; on; it gets loaded into the VIC-II's 'vic_raster' register.
scanline: .byte %01010101
; We also reserve space to store the address of the interrupt service
; routine that we are replacing in the IRQ vector, so that we can transfer
; control to it at the end of our routine.
.space saved_irq_vec 2
; ----- END of ribos.p65 -----

BIN
eg/c64/ribos/ribos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
eg/c64/ribos/ribos.prg Normal file

Binary file not shown.

BIN
eg/c64/ribos/ribos2-60p.prg Normal file

Binary file not shown.

103
eg/c64/ribos/ribos2.60p Normal file
View File

@ -0,0 +1,103 @@
// ribos2.60p - SixtyPical source for RIBOS2:
// Demonstration of the VIC-II raster interrupt on the Commodore 64:
// Alter the border colour in the middle part of the screen only,
// Simplified (KERNAL IRQ vector) version.
// By Chris Pressey, Cat's Eye Technologies.
// This work has been placed in the public domain.
// For comments, see ribos2.p65.
// ----- Types -----
typedef routine
inputs border_color, vic_intr, scanline
outputs border_color, vic_intr, scanline
trashes a, z, n, c, vic_raster
irq_handler
// ----- Addresses -----
// The CIA #1 chip.
byte cia1 @ $dc00 // pp. 328-331
byte intr_ctrl @ $dc0d // "CIA Interrupt Control Register
// (Read IRQs/Write Mask)"
// The VIC-II chip.
byte vic @ $d000 // Appendix G:
byte vic_ctrl @ $d011 // "Y SCROLL MODE"
byte vic_raster @ $d012 // "RASTER"
byte vic_intr @ $d019 // "Interrupt Request's" (sic)
byte vic_intr_enable @ $d01a // "Interrupt Request MASKS"
byte border_color @ $d020 // "BORDER COLOR"
// The address at which the IRQ vector is stored.
vector irq_handler cinv @ $314 // p. 319, "Vector: Hardware
// IRQ Interrupt"
// ----- Variables -----
vector irq_handler saved_irq_vec
byte scanline : 85 // %01010101
// ----- Externals ------
// An address in ROM which contains "PLA TAY PLA TAX RTI".
// ribos2.p65 just contains these instructions itself, but
// generating them as part of a SixtyPical program would not
// be practical. So we just jump to this location instead.
routine pla_tay_pla_tax_pla_rti
inputs a
trashes a
@ $EA81
// ----- Interrupt Handler -----
define our_service_routine irq_handler
{
ld a, vic_intr
st a, vic_intr
and a, 1
cmp a, 1
if not z {
goto saved_irq_vec
} else {
ld a, border_color
xor a, $ff
st a, border_color
ld a, scanline
xor a, $ff
st a, scanline
st a, vic_raster
trash vic_raster
goto pla_tay_pla_tax_pla_rti
}
}
// ----- Main Program -----
define main routine
inputs cinv, scanline, vic_ctrl, intr_ctrl
outputs cinv, saved_irq_vec, vic_ctrl, vic_intr_enable
trashes a, n, z, vic_raster
{
with interrupts off {
copy cinv, saved_irq_vec
copy our_service_routine, cinv
ld a, scanline
st a, vic_raster
ld a, vic_ctrl
and a, 127
st a, vic_ctrl
ld a, 1
st a, vic_intr_enable
ld a, intr_ctrl
}
}

179
eg/c64/ribos/ribos2.p65 Normal file
View File

@ -0,0 +1,179 @@
; ribos2.p65 - p65 assembly source for RIBOS2:
; Demonstration of the VIC-II raster interrupt on the Commodore 64:
; Alter the border colour in the middle part of the screen only,
; Simplified (KERNAL IRQ vector) version.
; By Chris Pressey, Cat's Eye Technologies.
; This work has been placed in the public domain.
; ----- BEGIN ribos2.p65 -----
; This is a simplified version of ribos.p65 which uses the Commodore 64
; KERNAL's support for interrupt handling. Whereas ribos.p65 could run
; with the KERNAL completely disabled, ribos2.p65 relies on it.
; I'll assume you've read through ribos.p65 at least once, and won't
; say much about the code that's shared between the two programs.
; Again, page references are from the 'Commodore 64 Programmer's
; Reference Guide'.
.org 0
.word $C000
.org $C000
; ----- Constants -----
; The CIA #1 chip.
.alias cia1 $dc00 ; pp. 328-331
.alias intr_ctrl cia1+$d ; "CIA Interrupt Control Register
; (Read IRQs/Write Mask)"
; The VIC-II chip.
.alias vic $d000 ; Appendix G:
.alias vic_ctrl vic+$11 ; "Y SCROLL MODE"
.alias vic_raster vic+$12 ; "RASTER"
.alias vic_intr vic+$19 ; "Interrupt Request's" (sic)
.alias vic_intr_enable vic+$1a ; "Interrupt Request MASKS"
.alias border_color vic+$20 ; "BORDER COLOR"
; The address at which the IRQ vector is stored.
.alias cinv $0314 ; p. 319, "Vector: Hardware
; IRQ Interrupt"
; ----- Main Routine -----
; This routine is intended to be called by the user (by, e.g., SYS 49152).
; It installs the raster interrupt handler and returns to the caller.
; Key to installing the interrupt handler is altering the IRQ service
; vector. As I learned from a careful reading of Sheldon Leemon's
; "Mapping the Commodore 64", if we wish to leave the KERNAL intact and
; operational, it gives us an easy way to do that. Whenever it handles
; an IRQ, it has to decide whether the IRQ was generated by a BRK
; instruction, or some external device issuing an interrupt request. In
; either case, it jumps indirectly through its IRQ-handling vector. We
; can simply modify this vector (at $314) to point to our routine. In
; fact, this is the "CINV" vector, which may already be familiar to you
; if you have done any modest amount of C64 machine language programming;
; it is normally called every 1/60 of a second due to the interrupt
; request generated by CIA#1 Timer B. Here we will simply be using it
; to detect when a raster interrupt has occurred, as well.
; First, disable interrupts before changing interrupt vectors.
sei
; We obtain the address of the current IRQ service routine in CINV
; and save it in the variable 'saved_irq_vec'.
lda cinv
sta saved_irq_vec
lda cinv+1
sta saved_irq_vec+1
; We then store the address of our IRQ service routine in its place.
lda #<our_service_routine
sta cinv
lda #>our_service_routine
sta cinv+1
; Now we must specify the raster line at which the interrupt gets called,
; setting the ninth bit to zero.
lda scanline
sta vic_raster
lda vic_ctrl
and #%01111111
sta vic_ctrl
; Then we enable the raster interrupt on the VIC-II chip.
lda #$01
sta vic_intr_enable
; We read the interrupt control port of CIA #1 for good measure.
lda intr_ctrl
; And we re-enable interrupts to resume normal operation -- plus our jazz.
cli
; Finally, we return to the caller.
rts
; ----- Raster Interrupt Service Routine ------
our_service_routine:
; First, we check to see if the current interrupt was caused by the raster.
lda vic_intr
sta vic_intr
and #$01
cmp #$01
beq we_handle_it
; If the interrupt was not caused by the raster, we continue execution as
; normal, with the existing interrupt service routine.
jmp (saved_irq_vec)
we_handle_it:
; If we got here, the interrupt was caused by the raster, so we do our thing.
lda border_color
eor #$ff
sta border_color
; Now, we make the interrupt trigger on the other scan line next time.
lda scanline
eor #$ff
sta scanline
sta vic_raster
; Return to normal operation. If we simply continue with the standard
; interrupt service routine by jumping through saved_irq_req, we will
; confuse it a bit, as it expects to be called 60 times per second, and
; continuing it here would make it occur more frequently. The result
; would be the cursor blinking more frequently and the time of day clock
; running fast.
; So, we issue a plain return from interrupt (RTI) here. But first, we
; must make sure that the state of the system is back to the way it was
; when the interrupt service routine was called. Since it can be called
; from anywhere, and since the code that was interrupted likely cares
; deeply about the values in its registers, the KERNAL routine which
; dispatches through CINV first carefully saves the contents of the
; registers on the stack. We must be equally careful about restoring
; those values before switching back to that interrupted code.
pla
tay
pla
tax
pla
rti
; ----- Variables -----
; 'scanline' stores the raster line that we want the interrupt to trigger
; on; it gets loaded into the VIC-II's 'vic_raster' register.
scanline: .byte %01010101
; We also reserve space to store the address of the interrupt service
; routine that we are replacing in the IRQ vector, so that we can transfer
; control to it at the end of our routine.
.space saved_irq_vec 2
; ----- END of ribos2.p65 -----

BIN
eg/c64/ribos/ribos2.prg Normal file

Binary file not shown.