.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