.include "jaguar.inc" .text ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; .extern Mandle ; Do mandelbrot picture... .extern start_mandGPU .extern end_mandGPU .extern mandGPU .extern olp2set ; objectlist pointer... .extern gSetOLP ; routine for setting OLP .extern ticks ; video stuff... .extern a_vdb .extern a_vde .extern a_hdb .extern a_hde .extern width .extern height ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bitmap_addr .equ $20000 ; Buffer in main memory BM_WIDTH .equ 640 ; Bitmap width in pixels BM_HEIGHT .equ 480 ; Bitmap height in pixels BM_DEPTH .equ 8 ; 8 bits per pixel BM_PHRASES .equ ((BM_WIDTH*BM_DEPTH)/64) ; phrase = 64 bits BM_OFFSET .equ (2*8) ; Two Phrases = offset to bitmap object MY_LISTSIZE .equ 5 ; List size in phrases: ; branch (1) ; branch (1) ; bitmap (2) ; stop (1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This is where we get control after the startup code... _start:: move.l ticks,d0 ; get the VB counter .2: move.l ticks,d1 sub.l d0,d1 cmp.l #100,d1 ; Wait for 5-6 seconds (300 vb ticks) ble .2 ; Go make a new object list for our pictures... bsr make_list ;;; Borrow Scott's Sneaky trick to cause display to popup at first VB ;;; (Change the bitmap to a STOP object, until the VB kicks in and updates it) move.l #$0,my_objlist+BM_OFFSET move.l #$C,my_objlist+BM_OFFSET+4 ; OK, now we stick in our new object list pointer. move.l d0,olp2set ; D0 is swapped OLP from InitLister move.l #gSetOLP,G_PC ; Set GPU PC move.l #RISCGO,G_CTRL ; Go! .1: move.l G_CTRL,d0 ; Wait for write. andi.l #$1,d0 bne .1 ; Now we stick in our new VB routine. This ; is OK because the move.l is atomic. move.l #my_UpdateList,LEVEL0 ; Install 68K LEVEL0 handler ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copy over the GPU program move.l #mandGPU,a0 ; Get the address of the GPU code move.l #start_mandGPU,a1 ; Get destination address move.l #end_mandGPU,d0 ; and calculate length of GPU code sub.l #start_mandGPU,d0 asr.l #2,d0 ; divide by 4 since we're copying longs .loop: move.l (a0)+,(a1)+ ; actually copy the code... dbra d0,.loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Copy the palette into the chip move.l #256,d0 move.l #CLUT,a0 move.l #cry_data,a1 .cloop: move.w (a1)+,(a0)+ dbra d0,.cloop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now set the proper Vmode... move.w #$2C1,VMODE ; Set 16 bit CRY; 640 overscanned ; bsr clearpic ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Draw the fractal, then just bail out to an illegal instruction... move.l #G_RAM,G_PC ; GPU Program counter gets $00f03000 move.l #$1,G_CTRL ; Set the GPU going ; jsr Mandle prout: bra.s prout ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Use the blitter to clear the bitmap for our fractal picture... ; Just set up enough Blitter stuff to do a block draw. Set A1_FLAGS to: ; ; Contiguous data ; 16 bit per pixel ; width of 56 pixels ; add increment ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clearpic: move.l #PITCH1|PIXEL8|WID256|XADDPIX,d0 move.l d0,A1_FLAGS ; Point A1BASE to the data move.l #$20000,d0 move.l d0,A1_BASE ; Set the pixel point to 0,0 move.w #0,d0 ; y swap d0 move.w #0,d0 ; x move.l d0,A1_PIXEL ; Set up the step size to -256 in x, 1 in y ; The x step requires that the pixel pointer by move.w #1,d0 ; y swap d0 move.w #(-256),d0 ; x move.l d0,A1_STEP move.l #0,A1_CLIP ; Set up Counters register to 256 in x write long to clear upper ; 256 in y, or in y as a word move.w #200,d0 ; y swap d0 move.w #256,d0 ; x move.l d0,B_COUNT ; Put some data in the blitter for it to write. move.l #0,d0 move.l d0,B_PATD move.l #0,d0 move.l d0,B_PATD+4 ; Now Turn IT ON !!!!!!!!!!!!! ; NO SOURCE DATA, NO OUTER LOOP, Turn on pattern data, Allow outer loop update move.l #PATDSEL|UPDA1,d0 move.l d0,B_CMD rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; make_list: Create my Object List Processor List ; ; Returns: Pre-word-swapped address of current object list in d0.l ; ; Registers: d0.l/d1.l - Phrase being built ; d2.l/d3.l - Link address overlays ; d4.l - Work register ; a0.l - Roving object list pointer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; make_list: movem.l d1-d4/a0,-(sp) ; Save registers lea my_objlist,a0 move.l a0,d2 ; Copy add.l #(MY_LISTSIZE-1)*8,d2 ; Address of STOP object move.l d2,d3 ; Copy for low half lsr.l #8,d2 ; Shift high half into place lsr.l #3,d2 swap d3 ; Place low half correctly clr.w d3 lsl.l #5,d3 ; Write first BRANCH object (branch if YPOS > a_vde ) clr.l d0 move.l #(BRANCHOBJ|O_BRLT),d1 ; $4000 = VC < YPOS or.l d2,d0 ; Do LINK overlay or.l d3,d1 move.w a_vde,d4 ; for YPOS lsl.w #3,d4 ; Make it bits 13-3 or.w d4,d1 move.l d0,(a0)+ move.l d1,(a0)+ ; Write second branch object (branch if YPOS < a_vdb) ; Note: LINK address is the same so preserve it andi.l #$FF000007,d1 ; Mask off CC and YPOS ori.l #O_BRGT,d1 ; $8000 = VC > YPOS move.w a_vdb,d4 ; for YPOS lsl.w #3,d4 ; Make it bits 13-3 or.w d4,d1 move.l d0,(a0)+ move.l d1,(a0)+ ; Write a standard BITMAP object move.l d2,d0 move.l d3,d1 ori.l #BM_HEIGHT/2<<14,d1 ; Height of image move.w #0,d4 ; move.w height,d4 ; Center bitmap vertically ; sub.w #BM_HEIGHT/2,d4 ; add.w a_vdb,d4 ; andi.w #$FFFE,d4 ; Must be even lsl.w #3,d4 or.w d4,d1 ; Stuff YPOS in low phrase move.l #bitmap_addr,d4 lsl.l #8,d4 or.l d4,d0 move.l d0,(a0)+ move.l d1,(a0)+ movem.l d0-d1,ol_update ; Second Phrase of Bitmap move.l #BM_PHRASES>>4,d0 ; Only part of top LONG is IWIDTH move.l #O_DEPTH8|O_NOGAP,d1 ; Bit Depth = 8-bit, Contiguous data move.w #32,d4 ; move.w width,d4 ; Get width in clocks ; lsr.w #1,d4 ; /2 Pixel Divisor ; sub.w #BM_WIDTH,d4 ; lsr.w #1,d4 or.w d4,d1 ori.l #((BM_PHRASES*2)<<18)|(BM_PHRASES<<28),d1 ; DWIDTH|IWIDTH move.l d0,(a0)+ move.l d1,(a0)+ ; Write a STOP object at end of list clr.l (a0)+ move.l #(STOPOBJ|O_STOPINTS),(a0)+ ; Now return swapped list pointer in D0 move.l #my_objlist,d0 swap d0 movem.l (sp)+,d1-d4/a0 rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Procedure: my_UpdateList ; Handle Video Interrupt and update object list fields ; destroyed by the object processor. my_UpdateList: move.l a0,-(sp) move.l #my_objlist+BM_OFFSET,a0 move.l ol_update,(a0) ; Phrase = d1.l/d0.l move.l ol_update+4,4(a0) add.l #1,ticks ; Increment ticks semaphore move.w #$101,INT1 ; Signal we're done move.w #$0,INT2 btst.b #(11-8),VC ; we're testing bit 11 (the 12th bit) of VC but... bne .bottom ; btst only works on bytes when operating on memory ; top field ori.w #1,vi_line2 ; set line next VI will occur on move.w vi_line2,VI ; and set it (VI is write-only) bra .done .bottom: ; bottom field andi.w #$fffe,vi_line2 ; set line next VI will occur on move.w vi_line2,VI ; and set it (VI is write-only) add.l #((BM_PHRASES)<<11),(a0) ; add IWIDTH to DATA to start one line lower .done: move.l (sp)+,a0 rte ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .data ; This file has a label cry_data that has, in 68k format the top level ; of cry for 8 bits .include "cry.pal" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .phrase .bss .dphrase my_objlist: .ds.l 16 ol_update: .ds.l 2 vi_line2: .ds.w 1 ; VI is write only, so cache it