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