Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


swapd0 last won the day on December 8 2018

swapd0 had the most liked content!

Community Reputation

390 Excellent

About swapd0

  • Rank

Profile Information

  • Gender

Recent Profile Visitors

11,512 profile views
  1. With a second read still fails 😫 I'm going to try to move the raster code to a small 100% asm sample program.
  2. When I wrote the routine I though about that but I hoped that the GPU would be blocked until the 68000 writes both parts of the longword. I was wrong.
  3. Ok, I think that I've found the bug. I call the GPU code from 6800 like this way. It hangs the Jaguar even if the loop it's executed only one time, but If I remove the last wait_gpu_idle(), it looks that never crashes. Looks like you can't hammer a gpu address from the 68000 and the GPU at the same time, isn't it? for ( int i = 0; i < 10; ++i ) { wait_gpu_idle(); gpu_queue[0] = (uint32_t)&gpu_shit_code; // fn gpu_queue[1] = 0; // gpu_queue[2] = 0; run_gpu_queue(); wait_gpu_idle(); } _run_gpu_queue:: move.l #_gpu_queue,_gpu_events_list rts _wait_gpu_idle:: lea _gpu_events_list,a0 .wait: moveq #127,d0 divu #3,d0 move.l (a0),d0 bne.s .wait rts .long _gpu_queue:: ds.l 128
  4. My even dispatcher code: ; GPU events queue ; ptr to function [data]* ; ptr to function [data]* ; 0 ; if a function has data, it must be read from r0 pointer ; .include "jaguar/jaguar.inc" .globl _gpu_events_list .gpu list_ptr .equr r19 event_list .equr r18 event .equr r17 return .equr r16 _gpu_events:: movei #_gpu_events_list,list_ptr moveq #0,event ; store event,(list_ptr) ; clear event list .wait_list: load (list_ptr),event_list or event_list, event_list jr EQ,.wait_list nop ; execute events .execute_event: load (event_list),event or event,event ; ptr == null, end of list, go to wait event list jr EQ,_gpu_events addqt #4,event_list ; point to next event or data store event_list,(list_ptr) ; save for next event move event_list,r0 ; parameters address ; jsr to routine movei #.l0,return subqt #4,r31 jump (event) store return,(r31) .l0: ; r0 will have number of words to skip movei #_gpu_events_list,list_ptr movei #.execute_event,event load (list_ptr),event_list jump (event) add r0,event_list ; skip parameters .long _gpu_events_list:: dc.l 0 ; pointer to events list My gpu interrupt code: ; include "jaguar/jaguar.inc" .gpu gpuFlagsPtr .equr r29 flags .equr r28 rasterAddr .equr r1 colors .equr r2 clut .equr r3 opFlags .equr r4 col .equr r5 .org G_RAM .macro EMPTY_IRQ .rept 8 nop .endr .endm cpu_interrupt: ; IRQ 0 movei #init_raster,r0 ; 3 jump t,(r0) ; 1 nop ; 1 nop ; 1 nop ; 1 nop ; 1 dsp_interrupt: EMPTY_IRQ timer_interrupt: EMPTY_IRQ op_interrupt: load (gpuFlagsPtr),flags ; GPU_FLAGS load (rasterAddr),colors movei #CLUT,clut ; 0, 1 load (colors),col addqt #8,colors store col,(clut) addqt #4,clut storew r0,(opFlags) ; resume OP store colors,(rasterAddr) ; rte bclr #3,flags ; serviced bset #12,flags ; clear interrupt flag load (r31),r30 addq #2,r30 addqt #4,r31 jump (r30) store flags,(gpuFlagsPtr) ; restore interrupt .long _raster_ptr:: dc.l 0 init_raster: movei #G_FLAGS,gpuFlagsPtr ; init gpu movei #OBF,opFlags movei #_raster_ptr,rasterAddr moveta rasterAddr,rasterAddr moveta opFlags,opFlags moveta gpuFlagsPtr,gpuFlagsPtr ; fall to next included file (must be gpu_events.s) Test code that does nothing. _gpu_shit_code:: nop nop nop nop nop nop nop nop nop nop nop nop ;rts moveq #0,r0 ; skip 0 parameter load (r31),r1 jump (r1) addqt #4,r31 Main code that tells the GPU to execute something. wait_gpu_idle(); for ( int i = 0; i < 10; ++i ) { wait_gpu_idle(); gpu_queue[0] = (uint32_t)&gpu_shit_code; // fn gpu_queue[1] = 0; // gpu_queue[2] = 0; // with this uncommented takes more time to crash the code... run_gpu_queue(); wait_gpu_idle(); } If I uncomment the gpu_queue[2] it takes more time to hang the jaguar, this means that r0 got some weird values so the event loop code fails? No, I'm testing the value of r0 after the execution of the event and is always 0. Maybe I can try to port this code to a small 100% asm test code.
  5. No because the event code and the interrupt routines uses different registers, there are no registers overlap.
  6. Ok, I got an event system running on the GPU, when I write an address into a GPU RAM location, starts to execute the functions written in that array, it's something like. gpu_queue[0] = gpu_draw_sprite; gpu_queue[1] = x; gpu_queue[2] = y; gpu_queue[3] = sprite_frame; gpu_queue[4]; run_gpu_queue(); // something like gpu_queue_ptr = gpu_queue If I load this code (gnu_shit_code) into the GPU and call it, it works fine without the GPUOB interrupts, but when I insert a GPUOB into the sprite list it hangs, sometimes very quickly sometimes it takes a while, I've to move the sprites with the joypad or it never hang. If I don't tell the GPU to execute this code, it works (it's in a busy wait). So I think that my event system that I've been using in all my projects (4 in total) has some bugs. Looking at the code it could be done in a better way, more simple and without move pc, rx... , maybe this instruction is messing around. _gpu_shit_code:: ; movei #$a0000,r0 ; load (r0),r0 .loop: nop nop nop nop nop nop nop nop nop nop nop nop ;rts moveq #4,r0 ; skip 1 parameter load (r31),r1 jump (r1) addqt #4,r31
  7. The code is a mix of C/68000 asm/GPU ams, without the toolchain you won't be able to compile it and it's a bit big. Although I'm doing the test with a small program, not the game, the library it's big. Tomorrow I'll try something different, run the sprite engine with the 68000 with GPUOB interrupt and execute some "random" code in the GPU.
  8. Nope, OP list is right but crashes... this is so frustrating 😫
  9. I've done a few more test and it looks that every time a sprite is culled the list can be "corrupted", it works ok without a GPUOBJ and I have no glitches, also I've dumped the list and looks ok, but with a GPUOBJ the code crashes, no time to dump the sprite list
  10. Another small update. I have a test program that draws several sprite with different bitmap depth, also I can scale some sprites. This is the part of the routine that check the sprite scale. if I remove this code, it it's more stable (It doesn't crash so often). So I think that with the GPUOBJ/OP Interrupts enabled, if there are some kind of pipeline stall it can break the code. ... movei #$2020,r0 cmp r0,scale jr EQ,continue_build_sprite moveq #31,tmp ; branch op ; check alignment and dst,tmp ; check 32bytes alignment movei #align_last_sprite,r20 jump NE,(r20) bset #SCALE_BIT,fields ; branch op continue_build_sprite: ...
  11. Small update, I'm using this code instead of bset & bclr to initialize the GPU and it's more stable, at least it works always the same way but it crashes when I draw the sprites with the GPU, but never if I use de 68000 with GPUOBJ. movei #G_FLAGS,gpuFlagsPtr ; init gpu movei #(1<<7)+(1<<14),r1 ; enable OBJ, reg page 1 store r1,(gpuFlagsPtr)
  12. I'm using GPU interrupt to make a raster with a 4bits bitmap, but also I've a routine to change colors in the VI because if you do it in the middle of a frame you can get a wrong color. What I don't understand it's that some times it works, and later it doesn't.
  13. if I put this bset #14,flags instead of bclr #14,flags it works... I think that my jaguar init code it's wrong, I must something missing because sometimes it works, and other times it doesn't. init_jag: move.w #$2700,sr ; disable all interrups move.w #$7fff,VI ; vbi off lea stack_top,sp lea dummy_irq,a0 move.l a0,LEVEL0.w lea _BASE,a0 move.l #$070007,d0 ; big endian move.l d0,G_END-_BASE(a0) move.l d0,D_END moveq #0,d0 move.l d0,G_CTRL-_BASE(a0) ; stop gpu move.l d0,D_CTRL ; stop dsp move.l #1<<14|%11111<<9,G_FLAGS-_BASE(a0) ; disable GPU-IRQs, bank #1 ; move.l #1<<14|%11111<<9,D_FLAGS ; disable DSP-IRQs, bank #1 move.l d0,D_FLAGS move.l #%11111100000000,J_INT ; clear and disable IRQs move.l #list,d0 swap d0 move.l d0,OLP-_BASE(a0) ; set OP to STOP-OBJECT moveq #0,d0 move.w d0,R_DAC move.w d0,L_DAC move.w d0,OBF-_BASE(a0) ; clear OP-Flag move.l d0,BORD1-_BASE(a0) ; border black move.w d0,BG-_BASE(a0) ; background black move.l d0,PIT0-_BASE(a0) ; stop PIT move.l d0,JPIT1 ; stop JPIT1 move.l d0,JPIT3 ; stop JPIT2 move.w #$1F01,INT1-_BASE(a0) ; clear pending irqs & enable vbl ; blitter init lea A1_BASE,a0 lea B_CMD,a1 .cb0: move.l d0,(a0)+ cmp.l a0,a1 bne.s .cb0 lea 4(a0),a0 ; skip B_CMD lea B_Z0+4,a1 .cb1: move.l d0,(a0)+ cmp.l a0,a1 bne.s .cb1 ; video init move.w CONFIG,d0 ; Also is joystick register andi.w #VIDTYPE,d0 ; 0 = PAL, 1 = NTSC beq.s .pal move.w #NTSC_HMID,d2 move.w #NTSC_WIDTH,d0 move.w #NTSC_VMID,d6 move.w #NTSC_HEIGHT,d4 bra.s .calc_values .pal: move.w #PAL_HMID,d2 move.w #PAL_WIDTH,d0 move.w #PAL_VMID,d6 move.w #PAL_HEIGHT,d4 .calc_values: move.w d0,d1 asr.w #1,d1 ; Width/2 sub.w d1,d2 ; Mid - Width/2 add.w #4,d2 ; (Mid - Width/2)+4 sub.w #1,d1 ; Width/2 - 1 ori.w #$400,d1 ; (Width/2 - 1)|$400 move.w d1,HDE move.w d2,HDB1 move.w d2,HDB2 move.w d6,d5 sub.w d4,d5 move.w d5,VDB move.w #$FFFF,VDE move.l #0,BORD1 ; Black border move.w #0,BG ; Init line buffer to black move.w #PWIDTH4|CSYNC|BGEN|RGB16|VIDEN,VMODE-_BASE(a0) ; Configure Video rts dummy_irq: move.w #$101,INT1 ; clear vbl interrupt and enable it move.w #0,INT2 ; restore interrupts *** rte
  14. Ok, this is my interrupt code. I'll have a look at your code to see what I'm doing wrong. .gpu stack .equr r31 flagsAddr .equr r29 flags .equr r28 rasterAddr .equr r0 colors .equr r1 clut .equr r2 op .equr r3 col .equr r4 .org G_RAM .macro EMPTY_IRQ .rept 8 nop .endr .endm ; this is the entry point of the GPU code cpu_interrupt: ; IRQ 0 movei #init_raster,r0 ; 3 movei #G_ENDRAM,stack ; 3 jump t,(r0) ; 1 moveta stack,stack ; 1 dsp_interrupt: EMPTY_IRQ timer_interrupt: EMPTY_IRQ op_interrupt: load (flagsAddr),flags ; GPU_FLAGS load (rasterAddr),colors movei #CLUT,clut ; 0, 1, 2, 3 loadp (colors),col addqt #8,colors storep col,(clut) addqt #8,clut storew op,(op) ; restore op store colors,(rasterAddr) ; rte bclr #3,flags ; serviced bset #12,flags ; clear interrupt flag load (stack),r30 addqt #4,stack addqt #2,r30 jump (r30) store flags,(flagsAddr) ; restore interrupt .long _raster_ptr:: dc.l 0 init_raster: movei #G_FLAGS,flagsAddr movei #OBF,op movei #_raster_ptr,rasterAddr load (flagsAddr),flags bset #7,flags store flags,(flagsAddr) moveta rasterAddr,rasterAddr moveta op,op moveta flagsAddr,flagsAddr subqt #4,stack ; fall to next included file (must be gpu_events.s)
  15. Also, I've checked and I don't smash any register, the interrupt runs in the alternative register bank and the main GPU code runs in the other. Edit: IMO the bug is when I return from the interrupt, the GPU doesn't return to the correct address.
  • Create New...