Jump to content

swapd0

Members
  • Content Count

    702
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by swapd0


  1. I want to stop all playing sounds, the sound engine & the DSP, maybe it's better if I turn off all voices, and then turn off the sound engine?

     

    I'm not using any pad reading neither random number generator, in the setup code I don't touch U235SE_ctrl_reg register.

     

    I doubt that the conversion is wrong because I did some test with $12345678 and it worked.

     

    Anyway I think that I can remove the wait loop, it's called in a menu to select a game and launch it. I thought that the DSP was still running so it makes the games hang.

     

     


  2. Coding for the Jaguar is a nightmare... Ok, let's go to the topic and see if someone spot what I'm doing wrong.

     

    I've a something like a filesystem to get the assets from the ROM, (sounds, graphics or anything else), then I upload the game code to the skunk board (default address $4000) and play/test the game.

     

    Now I've the assets of three games burned together into the ROM, I upload the code of each game and it works.

     

    I've coded the menu to select a game and launch it, the code copy a small code at the end of the ram and run it, this small code copy the game to $4000 and jumps there. Now comes the funny thing.

     

    Game 1 works

    Game 2 you can see the menu, but it hangs when it shows the intro scene

    Game 3 you hear the music but no image, sometimes it runs but with glitches and I doesn't read very well the joypad (I've to press fire several times to start the game)

     

    Even if I call run_game at the start of the code it doesn't work. It looks like the Jaguar can't be initalizated two times, one for the menu, the other at the start of each game.

     

    I've no idea why this doesn't work.

     

    LOAD_ADDRESS    .equ 2*1024*1024-64		; end of ram
    
    ;_run_game(const void *begin, const void *end)
    _run_game::
        move.w #$2700,sr
        move.w #$7fff,VI          ; VI
    
        lea _copy_run,a0
        move.l #LOAD_ADDRESS,a1
        move.w #(_end_copy_run-_copy_run)/2-1,d7
    .loop:
        move.w (a0)+,(a1)+
        dbf d7,.loop
        move.l 4(sp),a0
        move.l 8(sp),a1
        jmp LOAD_ADDRESS
    
    _copy_run:
        move.l #$4000,a2
    .loop:
        move.w (a0),$f00058         ; BG
        move.l (a0)+,(a2)+
        cmp.l a0,a1
        bge.s .loop
    
        jmp $4000.w
    _end_copy_run:

     


  3. Sorry, the sound is stopped but it waits forever in the wait loop, but I think that I can remove that wait because I don't upload anything into the DSP for about one second later.

     

    And yes, that is the output of the d0 register, I send the value to the skunk board after reading it.

     


  4. This is the code, I've just inserted the print_d0:

    _stop_sound_system::
    	lea playlist,a0							; The address of the sound effect playlist
    
    	moveq #15,d0
    	move.l d0,(a0)+
    	clr.l (a0)+
    
    	move.l #playlist,U235SE_sfxplaylist_ptr
    
    	lea U235SE_status_reg,a0
    .wait:
    	move.w #0,BG
        move.l (a0),d0
    	jsr _skunk_print_d0			; ***
    	move.w #3456,BG
        cmp.l #U235SE_SRMSK_ALL_STOPPED,d0
        bne.s .wait
    	rts

    And this is the output.

     

    00000000
    30303030
    33303330
    33333330
    33333333
    33333333
    33333333

     


  5. _stop_sound_system::
    	lea playlist,a0							; The address of the sound effect playlist
    
    	moveq #15,d0
    	move.l d0,(a0)+
    	clr.l (a0)+
    
    	move.l #playlist,U235SE_sfxplaylist_ptr
    
    	lea U235SE_status_reg,a0
    .wait:
    	move.w #0,BG
        move.l (a0),d0
    	move.w #3456,BG
        cmp.l #U235SE_SRMSK_ALL_STOPPED,d0
        bne.s .wait
    	rts

    My routine to stop the u235 sound system, the move BG it's to see what is going... why it never return? it's copy&paste from the sample code


  6. 10 hours ago, SCPCD said:

    Don't know if it's what you would like to achieve, but, I give it a try and made some modification (search SCPCD tags)

    Seems working fine on real Jaguar, JagFPGA & VirtualJaguar.

     

    rasters_SCPCD.zip 74.08 kB · 8 downloads

    rasters.jpg

    I just copy&paste the raster code, in that sprite demo it works, but in the other one it doesn't work... I've no idea why this happens, IMO it should work or doesn't on both programs.

     

    Edit: I had a quick look at your modifications, yesterday I did almost the same (including a semaphore) but I forgot to use the indexed load and one of the relative jump was too far, I had to write more code and use a unconditional jump. I'll use your solution, the code looks more clean now. Thanks.

    • Like 1

  7. 3 hours ago, matmook said:

    Nice effect!

    Another option is to NOT use interrupts for your rasters but a sprite instead. You will have an extra sprite to manage and write to but you won't interrupt the GPU on each line.

    Yes, I though about that but I'll need a 16bits background, the OP would eat all the bus cycles and the 68000 won't have enough free cycles to run the game logic. Or use a 8bits background with less colors.

     

    Anyway I want to try it with a semaphore.


  8. When you press * a GPUOB is inserted in the beginning of the OP list, sometimes it hangs quickly, some times you must move the sprites to crash the code, I don't know why. The same code (copy & pasted) is used in the raster.zip code (sorry I forgot to include the binary) and it works there.

     

    I hope to have some free time today to implement the semaphore, it's the right way to do it, but still don't know why it's so unstable because I'm using this for the background rasters in Classic Kong, and it worked in the demo that I uploaded some time ago.

     

     


  9. Next thing to try is the semaphore.

     

    I've moved the code to an old sprite test and it works...

     

    What I don't understand it's that now it fails quickly (the C test program), and usually when I press down or right in the joypad to move the sprites down or to the right. In test-c.jag you have to press * on the joypad to turn rasters on, you can move the sprites with the joypad.

     

     

    rasters.zip test-c.jag


  10. 9 hours ago, CyranoJ said:

    The 68000 writes to the GPU RAM in 16-bit segments, so two writes for a longword.

    The GPU reads as 32bit, and is clocked higher.

     

    It's reading only half the address (the high half)

     

    You should be setting a sempahore flag, and checking that, not the actual pointer value.

     

    .wait_list:
        load (list_ptr),event_list
        or event_list, event_list
        jr EQ,.wait_list
        nop

    That is your problem.

    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.


  11. 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

     


  12. 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.


  13. 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

     


  14. 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.

     


  15. 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 :( 

×
×
  • Create New...