Files
FireBee_SVN/BaS_GNU/sources/exceptions.S

832 lines
24 KiB
ArmAsm
Raw Blame History

/********************************************************/
/* exception vectoren intialisieren
/********************************************************/
#include "startcf.h"
.extern ___Bas_base
.extern ___SUP_SP
.extern ___BOOT_FLASH
.extern ___RAMBAR0
.extern _rt_cacr
.extern _rt_mod
.extern _rt_ssp
.extern _rt_usp
.extern _rt_vbr
.extern _illegal_instruction
.extern _privileg_violation
.extern _mmutr_miss
.extern ___MBAR
.extern ___MMUBAR
.extern _video_tlb
.extern _video_sbt
.extern cpusha
/* Register read/write macros */
#define MCF_MMU_MMUCR ___MMUBAR
#define MCF_MMU_MMUOR ___MMUBAR+0x04
#define MCF_MMU_MMUSR ___MMUBAR+0x08
#define MCF_MMU_MMUAR ___MMUBAR+0x10
#define MCF_MMU_MMUTR ___MMUBAR+0x14
#define MCF_MMU_MMUDR ___MMUBAR+0x18
#define MCF_EPORT_EPPAR ___MBAR+0xF00
#define MCF_EPORT_EPDDR ___MBAR+0xF04
#define MCF_EPORT_EPIER ___MBAR+0xF05
#define MCF_EPORT_EPDR ___MBAR+0xF08
#define MCF_EPORT_EPPDR ___MBAR+0xF09
#define MCF_EPORT_EPFR ___MBAR+0xF0C
#define MCF_GPIO_PODR_FEC1L ___MBAR+0xA07
#define MCF_PSC0_PSCTB_8BIT ___MBAR+0x860C
#define MCF_PSC3_PSCRB_8BIT ___MBAR+0x890C
#define MCF_PSC3_PSCTB_8BIT ___MBAR+0x890C
.global _vec_init
//mmu ---------------------------------------------------
/* Register read/write macros */
#define MCF_MMU_MMUCR ___MMUBAR
#define MCF_MMU_MMUOR ___MMUBAR+0x04
#define MCF_MMU_MMUSR ___MMUBAR+0x08
#define MCF_MMU_MMUAR ___MMUBAR+0x10
#define MCF_MMU_MMUTR ___MMUBAR+0x14
#define MCF_MMU_MMUDR ___MMUBAR+0x18
/* Bit definitions and macros for MCF_MMU_MMUCR */
#define MCF_MMU_MMUCR_EN (0x1)
#define MCF_MMU_MMUCR_ASM (0x2)
/* Bit definitions and macros for MCF_MMU_MMUOR */
#define MCF_MMU_MMUOR_UAA (0x1)
#define MCF_MMU_MMUOR_ACC (0x2)
#define MCF_MMU_MMUOR_RW (0x4)
#define MCF_MMU_MMUOR_ADR (0x8)
#define MCF_MMU_MMUOR_ITLB (0x10)
#define MCF_MMU_MMUOR_CAS (0x20)
#define MCF_MMU_MMUOR_CNL (0x40)
#define MCF_MMU_MMUOR_CA (0x80)
#define MCF_MMU_MMUOR_STLB (0x100)
#define MCF_MMU_MMUOR_AA(x) (((x)&0xFFFF)<<0x10)
/* Bit definitions and macros for MCF_MMU_MMUSR */
#define MCF_MMU_MMUSR_HIT (0x2)
#define MCF_MMU_MMUSR_WF (0x8)
#define MCF_MMU_MMUSR_RF (0x10)
#define MCF_MMU_MMUSR_SPF (0x20)
/* Bit definitions and macros for MCF_MMU_MMUAR */
#define MCF_MMU_MMUAR_FA(x) (((x)&0xFFFFFFFF)<<0)
/* Bit definitions and macros for MCF_MMU_MMUTR */
#define MCF_MMU_MMUTR_V (0x1)
#define MCF_MMU_MMUTR_SG (0x2)
#define MCF_MMU_MMUTR_ID(x) (((x)&0xFF)<<0x2)
#define MCF_MMU_MMUTR_VA(x) (((x)&0x3FFFFF)<<0xA)
/* Bit definitions and macros for MCF_MMU_MMUDR */
#define MCF_MMU_MMUDR_LK (0x2)
#define MCF_MMU_MMUDR_X (0x4)
#define MCF_MMU_MMUDR_W (0x8)
#define MCF_MMU_MMUDR_R (0x10)
#define MCF_MMU_MMUDR_SP (0x20)
#define MCF_MMU_MMUDR_CM(x) (((x)&0x3)<<0x6)
#define MCF_MMU_MMUDR_SZ(x) (((x)&0x3)<<0x8)
#define MCF_MMU_MMUDR_PA(x) (((x)&0x3FFFFF)<<0xA)
#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V)
#define mmuord_d ( MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
#define mmuord_i (MCF_MMU_MMUOR_ITLB|MCF_MMU_MMUOR_ACC|MCF_MMU_MMUOR_UAA)
#define wt_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
#define cb_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
#define nc_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(10)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X)
//---------------------------------------------------
/*********************************************************************
*
* General Purpose Timers (GPT)
*
*********************************************************************/
/* Register read/write macros */
#define MCF_GPT0_GMS ___MBAR+0x800
/*********************************************************************
*
* Slice Timers (SLT)
*
*********************************************************************/
#define MCF_SLT0_SCNT ___MBAR+0x908
/**********************************************************/
// macros
/**********************************************************/
.altmacro
.macro irq vector,int_mask,clr_int
local irq_protect
local sev_supint
local irq_end
move.w #0x2700,sr // disable interrupt
subq.l #8,a7
movem.l d0/a5,(a7) // register sichern
lea MCF_EPORT_EPFR,a5
move.b #clr_int,(a5) // clear int pending
// test auf protect mode ---------------------
move.b DIP_SWITCHa,d0
btst #7,d0
bne irq_protect // ja->
// -------------------------------------------
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
addq.l #8,a7
move.l \vector,-(a7)
move #0x2200,sr
rts
irq_protect:
move.l usp,a5 // usp holen
tst.b _rt_mod // supervisor?
bne sev_supint // ja ->
mov3q.l #-1,_rt_mod // auf supervisor setzen
move.l a5,_rt_usp // rt_usp speichern
move.l _rt_ssp,a5 // rt_ssp holen
#ifdef cf_stack
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),-(a5) // sr,vec
#else
move.w 8(a7),-(a5) // vector nr.
move.l 12(a7),-(a5) // pc verschieben
move.w 10(a7),-(a5) // sr verschieben
#endif
bra irq_end
sev_supint:
#ifdef cf_stack
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),-(a5) // sr,vec
bset #5,2(a5) // auf super setzen
#else
move.w 8(a7),-(a5) // vector nr.
move.l 12(a7),-(a5) // pc verschieben
move.w 10(a7),-(a5) // sr verschieben
bset #5,(a5) // auf super
#endif
irq_end:
move.l a5,usp // usp setzen
lea vector,a5
adda.l _rt_vbr,a5
move.l (a5),12(a7) // vectoradresse eintragen
move.b #\int_mask,10(a7) // intmaske setzen
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
addq.l #8,a7
rte // und weg
.endm
/*
* FIXME: ugly, but I'm just unable to come up with any better solution currently
*
* GNU as does not support multi-character constants. At least I don't know of any way it would.
* The following might look more than strange, but I considered the statement
*
* mchar move.l, 'T,'E,'S,'T,-(SP)
*
* somewhat more readable than
*
* move.l #1413829460,-(SP)
*
* If anybody knows of any better way on how to do this - please do!
*
*/
.macro mchar st,a,b,c,d,tgt
\st #\a << 24|\b<<16|\c<<8|\d,\tgt
.endm
.text
_vec_init:
mov3q.l #-1,_rt_mod // rt_mod auf super
clr.l _rt_ssp
clr.l _rt_usp
clr.l _rt_vbr
move.l #___RAMBAR0,d0 // sind in rambar0
movec d0,VBR
move.l d0,a0
move.l a0,a2
init_vec:
move.l #256,d0
lea std_exc_vec(pc),a1 // standard vector
init_vec_loop:
move.l a1,(a2)+ // mal standard vector f<EFBFBD>r alle setzen
subq.l #1,d0
bne init_vec_loop
move.l #___SUP_SP,(a0)
lea reset_vector(pc),a1
move.l a1,0x04(a0)
lea acess(pc),a1
move.l a1,0x08(a0)
move.b DIP_SWITCHa,d0 // ++ vr
btst #7,d0
beq no_protect_vectors
lea _illegal_instruction(pc),a1
move.l a1,0x0c(a0)
lea _illegal_instruction(pc),a1
move.l a1,0x10(a0)
lea zero_divide(pc),a1
move.l a1,0x14(a0)
lea _privileg_violation(pc),a1
move.l a1,0x20(a0)
lea linea(pc),a1
move.l a1,0x28(a0)
lea linef(pc),a1
move.l a1,0x2c(a0)
lea format(pc),a1
move.l a1,0x38(a0)
// floating point overflow
lea flpoow(pc),a1
move.l a1,0xc0(a0)
lea flpoow(pc),a1
move.l a1,0xc4(a0)
lea flpoow(pc),a1
move.l a1,0xc8(a0)
lea flpoow(pc),a1
move.l a1,0xcc(a0)
lea flpoow(pc),a1
move.l a1,0xd0(a0)
lea flpoow(pc),a1
move.l a1,0xd4(a0)
lea flpoow(pc),a1
move.l a1,0xd8(a0)
lea flpoow(pc),a1
move.l a1,0xdc(a0)
no_protect_vectors:
// int 1-7
lea irq1(pc),a1
move.l a1,0x104(a0)
lea irq2(pc),a1
move.l a1,0x108(a0)
lea irq3(pc),a1
move.l a1,0x10c(a0)
lea irq4(pc),a1
move.l a1,0x110(a0)
lea irq5(pc),a1
move.l a1,0x114(a0)
lea irq6(pc),a1
move.l a1,0x118(a0)
lea irq7(pc),a1
move.l a1,0x11c(a0)
//psc_vectors
lea psc3(pc),a1
move.l a1,0x180(a0)
//timer 1 vectors
lea timer0(pc),a1
move.l a1,0x1f8(a0)
rts
/********************************************************/
/* exception vector routinen
/********************************************************/
vector_table_start:
std_exc_vec:
move.w #0x2700,sr // disable interrupt
subq.l #8,a7
movem.l d0/a5,(a7) // register sichern
// test auf protect mode -------------------------------
move.b DIP_SWITCHa,d0
btst #7,d0
bne stv_protect // ja->
//------------------------------------------------------
move.w 8(a7),d0 // vector holen
and.l #0x3fc,d0 // vector nummer ausmaskieren
add.l _rt_vbr,d0 // + basis
move.l d0,a5
move.l (a5),d0
move.l 4(a7),a5 // a5 zur<EFBFBD>ck
move.l d0,4(a7)
move.w 10(a7),d0
bset #13,d0 // super
move.w d0,sr // orginal sr wert in super setzen
move.l (a7)+,d0 // d0 zur<EFBFBD>ck
rts
stv_protect:
move.l usp,a5 // usp holen
tst.b _rt_mod // supervisor?
bne sev_sup // ja ->
mov3q.l #-1,_rt_mod // auf supervisor setzen
move.l a5,_rt_usp // rt_usp speichern
move.l _rt_ssp,a5 // rt_ssp holen
#ifdef cf_stack
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),d0 // sr holen
move.l d0,-(a5) // sr transferieren
swap d0 // vec -> lw
#else
move.w 8(a7),d0 // vector holen
move.w d0,-(a5) // ablegen
move.l 12(a7),-(a5) // pc transferieren
move.w 10(a7),-(a5) // sr transferieren
#endif
move.l a5,usp // usp setzen
and.l #0x3fc,d0 // vector nummer ausmaskieren
add.l _rt_vbr,d0 // + basis
move.l d0,a5
move.l (a5),12(a7) // hier geht's weiter
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
addq.l #8,a7
rte // und weg
sev_sup:
#ifdef cf_stack
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),d0 // sr holen
bset #13,d0 // war aus rt super
move.l d0,-(a5) // sr transferieren
swap d0 // vec -> lw
#else
move.w 8(a7),d0 // vector holen
move.w d0,-(a5) // ablegen
move.l 12(a7),-(a5) // pc transferieren
move.w 10(a7),-(a5) // sr transferieren
bset #5,(a5) // war aus super
#endif
move.l a5,usp // usp setzen
and.l #0x3fc,d0 // vector nummer ausmaskieren
add.l _rt_vbr,d0 // + basis
move.l d0,a5
move.l (a5),12(a7) // hier geht's weiter
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
addq.l #8,a7
rte // und weg
//*******************************************
reset_vector:
move.w #0x2700,sr // disable interrupt
move.l #0x31415926,d0
cmp.l 0x426,d0 // reset vector g<EFBFBD>ltg?
beq std_exc_vec // ja->
jmp ___BOOT_FLASH // sonst kaltstart
acess:
move.w #0x2700,sr // disable interrupt
move.l d0,-(sp) // ++ vr
move.w 4(sp),d0
andi.l #0x0c03,d0
cmpi.l #0x0401,d0
beq access_mmu
cmpi.l #0x0402,d0
beq access_mmu
cmpi.l #0x0802,d0
beq access_mmu
cmpi.l #0x0c02,d0
beq access_mmu
bra bus_error
access_mmu:
move.l MCF_MMU_MMUSR,d0
btst #1,d0
bne bus_error
move.l MCF_MMU_MMUAR,d0
cmp.l #___Bas_base,d0 // max User RAM Bereich
bge bus_error // gr<EFBFBD>sser -> bus error
bra _mmutr_miss
bus_error:
move.l (sp)+,d0
bra std_exc_vec
zero_divide:
move.w #0x2700,sr // disable interrupt
move.l a0,-(a7)
move.l d0,-(a7)
move.l 12(a7),a0 // pc
move.w (a0)+,d0 // befehlscode
btst #7,d0 // long?
beq zd_word // nein->
addq.l #2,a0
zd_word:
and.l 0x3f,d0 // ea ausmaskieren
cmp.w #0x08,d0 // -(ax) oder weniger
ble zd_end
addq.l #2,a0
cmp.w #0x39,d0 // xxx.L
bne zd_nal
addq.l #2,a0
bra zd_end
zd_nal: cmp.w #0x3c,d0 // immediate?
bne zd_end // nein->
btst #7,d0 // long?
beq zd_end // nein
addq.l #2,a0
zd_end:
move.l a0,12(a7)
move.l (a7)+,d0
move.l (a7)+,a0
rte
linea:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
linef:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
format:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
//floating point
flpoow:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
irq1:
irq 0x64,1,0x02
irq2: // hbl
// move.b #3,2(a7)
// rte
irq 0x68,2,0x04
irq3:
irq 0x6c,3,0x08
irq4: // vbl
irq 0x70,4,0x10
irq5: // acp
irq 0x74,5,0x20
irq6: // mfp
move.w #0x2700,sr // disable interrupt
subq.l #8,a7
movem.l d0/a5,(a7) // register sichern
lea MCF_EPORT_EPFR,a5
move.b #0x40,(a5) // clear int6
// test auf timeout screen adr change -------------------------------------------------------
move.l _video_sbt,d0
beq irq6_non_sca // wenn 0 nichts zu tun
sub.l #0x70000000,d0 // 14 sec abz<EFBFBD>hlen
lea MCF_SLT0_SCNT,a5
cmp.l (a5),d0 // aktuelle zeit weg
ble irq6_non_sca // noch nicht abgelaufen
lea -28(a7),a7
movem.l d0-d4/a0-a1,(a7) // register sichern
clr.l d3 // beginn mit 0
bsr cpusha // cache leeren
// eintrag suchen
irq6_next_sca:
move.l d3,d0
move.l d0,MCF_MMU_MMUAR // addresse
move.l #0x106,d4
move.l d4,MCF_MMU_MMUOR // suchen ->
nop
move.l MCF_MMU_MMUOR,d4
clr.w d4
swap d4
move.l d4,MCF_MMU_MMUAR
mvz.w #0x10e,d4
move.l d4,MCF_MMU_MMUOR // eintr<EFBFBD>ge holen aus mmu
nop
move.l MCF_MMU_MMUTR,d4 // ID holen
lsr.l #2,d4 // bit 9 bis 2
cmp.w #sca_page_ID,d4 // ist screen change ID?
bne irq6_sca_pn // nein -> page keine screen area next
// eintrag <EFBFBD>ndern
add.l #std_mmutr,d0
move.l d3,d1 // page 0?
beq irq6_sca_pn0 // ja ->
add.l #cb_mmudr,d1 // sonst page cb
bra irq6_sca_pn1c
irq6_sca_pn0:
add.l #wt_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked
irq6_sca_pn1c:
mvz.w #0x10b,d2 // MMU update
move.l d0,MCF_MMU_MMUTR
move.l d1,MCF_MMU_MMUDR
move.l d2,MCF_MMU_MMUOR // setze tlb data only
nop
// page copy
move.l d3,a0
add.l #0x60000000,a0
move.l d3,a1
move.l #0x10000,d4 // die ganze page
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
nop
irq6_sca_pn:
add.l #0x00100000,d3 // next
cmp.l #0x00d00000,d3 // ende?
blt irq6_next_sca // nein->
move.l #0x2000,d0
move.l d0,_video_tlb // anfangszustand wieder herstellen
clr.l _video_sbt // zeit l<EFBFBD>schen
movem.l (a7),d0-d4/a0-a1 // register zur<EFBFBD>ck
lea 28(a7),a7
irq6_non_sca:
// test auf acsi dma -----------------------------------------------------------------
lea 0xfffffa0b,a5
bset #7,-4(a5) // int ena
btst.b #7,(a5) // acsi dma int?
beq non_acsi_dma
bsr acsi_dma
non_acsi_dma:
// ----------------------------------------------------------------------------------
tst.b (a5)
bne irq6_1
tst.b 2(a5)
bne irq6_1
movem.l (a7),d0/a5
addq.l #8,a7
rte
irq6_1:
lea MCF_GPIO_PODR_FEC1L,a5
bclr.b #4,(a5) // led on
lea blinker(pc),a5
addq.l #1,(a5) // +1
move.l (a5),d0
and.l #0x80,d0
bne irq6_2
lea MCF_GPIO_PODR_FEC1L,a5
bset.b #4,(a5) // led off
irq6_2:
// test auf protect mode ---------------------
move.b DIP_SWITCHa,d0
btst #7,d0
bne irq6_3 // ja->
// -------------------------------------------
move.l 0xF0020000,a5 // vector holen
add.l _rt_vbr,a5 // basis
move.l (a5),d0 // vector holen
move.l 4(a7),a5 // a5 zur<EFBFBD>ck
move.l d0,4(a7) // vector eintragen
move.l (a7)+,d0 // d0 zur<EFBFBD>ck
move #0x2600,sr
rts
irq6_3:
move.l usp,a5 // usp holen
tst.b _rt_mod // supervisor?
bne sev_sup6 // ja ->
mov3q.l #-1,_rt_mod // auf supervisor setzen
move.l a5,_rt_usp // rt_usp speichern
move.l _rt_ssp,a5 // rt_ssp holen
#ifdef cf_stack
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),-(a5) // sr transferieren
#else
move.w 8(a7),-(a5) // vector transferieren
move.l 12(a7),-(a5) // pc transferieren
move.w 10(a7),-(a5) // sr transferieren
#endif
move.l a5,usp // usp setzen
move.l 0xF0020000,a5 // vector holen: intack routine
add.l _rt_vbr,a5 // virtuelle VBR des Systems
move.l (a5),12(a7) // hier gehts weiter
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
addq.l #8,a7
move.b #6,2(a7) // intmaske setzen
rte // und weg
sev_sup6:
#ifdef cf_stack
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),-(a5) // sr,vec
bset #5,2(a5) // auf super setzen
#else
move.w 8(a7),-(a5) // vector nr.
move.l 12(a7),-(a5) // pc verschieben
move.w 10(a7),-(a5) // sr verschieben
bset #5,(a5) // auf super
#endif
move.l a5,usp // usp setzen
move.l 0xF0020000,a5 // vector holen: intack routine
add.l _rt_vbr,a5 // virtuelle VBR des Systems
move.l (a5),12(a7) // hier gehts weiter
movem.l (a7),d0/a5 // register zur<EFBFBD>ck
rts
blinker:.long 0
/**************************************************/
/* pseudo dma */
/**************************************************/
acsi_dma: // atari dma
move.l a1,-(a7)
move.l d1,-(a7)
lea MCF_PSC0_PSCTB_8BIT,a1 // ++ vr
mchar move.l, 'D,'M','A,'\ ,(a1)
//move.l #"DMA ",(a1)
mchar move.l, 'I,'N,'T,'!,(a1)
//move.l #'INT!',(a1)
lea 0xf0020110,a5 // fifo daten
acsi_dma_start:
move.l -12(a5),a1 // dma adresse
move.l -8(a5),d0 // byt counter
ble acsi_dma_end
btst.b #0,-16(a5) // write? (dma modus reg)
bne acsi_dma_wl // ja->
acsi_dma_rl:
tst.b -4(a5) // dma req?
bpl acsi_dma_fertig // 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
moveq #'.',d1
move.b d1,MCF_PSC0_PSCTB_8BIT
sub.l #16,d0 // byt counter -16
bpl acsi_dma_rl
bra acsi_dma_fertig
acsi_dma_wl:
tst.b -4(a5) // dma req?
bpl acsi_dma_fertig // 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
moveq #'.',d1
move.b d1,MCF_PSC0_PSCTB_8BIT
sub.l #16,d0 // byt counter -16
bpl acsi_dma_wl
acsi_dma_fertig:
move.l a1,-12(a5) // adresse zur<EFBFBD>ck
move.l d0,-8(a5) // byt counter zur<EFBFBD>ck
acsi_dma_end:
tst.b -4(a5) // dma req?
bmi acsi_dma_start // ja->
lea 0xfffffa0b,a5
bclr.b #7,4(a5) // clear int in service mfp
bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b
move.w #0x0d0a,d1
move.w d1,MCF_PSC0_PSCTB_8BIT
move.l (a7)+,d1
move.l (a7)+,a1
rts
/**************************************************/
/* irq 7 = pseudo bus error */
/**************************************************/
irq7:
lea -12(sp),sp
movem.l d0/a0,(sp)
move.l ___RAMBAR0+0x008,a0 // Real Access Error handler
move.l a0,8(sp) // This will be the return address for rts
move.w 12(sp),d0 // Format/Vector word
andi.l #0xf000,d0 // Keep only the Format
ori.l #2*4,d0 // Simulate Vector #2, no Fault
move.w d0,12(sp)
// TODO: Inside an interrupt handler, 16(sp) is the return address.
// For an Access Error, it should be the address of the fault instruction instead
lea MCF_EPORT_EPFR,a0
move.b #0x80,(a0) // clear int7
move.l (sp)+,d0
move.l (sp)+,a0
rts // Forward to the Access Error handler
/**************************************************/
/* psc3 com PIC MCF */
/**************************************************/
psc3:
move.w #0x2700,sr // disable interrupt
lea -20(a7),a7
movem.l d0-d2/a0/a3,(a7)
lea MCF_PSC3_PSCRB_8BIT,a3
move.b (a3),d1
cmp.b #2,d1 // anforderung rtc daten?
bne psc3_fertig
lea MCF_PSC0_PSCTB_8BIT,a0 // ++ vr
mchar move.l, 'P,'I,'C','\ ,(a0)
// move.l #'PIC ',(a0)
mchar move.l, 'I,'N,'T,'\ ,(a0)
// move.l #'INT ',(a0)
mchar move.l,'R,'T,'C,'\ ,(a0)
// move.l #'RTC!',(a0)
mchar move.l,'\r,'\n,0,0,(a0)
// move.l #0x0d0a,(a0)
lea 0xffff8961,a0
lea MCF_PSC3_PSCTB_8BIT,a3
clr.l d1
moveq #64,d2
move.b #0x82,(a3) // header: rtcd mcf->pic
loop_sr2:
move.b d1,(a0)
move.b 2(a0),d0
move.b d0,(a3)
addq.l #1,d1
cmp.b d1,d2
bne loop_sr2
psc3_fertig:
movem.l (a7),d0-d2/a0/a3 // register zur<EFBFBD>ck
lea 20(a7),a7
RTE
/**************************************************/
/* timer 0: video change later also others
/**************************************************/
timer0:
move #0x2700,sr
// halt
lea -28(a7),a7
movem.l d0-d4/a0-a1,(a7)
mvz.b 0xffff8201,d0 // l<EFBFBD>schen und high byt
cmp.w #2,d0
blt video_chg_end
cmp.w #0xd0,d0 // normale addresse
blt sca_other // nein->
lea MCF_SLT0_SCNT,a0
move.l (a0),d4
move.l d4,_video_sbt // time sichern
sca_other:
lsl.l #8,d0
move.b 0xffff8203,d0 // mid byt
lsl.l #8,d0
move.b 0xffff820d,d0 // low byt
move.l d0,d3
video_chg_1page:
// test ob page schon gesetzt
moveq #20,d4
move.l d0,d2
lsr.l d4,d2 // neue page
move.l _video_tlb,d4
bset.l d2,d4 // setzen als ge<EFBFBD>ndert
bne video_chg_2page // schon gesetzt gewesen? ja->weg
move.l d4,_video_tlb
bsr cpusha // cache leeren
// daten copieren
video_copy_data:
move.l d4,_video_tlb
and.l #0x00f00000,d0
move.l d0,a0
move.l a0,a1
add.l #0x60000000,a1
move.l #0x10000,d4 // die ganze page
video_copy_data_loop:
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
subq.l #1,d4
bne video_copy_data_loop
// eintrag suchen
move.l d0,MCF_MMU_MMUAR // addresse
move.l #0x106,d4
move.l d4,MCF_MMU_MMUOR // suchen -> schl<EFBFBD>gt neuen vor wenn keiner
nop
move.l MCF_MMU_MMUOR,d4
clr.w d4
swap d4
move.l d4,MCF_MMU_MMUAR
move.l d0,d1
add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0
add.l #0x60000000|wt_mmudr|MCF_MMU_MMUDR_LK,d1
mvz.w #0x10b,d2 // MMU update
move.l d0,MCF_MMU_MMUTR
move.l d1,MCF_MMU_MMUDR
move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data
nop
video_chg_2page:
// test ob evt. anschliessende page gesetzt werden muss
move.l d3,d0
mvz.w 0xffff8210,d4 // byts pro zeile
mvz.w 0xffff82aa,d2 // zeilen ende
mvz.w 0xffff82a8,d1 // zeilenstart
sub.l d1,d2 // differenz = anzahl zeilen
mulu d2,d4 // maximal 480 zeilen
add.l d4,d0 // video gr<EFBFBD>sse
cmp.l #0xe00000,d0 // maximale addresse
bge video_chg_end // wenn gleich oder gr<EFBFBD>sser -> fertig
moveq #20,d4
move.l d0,d2
lsr.l d4,d2 // neue page
move.l _video_tlb,d4
bset.l d2,d4 // setzen als ge<EFBFBD>ndert
beq video_copy_data // nein nochmal
video_chg_end:
// int pending l<EFBFBD>schen
lea MCF_GPT0_GMS,a0
bclr.b #0,3(a0)
nop
bset.b #0,3(a0)
movem.l (a7),d0-d4/a0-a1
lea 28(a7),a7
//--------------------------------------------------------------------------------------------------------
RTE