reformatted assembler code

This commit is contained in:
Markus Fröschle
2014-05-11 14:08:27 +00:00
parent b0fb7b8df3
commit dc646c75ad
3 changed files with 512 additions and 583 deletions

View File

@@ -67,4 +67,5 @@ end
tr tr
ib ib
add-symbol-file ../emutos/emutos2.img 0xe00000
load firebee/ram.elf load firebee/ram.elf

View File

@@ -96,44 +96,45 @@
.equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt .equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt
.equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt .equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt
.equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt .equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt
.equ INT_SOURCE_PSC3,32 // PSC3 interrupt .equ INT_SOURCE_PSC3,32 // PSC3 interrupt
.equ INT_SOURCE_PSC2,33 // PSC2 interrupt .equ INT_SOURCE_PSC2,33 // PSC2 interrupt
.equ INT_SOURCE_PSC1,34 // PSC1 interrupt .equ INT_SOURCE_PSC1,34 // PSC1 interrupt
.equ INT_SOURCE_PSC0,35 // PSC0 interrupt .equ INT_SOURCE_PSC0,35 // PSC0 interrupt
.equ INT_SOURCE_CTIMERS,36 // combined source for comm timers .equ INT_SOURCE_CTIMERS,36 // combined source for comm timers
.equ INT_SOURCE_SEC,37 // SEC interrupt .equ INT_SOURCE_SEC,37 // SEC interrupt
.equ INT_SOURCE_FEC1,38 // FEC1 interrupt .equ INT_SOURCE_FEC1,38 // FEC1 interrupt
.equ INT_SOURCE_FEC0,39 // FEC0 interrupt .equ INT_SOURCE_FEC0,39 // FEC0 interrupt
.equ INT_SOURCE_I2C,40 // I2C interrupt .equ INT_SOURCE_I2C,40 // I2C interrupt
.equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt .equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt
.equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt .equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt
.equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt .equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt
.equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt .equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt
.equ INT_SOURCE_DMA,48 // multichannel DMA interrupt .equ INT_SOURCE_DMA,48 // multichannel DMA interrupt
.equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt .equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt
.equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt .equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt
.equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt .equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt
.equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt .equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt
.equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt .equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt
.equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt .equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt
.equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt .equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt
.equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt .equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt
.equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt .equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt
.equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt .equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt
.equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt .equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt
.equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt .equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt
// Atari register equates (provided by FPGA) // Atari register equates (provided by FPGA)
.equ vbasehi, 0xffff8201 .equ vbasehi, 0xffff8201
//mmu ---------------------------------------------------
/* Register read/write macros */ /* MMU register read/write macros */
#define MCF_MMU_MMUCR __MMUBAR
#define MCF_MMU_MMUOR __MMUBAR+0x04 #define MCF_MMU_MMUCR __MMUBAR
#define MCF_MMU_MMUSR __MMUBAR+0x08 #define MCF_MMU_MMUOR __MMUBAR+0x04
#define MCF_MMU_MMUAR __MMUBAR+0x10 #define MCF_MMU_MMUSR __MMUBAR+0x08
#define MCF_MMU_MMUTR __MMUBAR+0x14 #define MCF_MMU_MMUAR __MMUBAR+0x10
#define MCF_MMU_MMUDR __MMUBAR+0x18 #define MCF_MMU_MMUTR __MMUBAR+0x14
#define MCF_MMU_MMUDR __MMUBAR+0x18
/* Bit definitions and macros for MCF_MMU_MMUCR */ /* Bit definitions and macros for MCF_MMU_MMUCR */
@@ -198,8 +199,8 @@
subq.l #8,a7 subq.l #8,a7
movem.l d0/a5,(a7) // save registers movem.l d0/a5,(a7) // save registers
lea MCF_EPORT_EPFR,a5 lea MCF_EPORT_EPFR,a5
move.b #\clr_int,(a5) // clear int pending move.b #\clr_int,(a5) // clear int pending
movem.l (a7),d0/a5 // restore registers movem.l (a7),d0/a5 // restore registers
addq.l #8,a7 addq.l #8,a7
@@ -223,74 +224,74 @@
* If anybody knows of any better way on how to do this - please do! * If anybody knows of any better way on how to do this - please do!
* *
*/ */
.macro mchar st,a,b,c,d,tgt .macro mchar st,a,b,c,d,tgt
\st #\a << 24|\b<<16|\c<<8|\d,\tgt \st #\a << 24|\b<<16|\c<<8|\d,\tgt
.endm .endm
.text .text
_vec_init: _vec_init:
move.l a2,-(sp) // Backup registers move.l a2,-(sp) // Backup registers
mov3q.l #-1,_rt_mod // rt_mod auf super mov3q.l #-1,_rt_mod // rt_mod auf super
clr.l _rt_ssp clr.l _rt_ssp
clr.l _rt_usp clr.l _rt_usp
clr.l _rt_vbr clr.l _rt_vbr
move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 move.l #__RAMBAR0,d0 // exception vectors reside in rambar0
movec d0,VBR movec d0,VBR
move.l d0,a0 move.l d0,a0
move.l a0,a2 move.l a0,a2
init_vec: init_vec:
move.l #256,d0 move.l #256,d0
lea std_exc_vec(pc),a1 // standard vector lea std_exc_vec(pc),a1 // standard vector
init_vec_loop: init_vec_loop:
move.l a1,(a2)+ // set standard vector for all exceptions move.l a1,(a2)+ // set standard vector for all exceptions
subq.l #1,d0 subq.l #1,d0
bne init_vec_loop bne init_vec_loop
move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table
lea reset_vector(pc),a1 // set reset vector lea reset_vector(pc),a1 // set reset vector
move.l a1,0x04(a0) move.l a1,0x04(a0)
lea access_exception(pc),a1 // set illegal access exception handler lea access_exception(pc),a1 // set illegal access exception handler
move.l a1,0x08(a0) move.l a1,0x08(a0)
.extern _get_bas_drivers .extern _get_bas_drivers
// trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS // trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS
lea _get_bas_drivers(pc),a1 lea _get_bas_drivers(pc),a1
move.l a1,0x80(a0) // trap #0 exception vector move.l a1,0x80(a0) // trap #0 exception vector
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
// ACP interrupts 1-7 (user-defined, generated by FPGA on the FireBee, M5484LITE has irq7 and irq5 for PCI) // ACP interrupts 1-7 (user-defined, generated by FPGA on the FireBee, M5484LITE has irq7 and irq5 for PCI)
lea irq1(pc),a1 lea irq1(pc),a1
move.l a1,0x104(a0) move.l a1,0x104(a0)
lea irq2(pc),a1 lea irq2(pc),a1
move.l a1,0x108(a0) move.l a1,0x108(a0)
lea irq3(pc),a1 lea irq3(pc),a1
move.l a1,0x10c(a0) move.l a1,0x10c(a0)
lea irq4(pc),a1 lea irq4(pc),a1
move.l a1,0x110(a0) move.l a1,0x110(a0)
lea irq5(pc),a1 lea irq5(pc),a1
move.l a1,0x114(a0) move.l a1,0x114(a0)
lea irq6(pc),a1 lea irq6(pc),a1
move.l a1,0x118(a0) move.l a1,0x118(a0)
lea irq7(pc),a1 lea irq7(pc),a1
move.l a1,0x11c(a0) move.l a1,0x11c(a0)
// install PSC vectors (used for PIC communication on the FireBee) // install PSC vectors (used for PIC communication on the FireBee)
lea handler_psc3(pc),a1 lea handler_psc3(pc),a1
// PSC3 interrupt source = 32 // PSC3 interrupt source = 32
move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0)
// timer vectors (triggers when vbashi gets changed, used for video page copy) // timer vectors (triggers when vbashi gets changed, used for video page copy)
lea handler_gpt0(pc),a1 lea handler_gpt0(pc),a1
// GPT0 interrupt source = 62 // GPT0 interrupt source = 62
move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0)
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
// install lowlevel_isr_handler for the three GPT timers // install lowlevel_isr_handler for the three GPT timers
lea _lowlevel_isr_handler(pc),a1 lea _lowlevel_isr_handler(pc),a1
move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0)
move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0)
move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0)
@@ -308,6 +309,8 @@ init_vec_loop:
move.l (sp)+,a2 // Restore registers move.l (sp)+,a2 // Restore registers
rts rts
/* /*
* exception vector routines * exception vector routines
*/ */
@@ -322,8 +325,8 @@ std_exc_vec:
#ifdef DBG_EXC #ifdef DBG_EXC
// printout vector number of exception // printout vector number of exception
lea -4 * 4(sp),sp // reserve stack space lea -4 * 4(sp),sp // reserve stack space
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
lsr.l #2,d0 // shift vector number in place lsr.l #2,d0 // shift vector number in place
cmp.l #33,d0 cmp.l #33,d0
@@ -334,15 +337,15 @@ std_exc_vec:
beq noprint beq noprint
cmp.l #46,d0 cmp.l #46,d0
beq noprint beq noprint
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
move.l d0,-(sp) // provide it to xprintf() move.l d0,-(sp) // provide it to xprintf()
pea exception_text pea exception_text
jsr _xprintf // call xprintf() jsr _xprintf // call xprintf()
add.l #3*4,sp // adjust stack add.l #3*4,sp // adjust stack
noprint: noprint:
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
lea 4 * 4(sp),sp lea 4 * 4(sp),sp
#endif /* DBG_EXC */ #endif /* DBG_EXC */
add.l _rt_vbr,d0 // + VBR add.l _rt_vbr,d0 // + VBR
@@ -356,7 +359,7 @@ noprint:
bset #13,d0 // set supervisor bit bset #13,d0 // set supervisor bit
move.w d0,sr // move.w d0,sr //
move.l (a7)+,d0 // restore d0 move.l (a7)+,d0 // restore d0
rts // jump to exception routine rts // jump to exception routine
exception_text: exception_text:
.ascii "DEBUG: EXCEPTION %d caught at %p" .ascii "DEBUG: EXCEPTION %d caught at %p"
@@ -367,8 +370,8 @@ reset_vector:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
move.l #0x31415926,d0 move.l #0x31415926,d0
cmp.l 0x426,d0 // _resvalid: reset vector valid? cmp.l 0x426,d0 // _resvalid: reset vector valid?
beq std_exc_vec // yes-> beq std_exc_vec // yes->
jmp _rom_entry // no, cold start machine jmp _rom_entry // no, cold start machine
// //
// Triggered when code tries to access a memory area that is not known to the MMU yet. // Triggered when code tries to access a memory area that is not known to the MMU yet.
@@ -376,32 +379,32 @@ reset_vector:
// //
access_exception: access_exception:
move.w #0x2700,sr // avoid us being interrupted by the video handler move.w #0x2700,sr // avoid us being interrupted by the video handler
// (this would probably overwrite the MMUAR register) // (this would probably overwrite the MMUAR register)
// save gcc scratch registers, others will be handled by called function // save gcc scratch registers, others will be handled by called function
lea -4*4(sp),sp lea -4*4(sp),sp
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
lea 4*4(sp),a0 // original stack pointer lea 4*4(sp),a0 // original stack pointer
move.l (a0),-(sp) // format status word move.l (a0),-(sp) // format status word
move.l 4(a0),-(sp) // program counter at access error move.l 4(a0),-(sp) // program counter at access error
jsr _access_exception // note the underscore jsr _access_exception // note the underscore
lea 2*4(sp),sp // adjust stack lea 2*4(sp),sp // adjust stack
tst.l d0 // handled? tst.l d0 // handled?
movem.l (sp),d0-d1/a0-a1 // restore scratch registers movem.l (sp),d0-d1/a0-a1 // restore scratch registers
lea 4*4(sp),sp lea 4*4(sp),sp
beq bus_error // no beq bus_error // no
rte rte
bus_error: bus_error:
bra std_exc_vec bra std_exc_vec
zero_divide: zero_divide:
move.l a0,-(a7) move.l a0,-(a7)
@@ -409,23 +412,23 @@ zero_divide:
move.l 12(a7),a0 // pc move.l 12(a7),a0 // pc
move.w (a0)+,d0 // command word move.w (a0)+,d0 // command word
btst #7,d0 // long? btst #7,d0 // long?
beq zd_word // nein-> beq zd_word // nein->
addq.l #2,a0 addq.l #2,a0
zd_word: zd_word:
and.l 0x3f,d0 // mask out ea field and.l 0x3f,d0 // mask out ea field
cmp.w #0x08,d0 // -(ax) or less? cmp.w #0x08,d0 // -(ax) or less?
ble zd_end ble zd_end
addq.l #2,a0 addq.l #2,a0
cmp.w #0x39,d0 // xxx.L cmp.w #0x39,d0 // xxx.L
bne zd_nal bne zd_nal
addq.l #2,a0 addq.l #2,a0
bra zd_end bra zd_end
zd_nal: cmp.w #0x3c,d0 // immediate? zd_nal: cmp.w #0x3c,d0 // immediate?
bne zd_end // no-> bne zd_end // no->
btst #7,d0 // long? btst #7,d0 // long?
beq zd_end // no beq zd_end // no
addq.l #2,a0 addq.l #2,a0
zd_end: zd_end:
move.l a0,12(a7) move.l a0,12(a7)
@@ -434,88 +437,88 @@ zd_end:
rte rte
irq1: irq1:
irq 0x64,1,0x02 irq 0x64,1,0x02
irq2: // hbl irq2: // hbl
// move.b #3,2(a7) // move.b #3,2(a7)
// rte // rte
irq 0x68,2,0x04 irq 0x68,2,0x04
irq3: irq3:
irq 0x6c,3,0x08 irq 0x6c,3,0x08
irq4: // vbl irq4: // vbl
irq 0x70,4,0x10 irq 0x70,4,0x10
#if MACHINE_M5484LITE // handlers for M5484LITE #if MACHINE_M5484LITE // handlers for M5484LITE
irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
lea -4*4(sp),sp // save gcc scratch registers lea -4*4(sp),sp // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
jsr _irq5_handler // call C handler routine jsr _irq5_handler // call C handler routine
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
lea 4*4(sp),sp lea 4*4(sp),sp
rte // return from exception rte // return from exception
irq5text: irq5text:
.ascii "IRQ5!" .ascii "IRQ5!"
.dc.b 13,10,0 .dc.b 13,10,0
irq6: irq6:
irq 0x74,5,0x20 irq 0x74,5,0x20
irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
lea -4*4(sp),sp // save gcc scratch registers lea -4*4(sp),sp // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
jsr _irq7_handler // call C handler routine jsr _irq7_handler // call C handler routine
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
lea 4*4(sp),sp lea 4*4(sp),sp
rte // return from exception rte // return from exception
irq7text: irq7text:
.ascii "IRQ7!" .ascii "IRQ7!"
.dc.b 13,10,0 .dc.b 13,10,0
#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ #elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */
irq5: irq5:
irq 0x74,5,0x20 irq 0x74,5,0x20
.extern _irq6_interrupt_handler // highlevel C handler .extern _irq6_interrupt_handler // highlevel C handler
irq6: // MFP interrupt from FPGA irq6: // MFP interrupt from FPGA
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
lea -4 * 4(sp),sp // save gcc scratch registers lea -4 * 4(sp),sp // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
move.l 4 * 4(sp),-(sp) // push original exception stack frame move.l 4 * 4(sp),-(sp) // push original exception stack frame
move.l 5 * 4(sp),-(sp) move.l 5 * 4(sp),-(sp)
jsr _irq6_interrupt_handler // call highlevel C handler jsr _irq6_interrupt_handler // call highlevel C handler
lea.l 2 * 4(sp),sp lea.l 2 * 4(sp),sp
tst.l d0 // completely handled? tst.l d0 // completely handled?
movem.l (sp),d0-d1/a0-a1 // restore registers saved above movem.l (sp),d0-d1/a0-a1 // restore registers saved above
lea 4 * 4(sp),sp // adjust stack lea 4 * 4(sp),sp // adjust stack
beq irq6_os // call OS handler beq irq6_os // call OS handler
rte rte
irq6_os: // call native OS irq6 handler irq6_os: // call native OS irq6 handler
move.l a5,-(sp) // save registers: TODO: this could be done more effective move.l a5,-(sp) // save registers: TODO: this could be done more effective
move.l d0,-(sp) move.l d0,-(sp)
move.l 0xf0020000,a5 // fetch vector move.l 0xf0020000,a5 // fetch vector
add.l _rt_vbr,a5 // add vector base add.l _rt_vbr,a5 // add vector base
move.l (a5),d0 // fetch handler move.l (a5),d0 // fetch handler
move.l 4(sp),a5 // restore a5 move.l 4(sp),a5 // restore a5
@@ -524,60 +527,60 @@ irq6_os: // call native OS irq6 handler
move.w #0x2600,sr // set interrupt mask move.w #0x2600,sr // set interrupt mask
rts rts
#ifdef _NOT_USED_ #ifdef _NOT_USED_ /* functionality moved to _irq6_interrupt_handler() (C) */
subq.l #8,a7 subq.l #8,a7
movem.l d0/a5,(a7) // save registers movem.l d0/a5,(a7) // save registers
lea MCF_EPORT_EPFR,a5 // clear int6 from edge port lea MCF_EPORT_EPFR,a5 // clear int6 from edge port
bset #6,(a5) bset #6,(a5)
// there was a potential bug here before: would also clear all other edge port interrupts that might have happened... // there was a potential bug here before: would also clear all other edge port interrupts that might have happened...
// move.b #0x40,(a5) // clear int6 from edge port // move.b #0x40,(a5) // clear int6 from edge port
// screen adr change timed out? // screen adr change timed out?
move.l _video_sbt,d0 move.l _video_sbt,d0
beq irq6_non_sca // nothing to do if 0 beq irq6_non_sca // nothing to do if 0
sub.l #0x70000000,d0 // substract 14 seconds sub.l #0x70000000,d0 // substract 14 seconds
lea MCF_SLT0_SCNT,a5 lea MCF_SLT0_SCNT,a5
cmp.l (a5),d0 // time reached? cmp.l (a5),d0 // time reached?
ble irq6_non_sca // not yet ble irq6_non_sca // not yet
lea -28(a7),a7 // save more registers lea -28(a7),a7 // save more registers
movem.l d0-d4/a0-a1,(a7) // movem.l d0-d4/a0-a1,(a7) //
clr.l d3 // beginn mit 0 clr.l d3 // beginn mit 0
jsr _flush_and_invalidate_caches jsr _flush_and_invalidate_caches
// eintrag suchen // eintrag suchen
irq6_next_sca: irq6_next_sca:
move.l d3,d0 move.l d3,d0
move.l d0,MCF_MMU_MMUAR // addresse move.l d0,MCF_MMU_MMUAR // addresse
move.l #0x106,d4 move.l #0x106,d4
move.l d4,MCF_MMU_MMUOR // suchen -> move.l d4,MCF_MMU_MMUOR // suchen ->
nop nop
move.l MCF_MMU_MMUOR,d4 move.l MCF_MMU_MMUOR,d4
clr.w d4 clr.w d4
swap d4 swap d4
move.l d4,MCF_MMU_MMUAR move.l d4,MCF_MMU_MMUAR
mvz.w #0x10e,d4 mvz.w #0x10e,d4
move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu
nop nop
move.l MCF_MMU_MMUTR,d4 // ID holen move.l MCF_MMU_MMUTR,d4 // ID holen
lsr.l #2,d4 // bit 9 bis 2 lsr.l #2,d4 // bit 9 bis 2
cmp.w #sca_page_ID,d4 // ist screen change ID? cmp.w #sca_page_ID,d4 // ist screen change ID?
bne irq6_sca_pn // nein -> page keine screen area next bne irq6_sca_pn // nein -> page keine screen area next
// eintrag <EFBFBD>ndern // eintrag <EFBFBD>ndern
add.l #std_mmutr,d0 add.l #std_mmutr,d0
move.l d3,d1 // page 0? move.l d3,d1 // page 0?
beq irq6_sca_pn0 // ja -> beq irq6_sca_pn0 // ja ->
add.l #copyback_mmudr,d1 // sonst page cb add.l #copyback_mmudr,d1 // sonst page cb
bra irq6_sca_pn1c bra irq6_sca_pn1c
irq6_sca_pn0: irq6_sca_pn0:
add.l #writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked add.l #writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked
irq6_sca_pn1c: irq6_sca_pn1c:
mvz.w #0x10b,d2 // MMU update mvz.w #0x10b,d2 // MMU update
move.l d0,MCF_MMU_MMUTR move.l d0,MCF_MMU_MMUTR
move.l d1,MCF_MMU_MMUDR move.l d1,MCF_MMU_MMUDR
move.l d2,MCF_MMU_MMUOR // setze tlb data only move.l d2,MCF_MMU_MMUOR // setze tlb data only
nop nop
// page copy // page copy
move.l d3,a0 move.l d3,a0
@@ -585,91 +588,51 @@ irq6_sca_pn1c:
move.l d3,a1 move.l d3,a1
move.l #0x10000,d4 // one whole page (1 MB) move.l #0x10000,d4 // one whole page (1 MB)
#define _DO_CPU_COPY
#ifndef _DO_CPU_COPY
// experiment: do video page copy using Coldfire DMA
lea -15 * 4(sp),sp
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
clr.l -(sp) // no special functions
move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp)
mov3q #7,-(sp) // highest DMA priority
move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA
move.l #1,-(sp) // copy 4 bytes at a time
move.l #0x100000,-(sp) // copy 1 Megabyte
move.l #4,-(sp) // destination increment
move.l a1,-(sp) // destination adress
move.l #4,-(sp) // source increment
move.l a0,-(sp) // source adress
move.l #1,-(sp) // channel 1
jsr _MCD_startDma
movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers
lea 15 * 4(sp),sp // adjust stack
wait_dma_finished:
clr.l -(sp)
jsr _MCD_dmaStatus
addq.l #4,sp
tst.l d0
cmp.l #6,d0
bne wait_dma_finished
#else
irq6_vcd0_loop:
move.l (a0)+,(a1)+ // page copy
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
subq.l #1,d4
bne irq6_vcd0_loop
#endif /* _DO_CPU_COPY */
irq6_sca_pn: irq6_sca_pn:
add.l #0x00100000,d3 // next add.l #0x00100000,d3 // next
cmp.l #0x00d00000,d3 // ende? cmp.l #0x00d00000,d3 // ende?
blt irq6_next_sca // nein-> blt irq6_next_sca // nein->
move.l #0x2000,d0 move.l #0x2000,d0
move.l d0,_video_tlb // anfangszustand wieder herstellen move.l d0,_video_tlb // anfangszustand wieder herstellen
clr.l _video_sbt // zeit löschen clr.l _video_sbt // zeit löschen
movem.l (sp),d0-d4/a0-a1 // restore registers movem.l (sp),d0-d4/a0-a1 // restore registers
lea 7 * 4(sp),sp lea 7 * 4(sp),sp
irq6_non_sca: irq6_non_sca:
// test auf acsi dma ----------------------------------------------------------------- // test auf acsi dma -----------------------------------------------------------------
lea 0xfffffa0b,a5 lea 0xfffffa0b,a5
bset #7,-4(a5) // int ena bset #7,-4(a5) // int ena
btst.b #7,(a5) // acsi dma int? btst.b #7,(a5) // acsi dma int?
beq non_acsi_dma beq non_acsi_dma
bsr acsi_dma bsr acsi_dma
non_acsi_dma: non_acsi_dma:
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
tst.b (a5) tst.b (a5)
bne irq6_1 bne irq6_1
tst.b 2(a5) tst.b 2(a5)
bne irq6_1 bne irq6_1
movem.l (a7),d0/a5 movem.l (a7),d0/a5
addq.l #8,a7 addq.l #8,a7
rte rte
irq6_1: irq6_1:
lea MCF_GPIO_PODR_FEC1L,a5 lea MCF_GPIO_PODR_FEC1L,a5
bclr.b #4,(a5) // led on bclr.b #4,(a5) // led on
lea blinker,a5 lea blinker,a5
addq.l #1,(a5) // +1 addq.l #1,(a5) // +1
move.l (a5),d0 move.l (a5),d0
and.l #0x80,d0 and.l #0x80,d0
bne irq6_2 bne irq6_2
lea MCF_GPIO_PODR_FEC1L,a5 lea MCF_GPIO_PODR_FEC1L,a5
bset.b #4,(a5) // led off bset.b #4,(a5) // led off
irq6_2: irq6_2:
move.l 0xf0020000,a5 // vector holen move.l 0xf0020000,a5 // vector holen
add.l _rt_vbr,a5 // basis add.l _rt_vbr,a5 // basis
move.l (a5),d0 // vector holen move.l (a5),d0 // vector holen
move.l 4(a7),a5 // a5 zurück move.l 4(a7),a5 // a5 zurück
move.l d0,4(a7) // vector eintragen move.l d0,4(a7) // vector eintragen
move.l (a7)+,d0 // d0 zurück move.l (a7)+,d0 // d0 zurück
move #0x2600,sr move #0x2600,sr
rts rts
@@ -677,7 +640,7 @@ irq6_2:
blinker:.long 0 blinker:.long 0
.text .text
/* /*
* pseudo dma * pseudo dma
@@ -700,29 +663,29 @@ acsi_dma_start:
btst.b #0,-16(a5) // write? (dma modus reg) btst.b #0,-16(a5) // write? (dma modus reg)
bne acsi_dma_wl // ja-> bne acsi_dma_wl // ja->
acsi_dma_rl: acsi_dma_rl:
tst.b -4(a5) // dma req? tst.b -4(a5) // dma req?
bpl acsi_dma_finished // nein-> bpl acsi_dma_finished // nein->
move.l (a5),(a1)+ // read 4 bytes move.l (a5),(a1)+ // read 4 bytes
move.l (a5),(a1)+ // read 4 bytes move.l (a5),(a1)+ // read 4 bytes
move.l (a5),(a1)+ // read 4 bytes move.l (a5),(a1)+ // read 4 bytes
move.l (a5),(a1)+ // read 4 bytes move.l (a5),(a1)+ // read 4 bytes
moveq #'.',d1 moveq #'.',d1
move.b d1,MCF_PSC0_PSCTB_8BIT move.b d1,MCF_PSC0_PSCTB_8BIT
sub.l #16,d0 // byt counter -16 sub.l #16,d0 // byt counter -16
bpl acsi_dma_rl bpl acsi_dma_rl
bra acsi_dma_finished bra acsi_dma_finished
acsi_dma_wl: acsi_dma_wl:
tst.b -4(a5) // dma req? tst.b -4(a5) // dma req?
bpl acsi_dma_finished // nein-> bpl acsi_dma_finished // nein->
move.l (a1)+,(a5) // write 4 byts move.l (a1)+,(a5) // write 4 byts
move.l (a1)+,(a5) // write 4 byts move.l (a1)+,(a5) // write 4 byts
move.l (a1)+,(a5) // write 4 byts move.l (a1)+,(a5) // write 4 byts
move.l (a1)+,(a5) // write 4 byts move.l (a1)+,(a5) // write 4 byts
moveq #'.',d1 moveq #'.',d1
move.b d1,MCF_PSC0_PSCTB_8BIT move.b d1,MCF_PSC0_PSCTB_8BIT
sub.l #16,d0 // byt counter -16 sub.l #16,d0 // byt counter -16
bpl acsi_dma_wl bpl acsi_dma_wl
@@ -730,11 +693,11 @@ acsi_dma_finished:
move.l a1,-12(a5) // adresse zur<EFBFBD>ck move.l a1,-12(a5) // adresse zur<EFBFBD>ck
move.l d0,-8(a5) // byt counter zur<EFBFBD>ck move.l d0,-8(a5) // byt counter zur<EFBFBD>ck
acsi_dma_end: acsi_dma_end:
tst.b -4(a5) // dma req? tst.b -4(a5) // dma req?
bmi acsi_dma_start // ja-> bmi acsi_dma_start // ja->
lea 0xfffffa0b,a5 lea 0xfffffa0b,a5
bclr.b #7,4(a5) // clear int in service mfp bclr.b #7,4(a5) // clear int in service mfp
bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b
move.w #0x0d0a,d1 move.w #0x0d0a,d1
move.w d1,MCF_PSC0_PSCTB_8BIT move.w d1,MCF_PSC0_PSCTB_8BIT
@@ -744,14 +707,15 @@ acsi_dma_end:
rts rts
#endif /* _NOT_USED_ */ #endif /* _NOT_USED_ */
/* /*
* irq 7 = pseudo bus error * irq 7 = pseudo bus error
*/ */
irq7: irq7:
lea -12(sp),sp lea -12(sp),sp
movem.l d0/a0,(sp) movem.l d0/a0,(sp)
move.l __RAMBAR0+0x008,a0 // real access error handler move.l __RAMBAR0+0x008,a0 // real access error handler
move.l a0,8(sp) // this will be the return address for rts move.l a0,8(sp) // this will be the return address for rts
move.w 12(sp),d0 // format/vector word move.w 12(sp),d0 // format/vector word
@@ -773,15 +737,15 @@ irq7:
* psc3 com PIC MCF * psc3 com PIC MCF
*/ */
handler_psc3: handler_psc3:
.extern _pic_interrupt_handler .extern _pic_interrupt_handler
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
lea -4 * 4(sp),sp // save gcc scratch registers lea -4 * 4(sp),sp // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
jsr _pic_interrupt_handler // call high level interrupt handler jsr _pic_interrupt_handler // call high level interrupt handler
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
rte rte
/* /*
@@ -790,41 +754,41 @@ handler_psc3:
* vbasehi is written to, i.e. when the video base address gets changed * vbasehi is written to, i.e. when the video base address gets changed
*/ */
handler_gpt0: handler_gpt0:
move #0x2700,sr // disable interrupts move #0x2700,sr // disable interrupts
lea -28(a7),a7 // save registers lea -28(a7),a7 // save registers
movem.l d0-d4/a0-a1,(a7) movem.l d0-d4/a0-a1,(a7)
mvz.b vbasehi,d0 // screen base address high mvz.b vbasehi,d0 // screen base address high
cmp.w #2,d0 // screen base lower than 0x20000? cmp.w #2,d0 // screen base lower than 0x20000?
blt video_chg_end // yes, do nothing blt video_chg_end // yes, do nothing
cmp.w #0xd0,d0 // lower than 0xd00000? - normal Falcon video area, mapped cmp.w #0xd0,d0 // lower than 0xd00000? - normal Falcon video area, mapped
// to 60d00000 (FPGA video memory) // to 60d00000 (FPGA video memory)
blt sca_other // blt sca_other
lea MCF_SLT0_SCNT,a0 lea MCF_SLT0_SCNT,a0
move.l (a0),_video_sbt // save time move.l (a0),_video_sbt // save time
bra video_chg_end bra video_chg_end
// FIXME: don't we need to get out here? // FIXME: don't we need to get out here?
sca_other: sca_other:
lsl.l #8,d0 // build new screen start address from Atari register contents lsl.l #8,d0 // build new screen start address from Atari register contents
move.b 0xffff8203,d0 // mid byte move.b 0xffff8203,d0 // mid byte
lsl.l #8,d0 lsl.l #8,d0
move.b 0xffff820d,d0 // low byte move.b 0xffff820d,d0 // low byte
move.l d0,d3 move.l d0,d3
video_chg_1page: video_chg_1page:
// check if page is already marked as video page // check if page is already marked as video page
moveq #20,d4 moveq #20,d4
move.l d0,d2 move.l d0,d2
lsr.l d4,d2 // new page lsr.l d4,d2 // new page
move.l _video_tlb,d4 move.l _video_tlb,d4
bset.l d2,d4 // set as changed bset.l d2,d4 // set as changed
bne video_chg_2page // was it set already? bne video_chg_2page // was it set already?
move.l d4,_video_tlb move.l d4,_video_tlb
jsr _flush_and_invalidate_caches jsr _flush_and_invalidate_caches
video_copy_data: video_copy_data:
move.l d4,_video_tlb move.l d4,_video_tlb
@@ -832,94 +796,59 @@ video_copy_data:
move.l d0,a0 move.l d0,a0
move.l a0,a1 move.l a0,a1
add.l #0x60000000,a1 add.l #0x60000000,a1
move.l #0x10000,d4 // whole page move.l #0x10000,d4 // whole page
#define _DO_CPU_COPY
#ifndef _DO_CPU_COPY
// experiment: do video page copy using Coldfire DMA
lea -4 * 4(sp),sp
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
clr.l -(sp) // no special functions
move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp)
mov3q #7,-(sp) // highest DMA priority
move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA
move.l #1,-(sp) // copy 4 bytes at a time
move.l #0x100000,-(sp) // copy 1 Megabyte
move.l #4,-(sp) // destination increment
move.l a1,-(sp) // destination adress
move.l #4,-(sp) // source increment
move.l a0,-(sp) // source adress
move.l #1,-(sp) // channel 1
jsr _MCD_startDma
.wait_dma_finished:
clr.l -(sp)
jsr _MCD_dmaStatus
addq.l #4,sp
tst.l d0
cmp.l #6,d0
bne .wait_dma_finished
movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers
lea 4 * 4(sp),sp // adjust stack
#else
video_copy_data_loop: video_copy_data_loop:
move.l (a0)+,(a1)+ // copy video page contents to real screen move.l (a0)+,(a1)+ // copy video page contents to real screen
move.l (a0)+,(a1)+ move.l (a0)+,(a1)+
move.l (a0)+,(a1)+ move.l (a0)+,(a1)+
move.l (a0)+,(a1)+ move.l (a0)+,(a1)+
subq.l #1,d4 subq.l #1,d4
bne video_copy_data_loop bne video_copy_data_loop
#endif
// eintrag suchen // eintrag suchen
move.l d0,MCF_MMU_MMUAR // adress move.l d0,MCF_MMU_MMUAR // adress
move.l #0x106,d4 move.l #0x106,d4
move.l d4,MCF_MMU_MMUOR // search -> new one will be offered if not found move.l d4,MCF_MMU_MMUOR // search -> new one will be offered if not found
nop nop
move.l MCF_MMU_MMUOR,d4 move.l MCF_MMU_MMUOR,d4
clr.w d4 clr.w d4
swap d4 swap d4
move.l d4,MCF_MMU_MMUAR move.l d4,MCF_MMU_MMUAR
move.l d0,d1 move.l d0,d1
add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0 add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1
mvz.w #0x10b,d2 // MMU update mvz.w #0x10b,d2 // MMU update
move.l d0,MCF_MMU_MMUTR move.l d0,MCF_MMU_MMUTR
move.l d1,MCF_MMU_MMUDR move.l d1,MCF_MMU_MMUDR
move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data
nop nop
video_chg_2page: video_chg_2page:
// test of adjacent page is needed also // test of adjacent page is needed also
move.l d3,d0 move.l d3,d0
mvz.w 0xffff8210,d4 // byts pro zeile mvz.w 0xffff8210,d4 // byts pro zeile
mvz.w 0xffff82aa,d2 // zeilen ende mvz.w 0xffff82aa,d2 // zeilen ende
mvz.w 0xffff82a8,d1 // zeilenstart mvz.w 0xffff82a8,d1 // zeilenstart
sub.l d1,d2 // differenz = anzahl zeilen sub.l d1,d2 // differenz = anzahl zeilen
mulu d2,d4 // maximal 480 zeilen mulu d2,d4 // maximal 480 zeilen
add.l d4,d0 // video gr<EFBFBD>sse add.l d4,d0 // video gr<EFBFBD>sse
cmp.l #__STRAM_END,d0 // maximale addresse cmp.l #__STRAM_END,d0 // maximale addresse
bge video_chg_end // wenn gleich oder gr<EFBFBD>sser -> fertig bge video_chg_end // wenn gleich oder gr<EFBFBD>sser -> fertig
moveq #20,d4 moveq #20,d4
move.l d0,d2 move.l d0,d2
lsr.l d4,d2 // neue page lsr.l d4,d2 // neue page
move.l _video_tlb,d4 move.l _video_tlb,d4
bset.l d2,d4 // setzen als ge<EFBFBD>ndert bset.l d2,d4 // setzen als ge<EFBFBD>ndert
beq video_copy_data // nein nochmal beq video_copy_data // nein nochmal
video_chg_end: video_chg_end:
lea MCF_GPT0_GMS,a0 // clear interrupt lea MCF_GPT0_GMS,a0 // clear interrupt
bclr.b #0,3(a0) bclr.b #0,3(a0)
nop nop
bset.b #0,3(a0) bset.b #0,3(a0)
movem.l (a7),d0-d4/a0-a1 // restore saved registers movem.l (a7),d0-d4/a0-a1 // restore saved registers
lea 7 * 4(sp),a7 lea 7 * 4(sp),a7
rte rte
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
@@ -927,22 +856,20 @@ video_chg_end:
* low-level interrupt service routine for routines registered with * low-level interrupt service routine for routines registered with
* isr_register_handler() * isr_register_handler()
*/ */
.global _lowlevel_isr_handler .global _lowlevel_isr_handler
.extern _isr_execute_handler .extern _isr_execute_handler
_lowlevel_isr_handler: _lowlevel_isr_handler:
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
link a6,#-4*4 // make room for link a6,#-4*4 // make room for
movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them
move.w 4(a6),d0 // fetch vector number from stack move.w 4(a6),d0 // fetch vector number from stack
lsr.l #2,d0 // move it in place lsr.l #2,d0 // move it in place
andi.l #0x000000ff,d0 // mask it out andi.l #0x000000ff,d0 // mask it out
move.l d0,-(sp) // push it move.l d0,-(sp) // push it
jsr _isr_execute_handler // call the C handler jsr _isr_execute_handler // call the C handler
lea 4(sp),sp // adjust stack lea 4(sp),sp // adjust stack
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 // cleanup stack unlk a6 // cleanup stack
rte rte
// vim: set syntax=asm68k :

View File

@@ -50,45 +50,45 @@ extern void (*rt_vbr[])(void);
*/ */
int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority, uint8_t intr, void (*handler)(void)) int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority, uint8_t intr, void (*handler)(void))
{ {
int ipl; int ipl;
int i; int i;
volatile uint8_t *ICR = &MCF_INTC_ICR01 - 1; volatile uint8_t *ICR = &MCF_INTC_ICR01 - 1;
uint8_t lp; uint8_t lp;
source &= 63; source &= 63;
priority &= 7; priority &= 7;
if (source < 1 || source > 63) if (source < 1 || source > 63)
{ {
dbg("interrupt source %d not defined\r\n", source); dbg("interrupt source %d not defined\r\n", source);
return -1; return -1;
} }
lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority); lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority);
/* check if this combination is already set somewhere */ /* check if this combination is already set somewhere */
for (i = 1; i < 64; i++) for (i = 1; i < 64; i++)
{ {
if (ICR[i] == lp) if (ICR[i] == lp)
{ {
dbg("level %d and priority %d already used for interrupt source %d!\r\n", dbg("level %d and priority %d already used for interrupt source %d!\r\n",
level, priority, i); level, priority, i);
return -1; return -1;
} }
} }
/* disable interrupts */ /* disable interrupts */
ipl = set_ipl(7); ipl = set_ipl(7);
VBR[64 + source] = handler; /* first 64 vectors are system exceptions */ VBR[64 + source] = handler; /* first 64 vectors are system exceptions */
/* set level and priority in interrupt controller */ /* set level and priority in interrupt controller */
ICR[source] = lp; ICR[source] = lp;
/* set interrupt mask to where it was before */ /* set interrupt mask to where it was before */
set_ipl(ipl); set_ipl(ipl);
return 0; return 0;
} }
#ifndef MAX_ISR_ENTRY #ifndef MAX_ISR_ENTRY
@@ -98,10 +98,10 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
typedef struct typedef struct
{ {
int vector; int vector;
int (*handler)(void *, void *); int (*handler)(void *, void *);
void *hdev; void *hdev;
void *harg; void *harg;
} ISRENTRY; } ISRENTRY;
ISRENTRY isrtab[MAX_ISR_ENTRY]; ISRENTRY isrtab[MAX_ISR_ENTRY];
@@ -109,111 +109,111 @@ ISRENTRY isrtab[MAX_ISR_ENTRY];
void isr_init(void) void isr_init(void)
{ {
int index; int index;
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
isrtab[index].vector = 0; isrtab[index].vector = 0;
isrtab[index].handler = 0; isrtab[index].handler = 0;
isrtab[index].hdev = 0; isrtab[index].hdev = 0;
isrtab[index].harg = 0; isrtab[index].harg = 0;
} }
} }
int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg) int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg)
{ {
/* /*
* This function places an interrupt handler in the ISR table, * This function places an interrupt handler in the ISR table,
* thereby registering it so that the low-level handler may call it. * thereby registering it so that the low-level handler may call it.
* *
* The two parameters are intended for the first arg to be a * The two parameters are intended for the first arg to be a
* pointer to the device itself, and the second a pointer to a data * pointer to the device itself, and the second a pointer to a data
* structure used by the device driver for that particular device. * structure used by the device driver for that particular device.
*/ */
int index; int index;
if ((vector == 0) || (handler == NULL)) if ((vector == 0) || (handler == NULL))
{ {
dbg("illegal vector or handler!\r\n"); dbg("illegal vector or handler!\r\n");
return false; return false;
} }
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if (isrtab[index].vector == vector) if (isrtab[index].vector == vector)
{ {
/* one cross each, only! */ /* one cross each, only! */
dbg("already set handler with this vector (%d, %d)\r\n", vector); dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false; return false;
} }
if (isrtab[index].vector == 0) if (isrtab[index].vector == 0)
{ {
isrtab[index].vector = vector; isrtab[index].vector = vector;
isrtab[index].handler = handler; isrtab[index].handler = handler;
isrtab[index].hdev = hdev; isrtab[index].hdev = hdev;
isrtab[index].harg = harg; isrtab[index].harg = harg;
return true; return true;
} }
} }
dbg("no available slots to register handler for vector %d\n\r", vector); dbg("no available slots to register handler for vector %d\n\r", vector);
return false; /* no available slots */ return false; /* no available slots */
} }
void isr_remove_handler(int (*handler)(void *, void *)) void isr_remove_handler(int (*handler)(void *, void *))
{ {
/* /*
* This routine removes from the ISR table all * This routine removes from the ISR table all
* entries that matches 'handler'. * entries that matches 'handler'.
*/ */
int index; int index;
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if (isrtab[index].handler == handler) if (isrtab[index].handler == handler)
{ {
isrtab[index].vector = 0; isrtab[index].vector = 0;
isrtab[index].handler = 0; isrtab[index].handler = 0;
isrtab[index].hdev = 0; isrtab[index].hdev = 0;
isrtab[index].harg = 0; isrtab[index].harg = 0;
return; return;
} }
} }
dbg("no such handler registered (handler=%p\r\n", handler); dbg("no such handler registered (handler=%p\r\n", handler);
} }
bool isr_execute_handler(int vector) bool isr_execute_handler(int vector)
{ {
/* /*
* This routine searches the ISR table for an entry that matches * This routine searches the ISR table for an entry that matches
* 'vector'. If one is found, then 'handler' is executed. * 'vector'. If one is found, then 'handler' is executed.
*/ */
int index; int index;
bool retval = false; bool retval = false;
/* /*
* locate a BaS Interrupt Service Routine handler. * locate a BaS Interrupt Service Routine handler.
*/ */
for (index = 0; index < MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if (isrtab[index].vector == vector) if (isrtab[index].vector == vector)
{ {
retval = true; retval = true;
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg)) if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{ {
return retval; return retval;
} }
} }
} }
dbg("no BaS isr handler for vector %d found\r\n", vector); dbg("no BaS isr handler for vector %d found\r\n", vector);
return retval; return retval;
} }
/* /*
@@ -221,24 +221,24 @@ bool isr_execute_handler(int vector)
*/ */
void pic_interrupt_handler(void) void pic_interrupt_handler(void)
{ {
uint8_t rcv_byte; uint8_t rcv_byte;
rcv_byte = MCF_PSC3_PSCRB_8BIT; rcv_byte = MCF_PSC3_PSCRB_8BIT;
if (rcv_byte == 2) // PIC requests RTC data if (rcv_byte == 2) // PIC requests RTC data
{ {
uint8_t *rtc_reg= (uint8_t *) 0xffff8961; uint8_t *rtc_reg= (uint8_t *) 0xffff8961;
uint8_t *rtc_data = (uint8_t *) 0xffff8963; uint8_t *rtc_data = (uint8_t *) 0xffff8963;
int index = 0; int index = 0;
xprintf("PIC interrupt requesting RTC data\r\n"); xprintf("PIC interrupt requesting RTC data\r\n");
MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC
do do
{ {
*rtc_reg = 0; *rtc_reg = 0;
MCF_PSC3_PSCTB_8BIT = *rtc_data; MCF_PSC3_PSCTB_8BIT = *rtc_data;
} while (index++ < 64); } while (index++ < 64);
} }
} }
extern int32_t video_sbt; extern int32_t video_sbt;
@@ -246,110 +246,111 @@ extern int32_t video_tlb;
void video_addr_timeout(void) void video_addr_timeout(void)
{ {
uint32_t addr = 0x0L; uint32_t addr = 0x0L;
uint32_t *src; uint32_t *src;
uint32_t *dst; uint32_t *dst;
uint32_t asid; uint32_t asid;
dbg("video address timeout\r\n"); dbg("video address timeout\r\n");
flush_and_invalidate_caches(); flush_and_invalidate_caches();
do do
{ {
uint32_t tlb; uint32_t tlb;
uint32_t page_attr; uint32_t page_attr;
/* /*
* search tlb entry id for addr (if not available, the MMU * search tlb entry id for addr (if not available, the MMU
* will provide a new one based on its LRU algorithm) * will provide a new one based on its LRU algorithm)
*/ */
MCF_MMU_MMUAR = addr; MCF_MMU_MMUAR = addr;
MCF_MMU_MMUOR = MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB | MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_RW | MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC; MCF_MMU_MMUOR_ACC;
NOP(); NOP();
tlb = (MCF_MMU_MMUOR >> 16) & 0xffff; tlb = (MCF_MMU_MMUOR >> 16) & 0xffff;
/* /*
* retrieve tlb entry with the found TLB entry id * retrieve tlb entry with the found TLB entry id
*/ */
MCF_MMU_MMUAR = tlb; MCF_MMU_MMUAR = tlb;
MCF_MMU_MMUOR = MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB | MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR | MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_RW | MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC; MCF_MMU_MMUOR_ACC;
NOP(); NOP();
asid = (MCF_MMU_MMUTR >> 2) & 0x1fff; /* fetch ASID of page */; asid = (MCF_MMU_MMUTR >> 2) & 0x1fff; /* fetch ASID of page */;
if (asid != sca_page_ID) /* check if screen area */ if (asid != sca_page_ID) /* check if screen area */
{ {
addr += 0x100000; addr += 0x100000;
continue; /* next page */ continue; /* next page */
} }
/* modify found TLB entry */ /* modify found TLB entry */
if (addr == 0x0) if (addr == 0x0)
{ {
page_attr = page_attr =
MCF_MMU_MMUDR_LK | MCF_MMU_MMUDR_LK |
MCF_MMU_MMUDR_SZ(0) | MCF_MMU_MMUDR_SZ(0) |
MCF_MMU_MMUDR_CM(0) | MCF_MMU_MMUDR_CM(0) |
MCF_MMU_MMUDR_R | MCF_MMU_MMUDR_R |
MCF_MMU_MMUDR_W | MCF_MMU_MMUDR_W |
MCF_MMU_MMUDR_X; MCF_MMU_MMUDR_X;
} }
else else
{ {
page_attr = page_attr =
MCF_MMU_MMUTR_SG | MCF_MMU_MMUTR_SG |
MCF_MMU_MMUTR_V; MCF_MMU_MMUTR_V;
} }
MCF_MMU_MMUTR = addr; MCF_MMU_MMUTR = addr;
MCF_MMU_MMUDR = page_attr; MCF_MMU_MMUDR = page_attr;
MCF_MMU_MMUOR = MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB | MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR | MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_ACC | MCF_MMU_MMUOR_ACC |
MCF_MMU_MMUOR_UAA; MCF_MMU_MMUOR_UAA;
NOP(); NOP();
dst = (uint32_t *) 0x60000000 + addr; dst = (uint32_t *) 0x60000000 + addr;
src = (uint32_t *) addr; src = (uint32_t *) addr;
while (dst < (uint32_t *) 0x60000000 + addr + 0x10000) while (dst < (uint32_t *) 0x60000000 + addr + 0x10000)
{ {
*dst++ = *src++; *dst++ = *src++;
*dst++ = *src++; *dst++ = *src++;
*dst++ = *src++; *dst++ = *src++;
*dst++ = *src++; *dst++ = *src++;
} }
addr += 0x100000; addr += 0x100000;
} while (addr < 0xd00000); } while (addr < 0xd00000);
video_tlb = 0x2000; video_tlb = 0x2000;
video_sbt = 0; video_sbt = 0;
} }
static uint32_t blinker = 0;
/* /*
* blink the Firebee's LED to show we are still alive * blink the Firebee's LED to show we are still alive
*/ */
void blink_led(void) void blink_led(void)
{ {
if ((blinker++ & 0x80) > 0) static uint16_t blinker = 0;
{
MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */ if ((blinker++ & 0x80) > 0)
} {
else MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */
{ }
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */ else
} {
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */
}
} }
/* /*
@@ -367,45 +368,45 @@ void blink_led(void)
bool irq6_acsi_dma_interrupt(void) bool irq6_acsi_dma_interrupt(void)
{ {
dbg("ACSI DMA interrupt\r\n"); dbg("ACSI DMA interrupt\r\n");
/* /*
* TODO: implement handler * TODO: implement handler
*/ */
return false; return false;
} }
bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2) bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
{ {
bool handled = false; bool handled = false;
MCF_EPORT_EPFR &= (1 << 6); /* clear int6 from edge port */ MCF_EPORT_EPFR |= (1 << 6); /* clear int6 from edge port */
if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT) if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT)
{ {
video_addr_timeout(); video_addr_timeout();
handled = true; handled = true;
} }
/* /*
* check if ACSI DMA interrupt * check if ACSI DMA interrupt
*/ */
if (FALCON_MFP_IERA & (1 << 7)) if (FALCON_MFP_IERA & (1 << 7))
{ {
/* ACSI interrupt is enabled */ /* ACSI interrupt is enabled */
if (FALCON_MFP_IPRA & (1 << 7)) if (FALCON_MFP_IPRA & (1 << 7))
{ {
irq6_acsi_dma_interrupt(); irq6_acsi_dma_interrupt();
handled = true; handled = true;
} }
} }
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB) if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
{ {
blink_led(); blink_led();
} }
return handled; return handled;
} }