134 lines
2.3 KiB
ArmAsm
134 lines
2.3 KiB
ArmAsm
.MACPACK generic
|
|
|
|
.autoimport
|
|
|
|
.importzp tmp1, tmp2
|
|
|
|
.export _init_interrupt_controller
|
|
.export _enable_irq
|
|
.export _disable_irq
|
|
.export _send_eoi
|
|
|
|
IRQ_CMD_ADDR = $effc
|
|
IRQ_DAT_ADDR = $effd
|
|
|
|
IRQ_CMD_MASK = $e0
|
|
IRQ_REG_MASK = $1f
|
|
IRQ_CMD_READIRQ = $00
|
|
IRQ_CMD_ENABLE = $20
|
|
IRQ_CMD_TYPE = $40
|
|
IRQ_CMD_EOI = $ff
|
|
|
|
.code
|
|
|
|
; void init_irq();
|
|
; mask all IRQs, set all type to edge.
|
|
.proc _init_interrupt_controller
|
|
ldx #$20 ; enable
|
|
ldy #00
|
|
jsr cmd_all
|
|
ldx #$40 ; edge type
|
|
ldy #$00
|
|
jsr cmd_all
|
|
rts
|
|
|
|
cmd_all: ; Send the same value to all 32 bytes
|
|
txa
|
|
add #$10
|
|
sta tmp1
|
|
loop:
|
|
txa
|
|
sta IRQ_CMD_ADDR
|
|
tya
|
|
sta IRQ_DAT_ADDR
|
|
inx
|
|
cpx tmp1
|
|
blt loop
|
|
rts
|
|
.endproc
|
|
|
|
|
|
; void enable_irq(uint8_t type, uint8_t irqnum);
|
|
; in A:
|
|
.proc _enable_irq
|
|
; Decide which byte we need to modify by dividing by 8 (>> 3)
|
|
pha
|
|
lsr
|
|
lsr
|
|
lsr ; A is now bytesel
|
|
sta tmp2 ; tmp2 is now bytesel
|
|
add #IRQ_CMD_ENABLE
|
|
sta IRQ_CMD_ADDR
|
|
lda IRQ_DAT_ADDR
|
|
sta tmp1
|
|
pla
|
|
and #$07 ; A is now 0-7
|
|
tax
|
|
inx ; X is now 1-8
|
|
lda #$01
|
|
L1: dex
|
|
beq L2
|
|
asl
|
|
bra L1
|
|
L2: pha ; Push bit mask to stack
|
|
ora tmp1 ; A is now 1 << (0-7) | enable
|
|
sta IRQ_DAT_ADDR
|
|
|
|
|
|
lda tmp2
|
|
add #IRQ_CMD_TYPE
|
|
sta IRQ_CMD_ADDR
|
|
lda IRQ_DAT_ADDR
|
|
sta tmp1
|
|
jsr popa ; A is now type
|
|
beq bit0
|
|
bit1: ; set `bit` to 1
|
|
pla
|
|
ora tmp1
|
|
bra L3
|
|
bit0: ; set `bit` to 0
|
|
pla
|
|
eor #$ff
|
|
and tmp1
|
|
L3: sta IRQ_DAT_ADDR
|
|
rts
|
|
|
|
.endproc
|
|
|
|
; TODO this is mostly the same as enable, why copy?
|
|
.proc _disable_irq
|
|
; Decide which byte we need to modify by dividing by 32 (>> 5)
|
|
pha
|
|
lsr
|
|
lsr
|
|
lsr ; A is now bytesel
|
|
add #IRQ_CMD_ENABLE
|
|
sta IRQ_CMD_ADDR
|
|
lda IRQ_DAT_ADDR
|
|
sta tmp1
|
|
pla
|
|
and $07 ; A is now 0-7
|
|
tax
|
|
inx ; X is now 1-8
|
|
lda #$01
|
|
L1: dex
|
|
beq L2
|
|
asl
|
|
bra L1
|
|
L2: eor #$ff ; Invert to set enable to 0
|
|
and tmp1 ; a is now ~(1 << (0-7)) & enable
|
|
sta IRQ_DAT_ADDR
|
|
rts
|
|
.endproc
|
|
|
|
; This should accept irqnum later.
|
|
; void send_eoi();
|
|
.proc _send_eoi
|
|
lda #IRQ_CMD_EOI
|
|
sta IRQ_CMD_ADDR
|
|
lda #$1
|
|
sta IRQ_DAT_ADDR
|
|
rts
|
|
.endproc
|
|
|