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: