2019-03-21 21:24:39 +00:00
|
|
|
// Test interrupt routine using a variable between calls (irq_idx)
|
2021-06-19 19:26:05 +00:00
|
|
|
/// @file
|
2021-06-19 20:11:26 +00:00
|
|
|
/// Commodore 64 Registers and Constants
|
2021-06-19 19:26:05 +00:00
|
|
|
/// @file
|
2021-06-19 20:11:26 +00:00
|
|
|
/// The MOS 6526 Complex Interface Adapter (CIA)
|
2021-06-19 20:28:44 +00:00
|
|
|
///
|
2021-06-19 19:26:05 +00:00
|
|
|
/// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
2020-12-21 07:57:41 +00:00
|
|
|
// Commodore 64 PRG executable file
|
|
|
|
.file [name="irq-idx-problem.prg", type="prg", segments="Program"]
|
|
|
|
.segmentdef Program [segments="Basic, Code, Data"]
|
|
|
|
.segmentdef Basic [start=$0801]
|
|
|
|
.segmentdef Code [start=$80d]
|
|
|
|
.segmentdef Data [startAfter="Code"]
|
|
|
|
.segment Basic
|
2020-06-27 20:36:52 +00:00
|
|
|
:BasicUpstart(__start)
|
2021-06-19 19:26:05 +00:00
|
|
|
/// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
2020-04-27 22:30:35 +00:00
|
|
|
.const CIA_INTERRUPT_CLEAR = $7f
|
2021-06-20 10:45:52 +00:00
|
|
|
/// VICII IRQ Status/Enable Raster
|
|
|
|
// @see #IRQ_ENABLE #IRQ_STATUS
|
|
|
|
/// 0 | RST| Reaching a certain raster line. The line is specified by writing
|
|
|
|
/// | | to register 0xd012 and bit 7 of $d011 and internally stored by
|
|
|
|
/// | | the VIC for the raster compare. The test for reaching the
|
|
|
|
/// | | interrupt raster line is done in cycle 0 of every line (for line
|
|
|
|
/// | | 0, in cycle 1).
|
2020-04-30 20:15:59 +00:00
|
|
|
.const IRQ_RASTER = 1
|
2020-12-29 18:37:32 +00:00
|
|
|
.const VICII_SIZE = $30
|
2020-04-30 20:15:59 +00:00
|
|
|
.const IRQ_CHANGE_NEXT = $7f
|
|
|
|
.const OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
2021-06-20 10:45:52 +00:00
|
|
|
/// $D012 RASTER Raster counter
|
2019-03-21 21:24:39 +00:00
|
|
|
.label RASTER = $d012
|
2021-06-20 10:45:52 +00:00
|
|
|
/// $D011 Control Register #1
|
|
|
|
/// - Bit#0-#2: YSCROLL Screen Soft Scroll Vertical
|
|
|
|
/// - Bit#3: RSEL Switch betweem 25 or 24 visible rows
|
|
|
|
/// RSEL| Display window height | First line | Last line
|
|
|
|
/// ----+--------------------------+-------------+----------
|
|
|
|
/// 0 | 24 text lines/192 pixels | 55 ($37) | 246 ($f6)
|
|
|
|
/// 1 | 25 text lines/200 pixels | 51 ($33) | 250 ($fa)
|
|
|
|
/// - Bit#4: DEN Switch VIC-II output on/off
|
|
|
|
/// - Bit#5: BMM Turn Bitmap Mode on/off
|
|
|
|
/// - Bit#6: ECM Turn Extended Color Mode on/off
|
|
|
|
/// - Bit#7: RST8 9th Bit for $D012 Rasterline counter
|
|
|
|
/// Initial Value: %10011011
|
2021-02-07 15:14:44 +00:00
|
|
|
.label VICII_CONTROL1 = $d011
|
2021-06-19 19:26:05 +00:00
|
|
|
/// VIC II IRQ Status Register
|
2019-03-21 21:24:39 +00:00
|
|
|
.label IRQ_STATUS = $d019
|
2021-06-19 19:26:05 +00:00
|
|
|
/// VIC II IRQ Enable Register
|
2019-03-21 21:24:39 +00:00
|
|
|
.label IRQ_ENABLE = $d01a
|
2021-06-19 19:26:05 +00:00
|
|
|
/// The CIA#1: keyboard matrix, joystick #1/#2
|
2020-04-26 21:30:04 +00:00
|
|
|
.label CIA1 = $dc00
|
2021-06-19 19:26:05 +00:00
|
|
|
/// The vector used when the KERNAL serves IRQ interrupts
|
2019-03-21 21:24:39 +00:00
|
|
|
.label KERNEL_IRQ = $314
|
|
|
|
.label SCREEN = $400
|
2020-12-29 18:37:32 +00:00
|
|
|
.label VICII_BASE = $d000
|
2019-03-21 21:24:39 +00:00
|
|
|
.label irq_idx = 2
|
2020-12-21 07:57:41 +00:00
|
|
|
.segment Code
|
2020-06-27 20:36:52 +00:00
|
|
|
__start: {
|
2021-05-02 12:28:03 +00:00
|
|
|
// volatile byte irq_idx = 0
|
2020-06-27 18:32:09 +00:00
|
|
|
lda #0
|
|
|
|
sta.z irq_idx
|
|
|
|
jsr main
|
|
|
|
rts
|
|
|
|
}
|
2019-03-21 21:24:39 +00:00
|
|
|
table_driven_irq: {
|
2019-09-29 21:13:37 +00:00
|
|
|
__b1:
|
2021-05-02 12:28:03 +00:00
|
|
|
// byte idx = IRQ_CHANGE_IDX[irq_idx]
|
2019-08-07 19:00:19 +00:00
|
|
|
ldy.z irq_idx
|
2019-03-21 21:24:39 +00:00
|
|
|
lda IRQ_CHANGE_IDX,y
|
2021-05-02 12:28:03 +00:00
|
|
|
// byte val = IRQ_CHANGE_VAL[irq_idx]
|
2019-03-21 21:24:39 +00:00
|
|
|
ldx IRQ_CHANGE_VAL,y
|
2020-02-23 08:44:36 +00:00
|
|
|
// irq_idx++;
|
2019-08-07 19:00:19 +00:00
|
|
|
inc.z irq_idx
|
2020-12-29 18:37:32 +00:00
|
|
|
// if (idx < VICII_SIZE)
|
|
|
|
cmp #VICII_SIZE
|
2019-09-29 21:13:37 +00:00
|
|
|
bcc __b2
|
2020-12-29 18:37:32 +00:00
|
|
|
// if (idx < VICII_SIZE + 8)
|
|
|
|
cmp #VICII_SIZE+8
|
2019-09-29 21:13:37 +00:00
|
|
|
bcc __b3
|
2020-02-23 08:44:36 +00:00
|
|
|
// *IRQ_STATUS = IRQ_RASTER
|
2019-03-21 21:24:39 +00:00
|
|
|
lda #IRQ_RASTER
|
|
|
|
sta IRQ_STATUS
|
2020-02-23 08:44:36 +00:00
|
|
|
// *RASTER = val
|
2019-03-21 21:24:39 +00:00
|
|
|
stx RASTER
|
2020-02-23 08:44:36 +00:00
|
|
|
// if (val < *RASTER)
|
2019-03-21 21:24:39 +00:00
|
|
|
ldy RASTER
|
2019-08-07 19:00:19 +00:00
|
|
|
sty.z $ff
|
|
|
|
cpx.z $ff
|
2019-09-29 21:13:37 +00:00
|
|
|
bcc !__ea81+
|
2019-03-21 21:24:39 +00:00
|
|
|
jmp $ea81
|
2019-09-29 21:13:37 +00:00
|
|
|
!__ea81:
|
2020-02-23 08:44:36 +00:00
|
|
|
// irq_idx = 0
|
2019-03-21 21:24:39 +00:00
|
|
|
lda #0
|
2019-08-07 19:00:19 +00:00
|
|
|
sta.z irq_idx
|
2020-02-23 08:44:36 +00:00
|
|
|
// }
|
2019-03-21 21:24:39 +00:00
|
|
|
jmp $ea81
|
2019-09-29 21:13:37 +00:00
|
|
|
__b3:
|
2020-12-29 18:37:32 +00:00
|
|
|
// SCREEN[idx + $3f8 - VICII_SIZE] = val
|
2019-03-21 21:24:39 +00:00
|
|
|
tay
|
|
|
|
txa
|
2020-12-29 18:37:32 +00:00
|
|
|
sta SCREEN+-VICII_SIZE+$3f8,y
|
2019-09-29 21:13:37 +00:00
|
|
|
jmp __b1
|
|
|
|
__b2:
|
2020-12-29 18:37:32 +00:00
|
|
|
// VICII_BASE[idx] = val
|
2019-03-21 21:24:39 +00:00
|
|
|
tay
|
|
|
|
txa
|
2020-12-29 18:37:32 +00:00
|
|
|
sta VICII_BASE,y
|
2019-09-29 21:13:37 +00:00
|
|
|
jmp __b1
|
2020-06-27 21:26:57 +00:00
|
|
|
}
|
|
|
|
main: {
|
|
|
|
// asm
|
|
|
|
sei
|
|
|
|
// CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR
|
|
|
|
// Disable CIA 1 Timer IRQ
|
|
|
|
lda #CIA_INTERRUPT_CLEAR
|
|
|
|
sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT
|
2021-02-07 15:14:44 +00:00
|
|
|
// *VICII_CONTROL1 &=$7f
|
2020-06-27 21:26:57 +00:00
|
|
|
// Set raster line to $60
|
|
|
|
lda #$7f
|
2021-02-07 15:14:44 +00:00
|
|
|
and VICII_CONTROL1
|
|
|
|
sta VICII_CONTROL1
|
2020-06-27 21:26:57 +00:00
|
|
|
// *RASTER = $60
|
|
|
|
lda #$60
|
|
|
|
sta RASTER
|
|
|
|
// *IRQ_ENABLE = IRQ_RASTER
|
|
|
|
// Enable Raster Interrupt
|
|
|
|
lda #IRQ_RASTER
|
|
|
|
sta IRQ_ENABLE
|
|
|
|
// *IRQ_STATUS = IRQ_RASTER
|
|
|
|
// Acknowledge any IRQ
|
|
|
|
sta IRQ_STATUS
|
|
|
|
// *KERNEL_IRQ = &table_driven_irq
|
|
|
|
// Setup the table driven IRQ routine
|
|
|
|
lda #<table_driven_irq
|
|
|
|
sta KERNEL_IRQ
|
|
|
|
lda #>table_driven_irq
|
|
|
|
sta KERNEL_IRQ+1
|
|
|
|
// asm
|
|
|
|
cli
|
|
|
|
// }
|
|
|
|
rts
|
2019-03-21 21:24:39 +00:00
|
|
|
}
|
2020-12-21 07:57:41 +00:00
|
|
|
.segment Data
|
2019-03-21 21:24:39 +00:00
|
|
|
IRQ_CHANGE_IDX: .byte $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT
|
2019-11-03 16:05:55 +00:00
|
|
|
IRQ_CHANGE_VAL: .byte $b, $b, $63, 0, 0, $80, 7, 7, $83, 0, 0, $60
|