;; This example shows how Z80 interrupt mode 2 can be used
;; on the CPC and KC Compact.
;;
;; This code is compatible with the CPC+, and will function
;; the same if standard raster interrupts are used.
;;
;; The hardware of the CPC and KC Compact does not generate
;; a interrupt vector to be used with Z80 mode 2. The 8-bit
;; vector read from the bus, when the interrupt is acknowledged,
;; can't be guaranteed.
;;
;; This example shows how the standard raster interrupts
;; can be used safely with this mode. The program will
;; continue to function correct even if a device is connected
;; which does generate a 8-bit vector as long as the device
;; is not activated.
;;
;; (c) Kevin Thacker, 2001-2002
;;
;; This source is released under the GNU Public License v2.

org &4000
nolist

;;------------------------------------------------------------
;; Setup interrupt handler - required

;; disable interrupts
di

;; set interrupt mode 2
im 2

;; set I register. This is the most significant byte
;; of the address of the interrupt handler table and forms 
;; bit 15..8 of the lookup address.
;; the table will cover &8000-&8100 inclusive.
ld a,&80
ld i,a

;; setup interrupt vector table
;;
;; as proved, bits 15..8 of the interrupt handler must
;; be the same as bits 7..0. Therefore the table is
;; filled with a single byte. In this example this is &81.
;;
;; the interrupt handler in this example is at &8181.
ld hl,&8000
ld e,l
ld d,h
inc de
ld (hl),&81     
ld bc,257       ;; 257 because of the case where 8-bit vector is &FF.
                ;; (interrupt handler will be formed from 
                ;; bytes at &80FF and &8100).
ldir

;; this is not necessary if the interrupt handler
;; is located at &8181, but this is included to make this
;; example complete.

ld a,&c3				;; JP instruction
ld hl,interrupt_handler	;; interrupt handler location
ld (&8181),a			;; poke JP instruction
ld (&8182),hl

;; enable interrupts
ei


;;----------------------------------------------------
;; the following code has been added so that the example will
;; assemble and function. This code is optional. You can
;; replace this with your own code.
;;
;;  
;; This code will change the colour of pen 0 at each 
;; interrupt. The result is thick horizontal bars 
;; of colour.
;; 

;; select pen 0
ld bc,&7f00
out (c),c

.main_loop
;; wait for start of vsync
ld b,&f5
.ml
in a,(c)
rra
jr nc,ml


;; wait for interrupt
halt
;; set pen 0 to "Blue"
ld bc,&7f44
out (c),c

;; wait for interrupt
halt
;; set pen 0 to "Bright Blue"
ld bc,&7f55
out (c),c

;; wait for interrupt
halt
;; set pen 0 to "Sky Blue"
ld bc,&7f57
out (c),c

;; wait for interrupt
halt
;; set pen 0 to "Pastel Cyan"
ld bc,&7f5b
out (c),c

;; wait for interrupt
halt
;; set pen 0 to "Pastel yellow"
ld bc,&7f43
out (c),c

;; wait for interrupt
halt
;; set pen 0 to "Bright while"
ld bc,&7f4b
out (c),c

jp main_loop

;;----------------------------------------------------
;; the interrupt handler - required

.interrupt_handler
ei                  ;; re-enable interrupts
reti                ;; reti is required if interrupt mode 2 is used. This
                    ;; is a safety measure because some devices will 
                    ;; monitor the z80 databus for this instruction
                    ;; and will not operate correctly if it is not present.
                    ;; Although this program assumes that these devices
                    ;; are not being used
