;****************************************** ; ST to Jag GPU Routine - by Orion_ [2008] ; Optimized by SCPCD [2014] ;****************************************** ; Convert a planar 4 planes ST screen (320 x 200) to a chunky 4bits Jaguar screen ; How to use it : ; 1) upload the next GPU code into the GPU internal RAM ; 2) Run the InitST2JAG function one time at startup, to init both GPU precalc Table ; 3) Wait until GPU are stopped ; 4) Init STScreen (4bpp plannar source) and JAGScreen (4bpp chunky destination) pointers ; 5) Run the ConvertST2JAG function to convert STScreen to JAGScreen each time it's needed. ; 6) Wait until GPU are stopped before reuse the GPU ;abcdefghijklmnopqrstuvwxyzABCDEF ;GHIJKLMNOPQRSTUVWXYZ0123456789-+ ;WGqaXHrbYIscZJtd0Kue1Lvf2Mwg3Nxh <- r2 ;4Oyi5Pzj6QAk7RBl8SCm9TDn-UEo+VFp <- r5 ;Table de valeurs 256 (long): ; ------------------------abcdefgh ;-> ---a---b---c---d---e---f---g---h ;Table de valeurs 256 (long): ; ------------------------qrstuvwx ;-> --q---r---s---t---u---v---w---x- InitST2JAG: movei #ST2JAGTable,r0 movei #ST2JAGTable2,r20 movei #STGenloop,r11 moveq #0,r1 movei #256,r12 STGenloop: moveq #1,r2 ; #1 | - | - move r1,r4 ; Rr1 | - | Wr2 move r1,r5 ; Rr1 | - | Wr4 move r1,r6 ; Rr1 | - | Wr5 move r1,r7 ; Rr1 | - | Wr6 move r1,r8 ; Rr1 | - | Wr7 move r1,r9 ; Rr1 | - | Wr8 move r1,r10 ; Rr1 | - | Wr9 move r1,r3 ; Rr1 | - | Wr10 and r2,r3 ; Rr2 Rr3 | - | Wr3 shlq #1,r2 ; #1 Rr2 | Cr3 | - nop ; - | Cr2 | Wr3 and r2,r4 ; Rr2 Rr4 | - | Wr2 shlq #1,r2 ; #1 Rr2 | Cr4 | - shlq #3,r4 ; #3 Rr4 | Cr2 | Wr4 and r2,r5 ; Rr2 Rr5 | Cr4 | Wr2 or r4,r3 ; Rr4 Rr3 | Cr5 | Wr4 shlq #6,r5 ; #6 Rr5 | Cr3 | Wr5 shlq #1,r2 ; #1 Rr2 | Cr5 | Wr3 or r5,r3 ; Rr5 Rr3 | Cr2 | Wr5 and r2,r6 ; Rr2 Rr6 | Cr3 | Wr2 shlq #1,r2 ; #1 Rr2 | Cr6 | Wr3 shlq #9,r6 ; #9 Rr6 | Cr2 | Wr6 and r2,r7 ; Rr2 Rr7 | Cr6 | Wr2 or r6,r3 ; Rr6 Rr3 | Cr7 | Wr6 shlq #1,r2 ; #1 Rr2 | Cr3 | Wr7 shlq #12,r7 ; #12 Rr7 | Cr2 | Wr3 and r2,r8 ; Rr2 Rr8 | Cr7 | Wr2 or r7,r3 ; Rr7 Rr3 | Cr8 | Wr7 shlq #1,r2 ; #1 Rr2 | Cr3 | Wr8 shlq #15,r8 ; #15 Rr8 | Cr2 | Wr3 and r2,r9 ; Rr2 Rr9 | Cr8 | Wr2 or r8,r3 ; Rr8 Rr3 | Cr9 | Wr8 shlq #1,r2 ; #1 Rr2 | Cr3 | Wr9 shlq #18,r9 ; #18 Rr9 | Cr2 | Wr3 and r2,r10 ; Rr2 Rr10 | Cr9 | Wr2 or r9,r3 ; Rr9 Rr3 | Cr10 | Wr9 shlq #21,r10 ; #21 Rr10 | Cr3 | Wr10 addq #1,r1 ; #1 Rr1 | Cr10 | Wr3 or r10,r3 ; Rr10 Rr3 | Cr1 | Wr10 store r3,(r0) ; Rr3 Rr0 | Cr12 | Wr3 shlq #1, r3 ; #1 Rr3 | - | - subq #1,r12 ; #1 Rr12 | Cr3 | Wr1 store r3,(r20) ; Rr3 Rr20 | Cr12 | Wr3 addqt #4, r20 ; #4 Rr20 | - | Wr12 jump NE,(r11) ; NE+Rflags Rr11 | Cr20 | - addqt #4,r0 ; #4 Rr0 | - | Wr20 ; - | Cr0 | - ; - | - | Wr0 ;---> STOP GPU movei #G_CTRL,r0 movei #0,r1 store r1,(r0) nop ;<--- STOP GPU ;-------------------------------- ConvertST2JAG: ; movei #BG,r17 ; BACKGROUND DEBUG COLOR ; movei #$FFFF,r0 ; BACKGROUND DEBUG COLOR ; storew r0,(r17) ; BACKGROUND DEBUG COLOR movei #STScreen,r10 ; both long aligned movei #JAGScreen,r15 load (r10),r10 load (r15),r15 movei #ST2JAGTable,r14 movei #ST2JAGTable2, r18 movei #255*4,r8 movei #STloop16,r9 movei #(320*200)/(8*2),r11 movei #G_HIDATA,r16 loadp (r10),r4 ; Rr10 | - | - addq #8,r10 ; #8 Rr10 | - | - nop ; - | Cr10 | - nop ; - | - | Wr10 ;rupture de sequence.... move r4,r5 ; Rr4 | - | Wr4 ;pour etre sur que loadp soit fini (acces memoire externe) load (r16),r0 ; Rr16 | - | Wr5 STloop16: loadp (r10),r24 ; Rr10 | - | - ; External RAM loadp = 10cycles (around) move r0,r1 ; Rr0 | - | - move r0,r2 ; Rr0 | - | Wr1 move r0,r3 ; Rr0 | - | Wr2 move r4,r6 ; Rr4 | - | Wr3 move r4,r7 ; Rr4 | - | Wr6 shrq #24-2,r0 ; #22 Rr0 | - | Wr7 shrq #16-2,r1 ; #14 Rr1 | Cr0 | - and r8,r0 ; Rr8 Rr0 | Cr1 | Wr0 and r8,r1 ; Rr8 Rr1 | Cr0 | Wr1 add r14, r0 ; Rr14 Rr0 | Cr1 | Wr0 add r14, r1 ; Rr14 Rr1 | Cr0 | Wr1 load (r0), r0 ; Rr0 | Cr1 | Wr0 ; abcdefgh ; Internal RAM = 3 cycles load (r1), r1 ; Rr1 | Cr0 | Wr1 ; ijklmnop ; Internal RAM = 3 cycles shrq #8-2,r2 ; #6 Rr2 | Cr1 | Wr0 shlq #2,r3 ; #2 Rr3 | Cr2 | Wr1 and r8,r2 ; Rr8 Rr2 | Cr3 | Wr2 and r8,r3 ; Rr8 Rr3 | Cr2 | Wr3 add r18, r2 ; Rr14 Rr2 | Cr3 | Wr2 add r18, r3 ; Rr14 Rr3 | Cr2 | Wr3 load (r2), r2 ; Rr2 | Cr3 | Wr2 ; qrstuvwx ; Internal RAM = 3 cycles load (r3), r3 ; Rr3 | Cr2 | Wr3 ; yzABCDEF ; Internal RAM = 3 cycles shrq #24-2,r4 ; #22 Rr4 | Cr3 | Wr2 shrq #16-2,r5 ; #14 Rr5 | Cr4 | Wr3 and r8,r4 ; Rr8 Rr4 | Cr5 | Wr4 and r8,r5 ; Rr8 Rr5 | Cr4 | Wr5 add r14, r4 ; Rr14 Rr4 | Cr5 | Wr4 add r14, r5 ; Rr14 Rr5 | Cr4 | Wr5 load (r4), r4 ; Rr4 | Cr5 | Wr4 ; GHIJKLMN ; Internal RAM = 3 cycles load (r5), r5 ; Rr5 | Cr4 | Wr5 ; OPQRSTUV ; Internal RAM = 3 cycles shrq #8-2,r6 ; #6 Rr6 | Cr5 | Wr4 shlq #2,r7 ; #2 Rr7 | Cr6 | Wr5 and r8,r6 ; Rr8 Rr6 | Cr7 | Wr6 and r8,r7 ; Rr8 Rr7 | Cr6 | Wr7 add r18, r6 ; Rr14 Rr6 | Cr7 | Wr6 add r18, r7 ; Rr14 Rr7 | Cr6 | Wr7 load (r6), r6 ; Rr6 | Cr7 | Wr6 ; WXYZ0123 load (r7), r7 ; Rr7 | Cr6 | Wr7 ; 456789-+ or r6, r4 ; Rr6 Rr4 | Cr7 | Wr6 or r7, r5 ; Rr7 Rr5 | Cr4 | Wr7 shlq #2, r4 ; #2 Rr4 | Cr5 | Wr4 shlq #2, r5 ; #2 Rr5 | Cr4 | Wr5 or r4, r0 ; Rr4 Rr0 | Cr5 | Wr4 or r5, r1 ; Rr5 Rr1 | Cr0 | Wr5 or r2, r0 ; Rr2 Rr0 | Cr1 | Wr0 or r3, r1 ; Rr3 Rr1 | Cr0 | Wr1 nop ; - | Cr1 | Wr0 move r24,r5 ; Rr24 | - | Wr1 move r24,r4 ; Rr24 | - | Wr5 load (r16),r20 ; Rr16 | - | Wr4 store r0,(r16) ; Rr0 Rr16 | Cr20 | - subq #1,r11 ; #1 Rr11 | - | Wr20 storep r1,(r15) ; Rr1 Rr15 | Cr11 | - ; store 16 colors ; storep = 10cycle (en moyenne) move r20,r0 ; Rr20 | - | Wr11 +Wflags addqt #8,r10 ; #8 Rr10 | - | Wr0 jump NE,(r9) ; NE+Rflags Rr9 | Cr10 | - addqt #8,r15 ; #8 Rr15 | - | Wr10 ; - | Cr15 | - ; - | - | Wr15 ; storew r11,(r17) ; BACKGROUND DEBUG COLOR ;---> STOP GPU movei #G_CTRL,r0 movei #0,r1 store r1,(r0) nop ;<--- STOP GPU ;-------------------------------- .long STScreen: dc.l 0 ; Screen Pointer MUST BE LONG ALIGNED !!!! JAGScreen: dc.l 0 ST2JAGTable: dcb.l 256,0 ; Precalc Table 1Kbytes ST2JAGTable2: dcb.l 256,0 ; Precalc Table 1Kbytes