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

001: ;-----------------------------------------------------------------------------
002: ; Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!!
003: ; Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!!
004: ;-----------------------------------------------------------------------------
005: ; Do not change any of the code in this file except where explicitly noted.
006: ; Making other changes can cause your program's startup code to be incorrect.
007: ;-----------------------------------------------------------------------------
008: 
009: 
010: ;----------------------------------------------------------------------------
011: ; Jaguar Development System Source Code
012: ; Copyright (c)1995 Atari Corp.
013: ; ALL RIGHTS RESERVED
014: ;
015: ; Module: startup.s - Hardware initialization/License screen display
016: ;
017: ; Revision History:
018: ;  1/12/95 - SDS: Modified from MOU.COF sources.
019: ;  2/28/95 - SDS: Optimized some code from MOU.COF.
020: ;  3/14/95 - SDS: Old code preserved old value from INT1 and OR'ed the
021: ;                 video interrupt enable bit. Trouble is that could cause
022: ;                 pending interrupts to persist. Now it just stuffs the value.
023: ;  4/17/95 - MF:  Moved definitions relating to startup picture's size and
024: ;                 filename to top of file, separate from everything else (so
025: ;                 it's easier to swap in different pictures).
026: ;----------------------------------------------------------------------------
027: ; Program Description:
028: ; Jaguar Startup Code
029: ;
030: ; Steps are as follows:
031: ; 1. Set GPU/DSP to Big-Endian mode
032: ; 2. Set VI to $FFFF to disable video-refresh.
033: ; 3. Initialize a stack pointer to high ram.
034: ; 4. Initialize video registers.
035: ; 5. Create an object list as follows:
036: ;            BRANCH Object (Branches to stop object if past display area)
037: ;            BRANCH Object (Branches to stop object if prior to display area)
038: ;            BITMAP Object (Jaguar License Acknowledgement - see below)
039: ;            STOP Object
040: ; 6. Install interrupt handler, configure VI, enable video interrupts,
041: ;    lower 68k IPL to allow interrupts.
042: ; 7. Use GPU routine to stuff OLP with pointer to object list.
043: ; 8. Turn on video.
044: ; 9. Jump to _start.
045: ;
046: ; Notes:
047: ; All video variables are exposed for program use. 'ticks' is exposed to allow
048: ; a flicker-free transition from license screen to next. gSetOLP and olp2set
049: ; are exposed so they don't need to be included by exterior code again.
050: ;-----------------------------------------------------------------------------
051: 
052:  .include "jaguar.inc"
053: 
054: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
055: ; Begin STARTUP PICTURE CONFIGURATION -- Edit this to change startup picture
056: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
057: 
058: PPP      .equ    4         ; Pixels per Phrase (1-bit)
059: BMP_WIDTH    .equ    192       ; Width in Pixels
060: BMP_HEIGHT   .equ    48       ; Height in Pixels
061: 
062: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
063: ; Change this macro as necessary. Games published by Atari but created by a
064: ; third-party should use "LICENSED TO" screen. Games published and
065: ; created by a third-party company should use "LICENSED BY" screen.
066: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
067: 
068:  .macro license_logo
069:  .incbin "/jaguar/source/sample.rgb" ; "Jaguar Developer Kit Sample"
070: ; .incbin "/jaguar/startup/lt_box.rgb" ; "Licensed To Atari Corp."
071: ; .incbin "/jaguar/startup/lb_box.rgb" ; "Licensed By Atari Corp."
072:  .endm
073: 
074: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
075: ; End of STARTUP PICTURE CONFIGURATION
076: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
077: 
078: ; Globals
079:   .globl gSetOLP
080:   .globl olp2set
081:   .globl ticks
082: 
083:   .globl  a_vdb
084:   .globl  a_vde
085:   .globl  a_hdb
086:   .globl  a_hde
087:   .globl  width
088:   .globl  height
089: ; Externals
090:   .extern _start
091: 
092: BMP_PHRASES  .equ    (BMP_WIDTH/PPP)  ; Width in Phrases
093: BMP_LINES    .equ    (BMP_HEIGHT*2)   ; Height in Half Scanlines
094: BITMAP_OFF   .equ    (2*8)         ; Two Phrases
095: LISTSIZE     .equ    5         ; List length (in phrases)
096: 
097: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Program Entry Point Follows...
098: 
099:   .text
100: 
101:   move.l  #$70007,G_END  ; big-endian mode
102:   move.l  #$70007,D_END
103:   move.w  #$FFFF,VI        ; disable video interrupts
104: 
105:   move.l  #INITSTACK,a7    ; Setup a stack
106: 
107: ;  jsr  Interlace   ; modify video regs for interlace mode  
108: 
109:   jsr  InitVideo        ; Setup our video registers.
110:   jsr  InitLister       ; Initialize Object Display List
111:   jsr  InitVBint        ; Initialize our VBLANK routine
112: 
113: ;;; Sneaky trick to cause display to popup at first VB
114: 
115:   move.l #$0,listbuf+BITMAP_OFF
116:   move.l #$C,listbuf+BITMAP_OFF+4
117: 
118:   move.l  d0,olp2set       ; D0 is swapped OLP from InitLister
119:   move.l  #gSetOLP,G_PC    ; Set GPU PC
120:   move.l  #RISCGO,G_CTRL   ; Go!
121: waitforset:
122:   move.l  G_CTRL,d0     ; Wait for write.
123:   andi.l  #$1,d0
124:   bne  waitforset
125: 
126:   move.w  #$2C7,VMODE      ; Configure Video
127:  
128: ;boucle:
129: ;  bra.s boucle
130:       jmp  _start   ; Jump to main code
131: 
132: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
133: ; Procedure: gSetOLP
134: ;            Use the GPU to set the OLP and quit.
135: ;
136: ;    Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.
137: ;
138: ; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or
139: ;          JR's. It will generate a warning with current versions of MADMAC
140: ;          because it doesn't '.ORG'.
141: ;
142:   .long
143:   .gpu
144: gSetOLP:
145:   movei   #olp2set,r0     ; Read value to write
146:   load    (r0),r1
147: 
148:   movei   #OLP,r0         ; Store it
149:   store   r1,(r0)
150: 
151:   moveq   #0,r0           ; Stop GPU
152:   movei   #G_CTRL,r1
153:   store   r0,(r1)
154:   nop               ; Two "feet" on the brake pedal
155:   nop
156: 
157:   .68000
158:   .bss
159:   .long
160: 
161: olp2set:     .ds.l   1             ; GPU Code Parameter
162: 
163:   .text
164: 
165: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
166: ; Procedure: InitVBint
167: ; Install our vertical blank handler and enable interrupts
168: ;
169: 
170: InitVBint:
171:   move.l  d0,-(sp)
172: 
173:   move.l  #UpdateList,LEVEL0 ; Install 68K LEVEL0 handler
174: 
175:   move.w  a_vde,d0         ; Must be ODD
176:   ori.w   #1,d0
177:   move.w  d0,VI
178:   move.w d0,vi_line  ; save it for later, VI is write-only
179: 
180:   move.w  #C_VIDENA,INT1          ; Enable video interrupts
181: 
182:   move.w  sr,d0
183:   and.w   #$F8FF,d0        ; Lower 68k IPL to allow
184:   move.w  d0,sr            ; interrupts
185: 
186:   move.l  (sp)+,d0
187:   rts
188: 
189: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190: ; Procedure: Interlace
191: ;            Sets up video signals correctly to enable interlaced video
192: ;            Modifies registers we were told never to touch.
193: ;            Code by Zerosquare of Jagware
194: ;
195: Interlace:
196:   move.w CONFIG, d0
197:   andi.w #16, d0
198:   bne.s Init60HzI
199:                                    
200:   Init50HzI:
201:   move.w #0, HC  
202:   move.w #1, VC    
203:   move.w #624, VP    
204:   move.w #614, VEB  
205:   move.w #619, VS    
206:   move.w #4, VEE  
207:   move.w #40, VBE  
208:   move.w #614, VBB  
209:   move.w #850, HP  
210:   move.w #1749, HS  
211:   move.w #787, HEQ  
212:   move.w #600, HVS  
213:   move.w #1709, HBB
214:   move.w #153, HBE  
215:   bra.s done
216: 
217:   Init60HzI:
218:   move.w #0, HC  
219:   move.w #1, VC  
220:   move.w #524, VP  
221:   move.w #512, VEB  
222:   move.w #518, VS  
223:   move.w #5,VEE  
224:   move.w #30,VBE  
225:   move.w #512,VBB  
226:   move.w #844,HP    
227:   move.w #1743,HS  
228:   move.w #780,HEQ  
229:   move.w #595,HVS  
230:   move.w #1697,HBB  
231:   move.w #118,HBE  
232: 
233: done:  rts
234:  
235: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
236: ; Procedure: InitVideo (same as in vidinit.s)
237: ;            Build values for hdb, hde, vdb, and vde and store them.
238: ;
239:      
240: InitVideo:
241:   movem.l d0-d6,-(sp)
242:    
243:   move.w  CONFIG,d0         ; Also is joystick register
244:   andi.w  #VIDTYPE,d0       ; 0 = PAL, 1 = NTSC
245:   beq  palvals
246: 
247:   move.w  #NTSC_HMID,d2
248:   move.w  #NTSC_WIDTH,d0
249: 
250:   move.w  #NTSC_VMID,d6
251:   move.w  #NTSC_HEIGHT,d4
252: 
253:   bra  calc_vals
254: palvals:
255:   move.w  #PAL_HMID,d2
256:   move.w  #PAL_WIDTH,d0
257: 
258:   move.w  #PAL_VMID,d6
259:   move.w  #PAL_HEIGHT,d4
260: 
261: calc_vals:
262:   move.w  d0,width
263:   move.w  d4,height
264: 
265:   move.w  d0,d1
266:   asr  #1,d1            ; Width/2
267: 
268:   sub.w   d1,d2             ; Mid - Width/2
269:   add.w   #4,d2             ; (Mid - Width/2)+4
270: 
271:   sub.w   #1,d1             ; Width/2 - 1
272:   ori.w   #$400,d1          ; (Width/2 - 1)|$400
273:  
274:   move.w  d1,a_hde
275:   move.w  d1,HDE
276: 
277:   move.w  d2,a_hdb
278:   move.w  d2,HDB1
279:   move.w  d2,HDB2
280: 
281:   move.w  d6,d5
282:   sub.w   d4,d5
283:   move.w  d5,a_vdb
284: 
285:   add.w   d4,d6
286:   move.w  d6,a_vde
287: 
288:   move.w  a_vdb,VDB
289:   move.w  #$FFFF,VDE
290:    
291:   move.l  #0,BORD1         ; Black border
292:   move.w  #0,BG            ; Init line buffer to black
293:  
294: ;  move.w #0,HC
295: ;  move.w #1,VC
296: 
297:   move.w #524,VP
298:  
299:   movem.l (sp)+,d0-d6
300:   rts
301: 
302: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
303: ; InitLister: Initialize Object List Processor List
304: ;
305: ;    Returns: Pre-word-swapped address of current object list in d0.l
306: ;
307: ;  Registers: d0.l/d1.l - Phrase being built
308: ;             d2.l/d3.l - Link address overlays
309: ;             d4.l      - Work register
310: ;             a0.l      - Roving object list pointer
311:  
312: InitLister:
313:   movem.l d1-d4/a0,-(sp)  ; Save registers
314:    
315:   lea     listbuf,a0
316:   move.l  a0,d2            ; Copy
317: 
318:   add.l   #(LISTSIZE-1)*8,d2   ; Address of STOP object
319:   move.l d2,d3   ; Copy for low half
320: 
321:   lsr.l #8,d2   ; Shift high half into place
322:   lsr.l #3,d2
323:  
324:   swap d3   ; Place low half correctly
325:   clr.w d3
326:   lsl.l #5,d3
327: 
328: ; Write first BRANCH object (branch if YPOS > a_vde )
329: 
330:   clr.l   d0
331:   move.l  #(BRANCHOBJ|O_BRLT),d1  ; $4000 = VC < YPOS
332:   or.l d2,d0   ; Do LINK overlay
333:   or.l d3,d1
334:        
335:   move.w  a_vde,d4                ; for YPOS
336:   lsl.w   #3,d4                   ; Make it bits 13-3
337:   or.w    d4,d1
338: 
339:   move.l d0,(a0)+
340:   move.l d1,(a0)+
341: 
342: ; Write second branch object (branch if YPOS < a_vdb)
343: ; Note: LINK address is the same so preserve it
344: 
345:   andi.l  #$FF000007,d1           ; Mask off CC and YPOS
346:   ori.l   #O_BRGT,d1       ; $8000 = VC > YPOS
347:   move.w  a_vdb,d4                ; for YPOS
348:   lsl.w   #3,d4                   ; Make it bits 13-3
349:   or.w    d4,d1
350: 
351:   move.l d0,(a0)+
352:   move.l d1,(a0)+
353: 
354: ; Write a standard BITMAP object
355: 
356:   move.l d2,d0
357:   move.l d3,d1
358: 
359:   ori.l  #BMP_HEIGHT/2<<14,d1       ; Height of image
360: 
361:   move.w  height,d4            ; Center bitmap vertically
362:   sub.w   #BMP_HEIGHT/2,d4
363:   add.w   a_vdb,d4
364:   andi.w  #$FFFE,d4               ; Must be even
365:   lsl.w   #3,d4
366:   or.w    d4,d1                   ; Stuff YPOS in low phrase
367: 
368:   move.l #license,d4
369:  
370:   lsl.l #8,d4
371:   or.l d4,d0
372:  
373:   move.l d0,(a0)+
374:   move.l d1,(a0)+
375:   movem.l d0-d1,bmpupdate
376: 
377: ; Second Phrase of Bitmap
378: 
379:   move.l #BMP_PHRASES>>4,d0 ; Only part of top LONG is IWIDTH
380:   move.l  #O_DEPTH16|O_NOGAP,d1   ; Bit Depth = 16-bit, Contiguous data
381: 
382:   move.w  width,d4             ; Get width in clocks
383:   lsr.w   #1,d4                ; /4 Pixel Divisor
384:   sub.w   #BMP_WIDTH,d4
385:   lsr.w   #1,d4
386:   or.w    d4,d1
387: 
388:   ori.l #((BMP_PHRASES*2)<<18)|(BMP_PHRASES<<28),d1 ; DWIDTH|IWIDTH
389: 
390:   move.l d0,(a0)+
391:   move.l d1,(a0)+
392: 
393: ; Write a STOP object at end of list
394:   clr.l   (a0)+
395:   move.l  #(STOPOBJ|O_STOPINTS),(a0)+
396: 
397: ; Now return swapped list pointer in D0
398: 
399:   move.l  #listbuf,d0
400:   swap    d0
401: 
402:   movem.l (sp)+,d1-d4/a0
403:   rts
404: 
405: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
406: ; Procedure: UpdateList
407: ;        Handle Video Interrupt and update object list fields
408: ;        destroyed by the object processor.
409: 
410: UpdateList:
411:   movem.l  d0/a0,-(sp)
412: 
413:   move.l  #listbuf+BITMAP_OFF,a0
414: 
415:   move.l  bmpupdate,(a0)       ; Phrase = d1.l/d0.l
416:   move.l  bmpupdate+4,4(a0)
417: 
418:   add.l #1,ticks  ; Increment ticks semaphore
419: 
420:   move.w  #$101,INT1       ; Signal we're done
421:   move.w  #$0,INT2
422:  
423:   btst.b #(11-8),VC  ; we're testing bit 11 (the 12th bit) of VC but...
424:   bne .bottom   ; btst only works on bytes when operating on memory
425: 
426:   ; top field
427:   ori.w #1,vi_line  ; set line next VI will occur on
428:   move.w  vi_line,VI  ; and set it (VI is write-only)
429: 
430:   bra .done
431: 
432: .bottom: ; bottom field
433:   andi.w #$fffe,vi_line  ; set line next VI will occur on
434:   move.w  vi_line,VI  ; and set it (VI is write-only)
435: 
436:   add.l #((BMP_PHRASES)<<11),(a0) ; add IWIDTH to DATA to start one line lower
437: 
438: .done:
439: 
440: ; test de scrolling
441: ;  move.w bmpupdate+6,d0
442: ;  add.w #16,d0
443: ;  and.w #$CFFF,d0
444: ;  move.w d0,bmpupdate+6
445:  
446:   movem.l  (sp)+,d0/a0
447:   rte
448: 
449: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
450: 
451:   .data
452:   .phrase
453: license:
454:   license_logo
455: 
456:   .bss
457:   .dphrase
458: 
459: listbuf:     .ds.l   LISTSIZE*2    ; Object List
460: bmpupdate:   .ds.l   2         ; One Phrase of Bitmap for Refresh
461: ticks:  .ds.l 1   ; Incrementing # of ticks
462: vi_line: .ds.w 1   ; VI is write only, so cache it
463: a_hdb:   .ds.w   1
464: a_hde:       .ds.w   1
465: a_vdb:       .ds.w   1
466: a_vde:       .ds.w   1
467: width:       .ds.w   1
468: height:      .ds.w   1
469: 
470:   .end
471: