001:
002: .include "jaguar.inc"
003:
004: .text
005:
006: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
007: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
008:
009: ; .extern Mandle ; Do mandelbrot picture...
010: .extern start_mandGPU
011: .extern end_mandGPU
012: .extern mandGPU
013:
014: .extern olp2set ; objectlist pointer...
015: .extern gSetOLP ; routine for setting OLP
016: .extern ticks ; video stuff...
017: .extern a_vdb
018: .extern a_vde
019: .extern a_hdb
020: .extern a_hde
021: .extern width
022: .extern height
023:
024: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
025: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
026: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
027:
028: bitmap_addr .equ $20000 ; Buffer in main memory
029: BM_WIDTH .equ 640 ; Bitmap width in pixels
030: BM_HEIGHT .equ 480 ; Bitmap height in pixels
031: BM_DEPTH .equ 8 ; 8 bits per pixel
032: BM_PHRASES .equ ((BM_WIDTH*BM_DEPTH)/64) ; phrase = 64 bits
033: BM_OFFSET .equ (2*8) ; Two Phrases = offset to bitmap object
034:
035: MY_LISTSIZE .equ 5 ; List size in phrases:
036: ; branch (1)
037: ; branch (1)
038: ; bitmap (2)
039: ; stop (1)
040:
041: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
042: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
043: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
044: ; This is where we get control after the startup code...
045:
046: _start::
047: move.l ticks,d0 ; get the VB counter
048: .2:
049: move.l ticks,d1
050: sub.l d0,d1
051: cmp.l #100,d1 ; Wait for 5-6 seconds (300 vb ticks)
052: ble .2
053:
054: ; Go make a new object list for our pictures...
055:
056: bsr make_list
057:
058: ;;; Borrow Scott's Sneaky trick to cause display to popup at first VB
059: ;;; (Change the bitmap to a STOP object, until the VB kicks in and updates it)
060:
061: move.l #$0,my_objlist+BM_OFFSET
062: move.l #$C,my_objlist+BM_OFFSET+4
063:
064: ; OK, now we stick in our new object list pointer.
065:
066: move.l d0,olp2set ; D0 is swapped OLP from InitLister
067: move.l #gSetOLP,G_PC ; Set GPU PC
068: move.l #RISCGO,G_CTRL ; Go!
069: .1:
070: move.l G_CTRL,d0 ; Wait for write.
071: andi.l #$1,d0
072: bne .1
073:
074: ; Now we stick in our new VB routine. This
075: ; is OK because the move.l is atomic.
076:
077: move.l #my_UpdateList,LEVEL0 ; Install 68K LEVEL0 handler
078:
079: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
080: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
081: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
082:
083: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
084: ; Copy over the GPU program
085:
086: move.l #mandGPU,a0 ; Get the address of the GPU code
087: move.l #start_mandGPU,a1 ; Get destination address
088: move.l #end_mandGPU,d0 ; and calculate length of GPU code
089: sub.l #start_mandGPU,d0
090: asr.l #2,d0 ; divide by 4 since we're copying longs
091: .loop:
092: move.l (a0)+,(a1)+ ; actually copy the code...
093: dbra d0,.loop
094:
095: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
096: ; Copy the palette into the chip
097:
098: move.l #256,d0
099: move.l #CLUT,a0
100: move.l #cry_data,a1
101:
102: .cloop:
103: move.w (a1)+,(a0)+
104: dbra d0,.cloop
105:
106: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
107: ; Now set the proper Vmode...
108:
109: move.w #$2C1,VMODE ; Set 16 bit CRY; 640 overscanned
110:
111: ; bsr clearpic
112:
113: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
114: ; Draw the fractal, then just bail out to an illegal instruction...
115:
116: move.l #G_RAM,G_PC ; GPU Program counter gets $00f03000
117:
118: move.l #$1,G_CTRL ; Set the GPU going
119: ; jsr Mandle
120: prout:
121: bra.s prout
122:
123:
124:
125: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
126: ; Use the blitter to clear the bitmap for our fractal picture...
127: ; Just set up enough Blitter stuff to do a block draw. Set A1_FLAGS to:
128: ;
129: ; Contiguous data
130: ; 16 bit per pixel
131: ; width of 56 pixels
132: ; add increment
133: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
134:
135: clearpic:
136: move.l #PITCH1|PIXEL8|WID256|XADDPIX,d0
137: move.l d0,A1_FLAGS
138:
139: ; Point A1BASE to the data
140:
141: move.l #$20000,d0
142: move.l d0,A1_BASE
143:
144: ; Set the pixel point to 0,0
145:
146: move.w #0,d0 ; y
147: swap d0
148: move.w #0,d0 ; x
149: move.l d0,A1_PIXEL
150:
151: ; Set up the step size to -256 in x, 1 in y
152: ; The x step requires that the pixel pointer by
153:
154: move.w #1,d0 ; y
155: swap d0
156: move.w #(-256),d0 ; x
157: move.l d0,A1_STEP
158:
159: move.l #0,A1_CLIP
160:
161: ; Set up Counters register to 256 in x write long to clear upper
162: ; 256 in y, or in y as a word
163:
164: move.w #200,d0 ; y
165: swap d0
166: move.w #256,d0 ; x
167: move.l d0,B_COUNT
168:
169: ; Put some data in the blitter for it to write.
170:
171: move.l #0,d0
172: move.l d0,B_PATD
173: move.l #0,d0
174: move.l d0,B_PATD+4
175:
176: ; Now Turn IT ON !!!!!!!!!!!!!
177:
178: ; NO SOURCE DATA, NO OUTER LOOP, Turn on pattern data, Allow outer loop update
179:
180: move.l #PATDSEL|UPDA1,d0
181: move.l d0,B_CMD
182: rts
183:
184: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
185: ; make_list: Create my Object List Processor List
186: ;
187: ; Returns: Pre-word-swapped address of current object list in d0.l
188: ;
189: ; Registers: d0.l/d1.l - Phrase being built
190: ; d2.l/d3.l - Link address overlays
191: ; d4.l - Work register
192: ; a0.l - Roving object list pointer
193: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
194:
195: make_list:
196: movem.l d1-d4/a0,-(sp) ; Save registers
197:
198: lea my_objlist,a0
199: move.l a0,d2 ; Copy
200:
201: add.l #(MY_LISTSIZE-1)*8,d2 ; Address of STOP object
202: move.l d2,d3 ; Copy for low half
203:
204: lsr.l #8,d2 ; Shift high half into place
205: lsr.l #3,d2
206:
207: swap d3 ; Place low half correctly
208: clr.w d3
209: lsl.l #5,d3
210:
211: ; Write first BRANCH object (branch if YPOS > a_vde )
212:
213: clr.l d0
214: move.l #(BRANCHOBJ|O_BRLT),d1 ; $4000 = VC < YPOS
215: or.l d2,d0 ; Do LINK overlay
216: or.l d3,d1
217:
218: move.w a_vde,d4 ; for YPOS
219: lsl.w #3,d4 ; Make it bits 13-3
220: or.w d4,d1
221:
222: move.l d0,(a0)+
223: move.l d1,(a0)+
224:
225: ; Write second branch object (branch if YPOS < a_vdb)
226: ; Note: LINK address is the same so preserve it
227:
228: andi.l #$FF000007,d1 ; Mask off CC and YPOS
229: ori.l #O_BRGT,d1 ; $8000 = VC > YPOS
230: move.w a_vdb,d4 ; for YPOS
231: lsl.w #3,d4 ; Make it bits 13-3
232: or.w d4,d1
233:
234: move.l d0,(a0)+
235: move.l d1,(a0)+
236:
237: ; Write a standard BITMAP object
238:
239: move.l d2,d0
240: move.l d3,d1
241:
242: ori.l #BM_HEIGHT/2<<14,d1 ; Height of image
243:
244: move.w #0,d4
245: ; move.w height,d4 ; Center bitmap vertically
246: ; sub.w #BM_HEIGHT/2,d4
247: ; add.w a_vdb,d4
248: ; andi.w #$FFFE,d4 ; Must be even
249:
250: lsl.w #3,d4
251: or.w d4,d1 ; Stuff YPOS in low phrase
252:
253:
254: move.l #bitmap_addr,d4
255:
256: lsl.l #8,d4
257: or.l d4,d0
258:
259: move.l d0,(a0)+
260: move.l d1,(a0)+
261: movem.l d0-d1,ol_update
262:
263: ; Second Phrase of Bitmap
264:
265: move.l #BM_PHRASES>>4,d0 ; Only part of top LONG is IWIDTH
266: move.l #O_DEPTH8|O_NOGAP,d1 ; Bit Depth = 8-bit, Contiguous data
267:
268: move.w #32,d4
269: ; move.w width,d4 ; Get width in clocks
270: ; lsr.w #1,d4 ; /2 Pixel Divisor
271: ; sub.w #BM_WIDTH,d4
272: ; lsr.w #1,d4
273: or.w d4,d1
274:
275: ori.l #((BM_PHRASES*2)<<18)|(BM_PHRASES<<28),d1 ; DWIDTH|IWIDTH
276:
277: move.l d0,(a0)+
278: move.l d1,(a0)+
279:
280: ; Write a STOP object at end of list
281:
282: clr.l (a0)+
283: move.l #(STOPOBJ|O_STOPINTS),(a0)+
284:
285: ; Now return swapped list pointer in D0
286:
287: move.l #my_objlist,d0
288: swap d0
289:
290: movem.l (sp)+,d1-d4/a0
291: rts
292:
293: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294: ; Procedure: my_UpdateList
295: ; Handle Video Interrupt and update object list fields
296: ; destroyed by the object processor.
297:
298: my_UpdateList:
299: move.l a0,-(sp)
300:
301: move.l #my_objlist+BM_OFFSET,a0
302:
303: move.l ol_update,(a0) ; Phrase = d1.l/d0.l
304: move.l ol_update+4,4(a0)
305:
306: add.l #1,ticks ; Increment ticks semaphore
307:
308: move.w #$101,INT1 ; Signal we're done
309: move.w #$0,INT2
310:
311: btst.b #(11-8),VC ; we're testing bit 11 (the 12th bit) of VC but...
312: bne .bottom ; btst only works on bytes when operating on memory
313:
314: ; top field
315: ori.w #1,vi_line2 ; set line next VI will occur on
316: move.w vi_line2,VI ; and set it (VI is write-only)
317:
318: bra .done
319:
320: .bottom: ; bottom field
321: andi.w #$fffe,vi_line2 ; set line next VI will occur on
322: move.w vi_line2,VI ; and set it (VI is write-only)
323:
324: add.l #((BM_PHRASES)<<11),(a0) ; add IWIDTH to DATA to start one line lower
325:
326: .done:
327:
328: move.l (sp)+,a0
329: rte
330:
331: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
332: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
333: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
334:
335: .data
336:
337: ; This file has a label cry_data that has, in 68k format the top level
338: ; of cry for 8 bits
339:
340: .include "cry.pal"
341:
342: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
343: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
344: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
345:
346: .phrase
347: .bss
348: .dphrase
349:
350: my_objlist:
351: .ds.l 16
352:
353: ol_update:
354: .ds.l 2
355:
356: vi_line2: .ds.w 1 ; VI is write only, so cache it