; ; Execute code in Amiga color registers on AGA computers (A1200 or A4000) ; Written by Harry "Piru" Sintonen 2024-03-14 ; ; NOTE: This code requires AGA chipsent and at least 68010 CPU. The code ; will crash if these conditions are not met, and there is no checks for ; these requirements. Also please note that currently it seems that UAE ; emulator is unable to emulate this hack correctly. ; ; to compile it: phxass M=68020 colexec.asm ; ; License: CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/ ; _LVOSupervisor EQU -30 _LVODisable EQU -120 _LVOEnable EQU -126 custom EQU $dff000 dmaconr EQU $002 dmacon EQU $096 bplcon2 EQU $104 color0 EQU $180 illvec EQU 4*4 main: move.l (4).w,a6 ; get vector base register to a4 lea (getvbr,pc),a5 jsr (_LVOSupervisor,a6) lea custom,a5 jsr (_LVODisable,a6) ; store old dma, disable all dma move.w (dmaconr,a5),_olddmacon move.w #$7fff,(dmacon,a5) ; save previous & set up a new illegal inst vector move.l (illvec,a4),_oldillegalvec move.l #illegalinst,(illvec,a4) ; copy the code to color registers move.w #0,(bplcon2,a5) ; clear RDRAM lea (hackend,pc),a0 move.l a0,d0 lea (hack,pc),a0 lea (color0,a5),a1 sub.l a0,d0 lsr.l #1,d0 subq.l #1,d0 .copy: move.w (a0)+,(a1)+ dbf d0,.copy ; clear CPU caches (technically not needed) bsr.b clearcache ; make color registers readable move.w #1<<8,(bplcon2,a5) ; set RDRAM moveq #0,d7 ; jmp to $dff180 to execute our code jmp (color0,a5) backhere: move.w #0,(bplcon2,a5) ; clear RDRAM ; restore the previous illegal inst vector move.l (_oldillegalvec,pc),(illvec,a4) ; restore the previous dma control move.w (_olddmacon,pc),d0 or.w #$8000,d0 move.w d0,(dmacon,a5) jsr (_LVOEnable,a6) move.l d7,d0 rts getvbr: movec vbr,a4 rte ; in: A6=execbase clearcache: move.w ($128,a6),d0 ; AttnFlags btst #1,d0 ; 68020 or better? beq.b .nocache move.l a5,a0 lea (.cachec,pc),a5 jmp (_LVOSupervisor,a6) .nocache: rts .cachec: btst #3,d0 ; 68040 or better? move.l a0,a5 bne.b .is040p movec cacr,d0 ; 68020 or 68030 or.w #$808,d0 movec d0,cacr rte .is040p: ; 68040 or 68060 dc.w $f478 ; CPUSHA BC flush the data into memory dc.w $f4d8 ; INVA BC invalidate the data and inst caches nop rte illegalinst: move.l #backhere,(2,sp) ; hack the return address rte ; return from the exception ; NOTE: only bit 15 and lower 12-bits will be preserved, bits 12-14 will always be 0. hack: ori.w #1337,d7 ; 0047 0539 dc.w $0fff ; illegal opcode hackend: _olddmacon: ds.w 1 _oldillegalvec: ds.l 1