File: JAGMAND.S - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

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