reformatted assembler code
This commit is contained in:
@@ -67,4 +67,5 @@ end
|
|||||||
|
|
||||||
tr
|
tr
|
||||||
ib
|
ib
|
||||||
|
add-symbol-file ../emutos/emutos2.img 0xe00000
|
||||||
load firebee/ram.elf
|
load firebee/ram.elf
|
||||||
|
|||||||
@@ -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 :
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user