;************************************************************************
;* TITLE:         BIOSASM.S            					*
;* PROJECT:	  JAGUAR MC   						*
;* FUNCTION:      Jaguar BIOS       					*
;* PROGRAMMER:    Hans-Martin Krober					*
;* DATE:       	  11/95              					*
;*                         						*
;*         Usage of Atari Jaguar startup code by Scott Sanders.		*
;*									*
;* NOTE:          Link this file <<<< FIRST >>>>      			*
;*                         						*
;*            COPYRIGHT 1993,1994,1995 Atari U.S. Corporation           *
;*          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
;*          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
;*        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
;*                          ALL RIGHTS RESERVED.                        *
;*                         						*
;************************************************************************

;***  Include Files

	.include	"jaguar.inc"

;************************************************************************
;***  Defines
;************************************************************************

supsiz		.equ	$1000			; 4k of super stack

;
;***  Object Processor
;
PPP     	.equ    4      			; Pixels per Phrase (16-bit)
MSCRN_WIDTH   	.equ    320     		; Width in Pixels
MSCRN_HEIGHT  	.equ    200    			; Height in Pixels
MSCRN_PHRASES 	.equ    (MSCRN_WIDTH/PPP) 	; Width in Phrases
MSCRN_LINES   	.equ    (MSCRN_HEIGHT*2)  	; Height in Half Scanlines
MSCRN_OFF  	.equ    (2*8)       		; Two Phrases
LISTSIZE    	.equ    5       		; List length (in phrases)

STARTUP_COLOR	.equ     $07E807E8		; Initial Screen Color (green)


CRT_KEYBD_OK	.equ	$88
CRT_TIME_OUT	.equ	5

;************************************************************************
;***  External Data
;************************************************************************

	.extern	_CrtInit
	.extern	_CrtSendCommand
	.extern	_CrtReadKeybd
	.extern	_init_jag_uart

	.extern	_init_conout

	.extern _main
;************************************************************************
;***  External Rotuines
;************************************************************************



;************************************************************************
;***  Global Data
;************************************************************************


;************************************************************************
;***  Global Routines
;************************************************************************
	.globl	reseth

	.globl	_mscreen	


;************************************************************************
;***	SYSTEM'S MAIN ENTRY POINT
;************************************************************************
	.text
reseth:
	move.w	#$2700,sr		;*** super visor mode, no irqs;
	move.l  #$70007,G_END		; big-endian mode
	move.l  #$70007,D_END
	move.w  #$FFFF,VI       	; disable video interrupts
;
;***  Stack
;
	move.l	#_supstk+supsiz,sp	;*** Setup OS Stack

;
;***  Clear RAM
;

;
;***  Init Video
;
	jsr 	InitVideo      		; Setup our video registers.
	jsr 	InitLister     		; Initialize Object Display List
					; >> D0 has swapped OLP, DO NOT DESTROY
	jsr 	InitVBint      		; Initialize our VBLANK routine
;					; Saves D0 so OLP is ok
; Sneaky trick to cause display to popup at first VB
;
	move.l	#$0,op_mscrn_list+MSCRN_OFF
	move.l	#$C,op_mscrn_list+MSCRN_OFF+4

	move.l  d0,olp2set      	; D0 is swapped OLP from InitLister
	move.l  #gSetOLP,G_PC   	; Set GPU PC
	move.l  #RISCGO,G_CTRL  	; Go!
waitforset:
	move.l  G_CTRL,d0   		; Wait for write.
	andi.l  #$1,d0
	bne 	waitforset

	move.w  #$6C7,VMODE     	; Configure Video

	move.l	#_mscreen, _v_bas_ad	; Video Base Address


	move.l	#STARTUP_COLOR, -(a7)
	jsr	_ClearScrn		; Clear Screen
	addq.l	#4, a7

;
;***  Init Cortina
;
	jsr	_CrtInit

;
;***  Init Jaguar Uart
;

	jsr	_init_jag_uart
;	cmp.w	d0, $88
;	bne	.panic		

;
;***  Init Keyboard & Mouse
;

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupKeybd, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7

.1:
	move.w	#0, -(a7)
	jsr	_CrtReadKeybd
	addq.w	#2, a7
	cmp.w	#$fa,d0
	bne	.1

	move.w	#$f0, setupKeybd+2

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupKeybd, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7

.2:
	move.w	#0, -(a7)
	jsr	_CrtReadKeybd
	addq.w	#2, a7
	cmp.w	#$fa,d0
	bne	.2

	move.w	#$03, setupKeybd+2

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupKeybd, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7

.3:
	move.w	#0, -(a7)
	jsr	_CrtReadKeybd
	addq.w	#2, a7
	cmp.w	#$fa,d0
	bne	.3

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupMouse, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7


	jsr	_init_conout
;
;***  Init Sound
;

;
;***  Init Trap/Irq Vectors
;

;************* test 
	jsr	_main
;
;***  Call MiNT
;
;   	jmp	_startMiNT		; Jump to main code

;***
	illegal



;
;***
; Procedure: gSetOLP
;            Use the GPU to set the OLP and quit.
;
;    Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.
;
; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or
;          JR's. It will generate a warning with current versions of MADMAC
;          because it doesn't '.ORG'.
;
		.long
		.gpu
gSetOLP:
		movei   #olp2set,r0   		; Read value to write
		load    (r0),r1

		movei   #OLP,r0       		; Store it
		store   r1,(r0)

		moveq   #0,r0         		; Stop GPU
		movei   #G_CTRL,r1
		store   r0,(r1)
		nop             		; Two "feet" on the brake pedal
		nop

		.68000
		.text

;***
; Procedure: InitVBint
; Install our vertical blank handler and enable interrupts
;

InitVBint:
		move.l  d0,-(sp)

		move.l  #UpdateList,LEVEL0	; Install 68K LEVEL0 handler

		move.w  a_vde,d0        	; Must be ODD
		ori.w   #1,d0
		move.w  d0,VI

		move.w  #C_VIDENA,INT1         	; Enable video interrupts

		move.w  sr,d0
		and.w   #$F8FF,d0       	; Lower 68k IPL to allow
		move.w  d0,sr           	; interrupts

		move.l  (sp)+,d0
		rts
;		
;***
; Procedure: InitVideo (same as in vidinit.s)
;            Build values for hdb, hde, vdb, and vde and store them.
;
						
InitVideo:
		movem.l d0-d6,-(sp)
			
		move.w  CONFIG,d0      		 ; Also is joystick register
		andi.w  #VIDTYPE,d0    		 ; 0 = PAL, 1 = NTSC
		beq 	palvals

		move.w  #NTSC_HMID,d2
		move.w  #NTSC_WIDTH,d0

		move.w  #NTSC_VMID,d6
		move.w  #NTSC_HEIGHT,d4

		bra 	calc_vals
palvals:
		move.w  #PAL_HMID,d2
		move.w  #PAL_WIDTH,d0

		move.w  #PAL_VMID,d6
		move.w  #PAL_HEIGHT,d4

calc_vals:
		move.w  d0,width
		move.w  d4,height

		move.w  d0,d1
		asr 	#1,d1         	 	; Width/2

		sub.w   d1,d2         	  	; Mid - Width/2
		add.w   #4,d2         	  	; (Mid - Width/2)+4

		sub.w   #1,d1         	  	; Width/2 - 1
		ori.w   #$400,d1      	  	; (Width/2 - 1)|$400
		
		move.w  d1,a_hde
		move.w  d1,HDE

		move.w  d2,a_hdb
		move.w  d2,HDB1
		move.w  d2,HDB2

		move.w  d6,d5
		sub.w   d4,d5
		move.w  d5,a_vdb

		add.w   d4,d6
		move.w  d6,a_vde

		move.w  a_vdb,VDB
		move.w  #$FFFF,VDE
			
		move.l  #0,BORD1        	; Black border
		move.w  #0,BG           	; Init line buffer to black
			
		movem.l (sp)+,d0-d6
		rts

;
;***
; InitLister: Initialize Object List Processor List
;
;    Returns: Pre-word-swapped address of current object list in d0.l
;
;  Registers: d0.l/d1.l - Phrase being built
;             d2.l/d3.l - Link address overlays
;             d4.l      - Work register
;             a0.l      - Roving object list pointer
		
InitLister:
		movem.l d1-d4/a0,-(sp)		; Save registers
			
		lea     op_mscrn_list,a0
		move.l  a0,d2           	; Copy

		add.l   #(LISTSIZE-1)*8,d2  	; Address of STOP object
		move.l	d2,d3			; Copy for low half

		lsr.l	#8,d2			; Shift high half into place
		lsr.l	#3,d2			; In phrases
		
		lsr.l	#3,d3			; In phrases
		swap	d3			; Place low half correctly
		clr.w	d3
		lsl.l	#8,d3

; Write first BRANCH object (branch if YPOS > a_vde )

		clr.l   d0
		move.l  #(BRANCHOBJ|O_BRLT),d1  ; $4000 = VC < YPOS
		or.l	d2,d0			; Do LINK overlay
		or.l	d3,d1
								
		move.w  a_vde,d4                ; for YPOS
		lsl.w   #3,d4                   ; Make it bits 13-3
		or.w    d4,d1

		move.l	d0,(a0)+
		move.l	d1,(a0)+

; Write second branch object (branch if YPOS < a_vdb)
; Note: LINK address is the same so preserve it

		andi.l  #$FF000007,d1           ; Mask off CC and YPOS
		ori.l   #O_BRGT,d1      	; $8000 = VC > YPOS
		move.w  a_vdb,d4                ; for YPOS
		lsl.w   #3,d4                   ; Make it bits 13-3
		or.w    d4,d1

		move.l	d0,(a0)+
		move.l	d1,(a0)+

; Write a standard MSCRN object
		move.l	d2,d0
		move.l	d3,d1

		ori.l  #MSCRN_HEIGHT<<14,d1       ; Height of image

		move.w  height,d4           	; Center MSCRN vertically
		sub.w   #MSCRN_HEIGHT,d4
		add.w   a_vdb,d4
		andi.w  #$FFFE,d4               ; Must be even
		lsl.w   #3,d4
		or.w    d4,d1                   ; Stuff YPOS in low phrase

		move.l	#_mscreen,d4
		lsl.l	#8,d4
		or.l	d4,d0

		move.l	d0,(a0)+
		move.l	d1,(a0)+
		movem.l	d0-d1,op_mscrn_update

; Second Phrase of MSCRN
		move.l	#MSCRN_PHRASES>>4,d0	; Only part of top LONG is IWIDTH
		move.l  #O_DEPTH16|O_NOGAP,d1   ; Bit Depth = 16-bit, Contiguous data

		move.w  width,d4            	; Get width in clocks
		lsr.w   #2,d4               	; /4 Pixel Divisor
		sub.w   #MSCRN_WIDTH,d4
		lsr.w   #1,d4
		or.w    d4,d1

		ori.l	#(MSCRN_PHRASES<<18)|(MSCRN_PHRASES<<28),d1	; DWIDTH|IWIDTH

		move.l	d0,(a0)+
		move.l	d1,(a0)+

; Write a STOP object at end of list
		clr.l   (a0)+
		move.l  #(STOPOBJ|O_STOPINTS),(a0)+

; Now return swapped list pointer in D0

		move.l  #op_mscrn_list,d0
		swap    d0

		movem.l (sp)+,d1-d4/a0
		rts

;***
; Procedure: UpdateList
;        Handle Video Interrupt and update object list fields
;        destroyed by the object processor.

UpdateList:
		move.l  a0,-(sp)

		move.l  #op_mscrn_list+MSCRN_OFF,a0

		move.l  op_mscrn_update,(a0)	; Phrase = d1.l/d0.l
		move.l  op_mscrn_update+4,4(a0)

		add.l	#1,ticks		; Increment ticks semaphore

		move.w  #$101,INT1      	; Signal we're done
		move.w  #$0,INT2

		move.l  (sp)+,a0
		rte


;
;***
;	ClearScreen
;

_ClearScrn::
	movem.l	d0-d1,-(sp)
	move.l	8+4(sp),d1
	move.l	#PITCH1 | PIXEL16 | WID320 | XADDPIX,d0
	move.l	d0,A1_FLAGS

; Point A1BASE to the data
	move.l	_v_bas_ad,d0
	move.l	d0,A1_BASE

; Set the pixel point to 0,0
	move.w	#0,d0			; y
	swap	d0
	move.w	#0,d0			; x
	move.l	d0,A1_PIXEL

; Set up the step size to -320 in x
; 1 in y
; The x step requires that the pixel pointer by 
	move.w	#1,d0			; y
	swap	d0
	move.w	#(-MSCRN_WIDTH),d0
	move.l	d0,A1_STEP

; Set up Counters register to 256 in x write long to clear upper
; 256 in y, or in y as a word

	move.w	#MSCRN_HEIGHT,d0		; y
	swap	d0
	move.w	#MSCRN_WIDTH,d0			; x
	move.l	d0,B_COUNT

; Put some data in the blitter for it to write
; This is a cheat I am using all 0 so there is 
; no need to word swap

	move.l	d1,B_PATD	
	move.l	d1,B_PATD+4	

; Now Turn IT ON !!!!!!!!!!!!!

; NO SOURCE DATA
; NO OUTER LOOP
; Turn on pattern data
; Allow outer loop update

	move.l	#PATDSEL|UPDA1,d0
	move.l	d0,B_CMD
	movem.l	(sp)+,d0-d1
	rts



;***  Data Section

	.data
	.phrase

_scrn_w:
	.dc.w    MSCRN_WIDTH		; Width of screen
_scrn_h:
	.dc.w    MSCRN_HEIGHT     	; Height of screen



setupKeybd:
	.dc.w	$7f, $f4, $ffff
setupMouse:
	.dc.w	$79, $98, $22, $ffff


;***  BSS Section / Starts at $4000 on Jaguar
	.bss
	.phrase
_mscreen:
	.ds.b MSCRN_WIDTH * MSCRN_HEIGHT * PPP / 2  ; memory for the screen

_supstk:
	.ds.b supsiz				; Super stack
_supstk_end:

	.phrase
_v_bas_ad:
   	.ds.l 1					; Screen pointer

		.dphrase
op_mscrn_list:  .ds.l   LISTSIZE*2  		; Object List
op_mscrn_update:.ds.l   2       		; One Phrase of MSCRN for Refresh
ticks:		.ds.l	1			; Incrementing # of ticks
a_hdb:  	.ds.w   1
a_hde:      	.ds.w   1
a_vdb:      	.ds.w   1
a_vde:      	.ds.w   1
width:      	.ds.w   1
height:     	.ds.w   1

		.long
olp2set:    	.ds.l   1           		; GPU Code Parameter

;* TITLE:         STARTUP.S            					*
;* PROJECT:	  JAGUAR MC   						*
;* FUNCTION:      STARTUP CODE       					*
;* PROGRAMMER:    Hans-Martin Krober					*
;* DATE:       	  11/95              					*
;*                         						*
;*         Usage of Atari Jaguar startup code by Scott Sanders.		*
;*									*
;* NOTE:          Link this file <<<< FIRST >>>>      			*
;*                         						*
;*            COPYRIGHT 1993,1994,1995 Atari U.S. Corporation           *
;*          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
;*          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
;*        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
;*                          ALL RIGHTS RESERVED.                        *
;*                         						*
;************************************************************************

;***  Include Files

	.include	"jaguar.inc"

;************************************************************************
;***  Defines
;************************************************************************

supsiz		.equ	$1000			; 4k of super stack

;
;***  Object Processor
;
PPP     	.equ    4      			; Pixels per Phrase (16-bit)
MSCRN_WIDTH   	.equ    320     		; Width in Pixels
MSCRN_HEIGHT  	.equ    200    			; Height in Pixels
MSCRN_PHRASES 	.equ    (MSCRN_WIDTH/PPP) 	; Width in Phrases
MSCRN_LINES   	.equ    (MSCRN_HEIGHT*2)  	; Height in Half Scanlines
MSCRN_OFF  	.equ    (2*8)       		; Two Phrases
LISTSIZE    	.equ    5       		; List length (in phrases)

STARTUP_COLOR	.equ     $07E807E8		; Initial Screen Color (green)


CRT_KEYBD_OK	.equ	$88
CRT_TIME_OUT	.equ	5

;************************************************************************
;***  External Data
;************************************************************************

	.extern	_CrtInit
	.extern	_CrtSendCommand
	.extern	_CrtReadKeybd
	.extern	_init_jag_uart

	.extern	_init_conout

	.extern _main
;************************************************************************
;***  External Rotuines
;************************************************************************



;************************************************************************
;***  Global Data
;************************************************************************


;************************************************************************
;***  Global Routines
;************************************************************************
	.globl	reseth

	.globl	_mscreen	


;************************************************************************
;***	SYSTEM'S MAIN ENTRY POINT
;************************************************************************
	.text
reseth:
	move.w	#$2700,sr		;*** super visor mode, no irqs;
	move.l  #$70007,G_END		; big-endian mode
	move.l  #$70007,D_END
	move.w  #$FFFF,VI       	; disable video interrupts
;
;***  Stack
;
	move.l	#_supstk+supsiz,sp	;*** Setup OS Stack

;
;***  Clear RAM
;

;
;***  Init Video
;
	jsr 	InitVideo      		; Setup our video registers.
	jsr 	InitLister     		; Initialize Object Display List
					; >> D0 has swapped OLP, DO NOT DESTROY
	jsr 	InitVBint      		; Initialize our VBLANK routine
;					; Saves D0 so OLP is ok
; Sneaky trick to cause display to popup at first VB
;
	move.l	#$0,op_mscrn_list+MSCRN_OFF
	move.l	#$C,op_mscrn_list+MSCRN_OFF+4

	move.l  d0,olp2set      	; D0 is swapped OLP from InitLister
	move.l  #gSetOLP,G_PC   	; Set GPU PC
	move.l  #RISCGO,G_CTRL  	; Go!
waitforset:
	move.l  G_CTRL,d0   		; Wait for write.
	andi.l  #$1,d0
	bne 	waitforset

	move.w  #$6C7,VMODE     	; Configure Video

	move.l	#_mscreen, _v_bas_ad	; Video Base Address


	move.l	#STARTUP_COLOR, -(a7)
	jsr	_ClearScrn		; Clear Screen
	addq.l	#4, a7

;
;***  Init Cortina
;
	jsr	_CrtInit

;
;***  Init Jaguar Uart
;

	jsr	_init_jag_uart
;	cmp.w	d0, $88
;	bne	.panic		

;
;***  Init Keyboard & Mouse
;

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupKeybd, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7

.1:
	move.w	#0, -(a7)
	jsr	_CrtReadKeybd
	addq.w	#2, a7
	cmp.w	#$fa,d0
	bne	.1

	move.w	#$f0, setupKeybd+2

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupKeybd, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7

.2:
	move.w	#0, -(a7)
	jsr	_CrtReadKeybd
	addq.w	#2, a7
	cmp.w	#$fa,d0
	bne	.2

	move.w	#$03, setupKeybd+2

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupKeybd, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7

.3:
	move.w	#0, -(a7)
	jsr	_CrtReadKeybd
	addq.w	#2, a7
	cmp.w	#$fa,d0
	bne	.3

	move.w	#CRT_TIME_OUT, -(a7)
	move.w	#CRT_KEYBD_OK, -(a7)
	move.l	#setupMouse, -(a7)
	jsr	_CrtSendCommand
	addq.l	#8,a7


	jsr	_init_conout
;
;***  Init Sound
;

;
;***  Init Trap/Irq Vectors
;

;************* test 
	jsr	_main
;
;***  Call MiNT
;
;   	jmp	_startMiNT		; Jump to main code

;***
	illegal



;
;***
; Procedure: gSetOLP
;            Use the GPU to set the OLP and quit.
;
;    Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.
;
; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or
;          JR's. It will generate a warning with current versions of MADMAC
;          because it doesn't '.ORG'.
;
		.long
		.gpu
gSetOLP:
		movei   #olp2set,r0   		; Read value to write
		load    (r0),r1

		movei   #OLP,r0       		; Store it
		store   r1,(r0)

		moveq   #0,r0         		; Stop GPU
		movei   #G_CTRL,r1
		store   r0,(r1)
		nop             		; Two "feet" on the brake pedal
		nop

		.68000
		.text

;***
; Procedure: InitVBint
; Install our vertical blank handler and enable interrupts
;

InitVBint:
		move.l  d0,-(sp)

		move.l  #UpdateList,LEVEL0	; Install 68K LEVEL0 handler

		move.w  a_vde,d0        	; Must be ODD
		ori.w   #1,d0
		move.w  d0,VI

		move.w  #C_VIDENA,INT1         	; Enable video interrupts

		move.w  sr,d0
		and.w   #$F8FF,d0       	; Lower 68k IPL to allow
		move.w  d0,sr           	; interrupts

		move.l  (sp)+,d0
		rts
;		
;***
; Procedure: InitVideo (same as in vidinit.s)
;            Build values for hdb, hde, vdb, and vde and store them.
;
						
InitVideo:
		movem.l d0-d6,-(sp)
			
		move.w  CONFIG,d0      		 ; Also is joystick register
		andi.w  #VIDTYPE,d0    		 ; 0 = PAL, 1 = NTSC
		beq 	palvals

		move.w  #NTSC_HMID,d2
		move.w  #NTSC_WIDTH,d0

		move.w  #NTSC_VMID,d6
		move.w  #NTSC_HEIGHT,d4

		bra 	calc_vals
palvals:
		move.w  #PAL_HMID,d2
		move.w  #PAL_WIDTH,d0

		move.w  #PAL_VMID,d6
		move.w  #PAL_HEIGHT,d4

calc_vals:
		move.w  d0,width
		move.w  d4,height

		move.w  d0,d1
		asr 	#1,d1         	 	; Width/2

		sub.w   d1,d2         	  	; Mid - Width/2
		add.w   #4,d2         	  	; (Mid - Width/2)+4

		sub.w   #1,d1         	  	; Width/2 - 1
		ori.w   #$400,d1      	  	; (Width/2 - 1)|$400
		
		move.w  d1,a_hde
		move.w  d1,HDE

		move.w  d2,a_hdb
		move.w  d2,HDB1
		move.w  d2,HDB2

		move.w  d6,d5
		sub.w   d4,d5
		move.w  d5,a_vdb

		add.w   d4,d6
		move.w  d6,a_vde

		move.w  a_vdb,VDB
		move.w  #$FFFF,VDE
			
		move.l  #0,BORD1        	; Black border
		move.w  #0,BG           	; Init line buffer to black
			
		movem.l (sp)+,d0-d6
		rts

;
;***
; InitLister: Initialize Object List Processor List
;
;    Returns: Pre-word-swapped address of current object list in d0.l
;
;  Registers: d0.l/d1.l - Phrase being built
;             d2.l/d3.l - Link address overlays
;             d4.l      - Work register
;             a0.l      - Roving object list pointer
		
InitLister:
		movem.l d1-d4/a0,-(sp)		; Save registers
			
		lea     op_mscrn_list,a0
		move.l  a0,d2           	; Copy

		add.l   #(LISTSIZE-1)*8,d2  	; Address of STOP object
		move.l	d2,d3			; Copy for low half

		lsr.l	#8,d2			; Shift high half into place
		lsr.l	#3,d2			; In phrases
		
		lsr.l	#3,d3			; In phrases
		swap	d3			; Place low half correctly
		clr.w	d3
		lsl.l	#8,d3

; Write first BRANCH object (branch if YPOS > a_vde )

		clr.l   d0
		move.l  #(BRANCHOBJ|O_BRLT),d1  ; $4000 = VC < YPOS
		or.l	d2,d0			; Do LINK overlay
		or.l	d3,d1
								
		move.w  a_vde,d4                ; for YPOS
		lsl.w   #3,d4                   ; Make it bits 13-3
		or.w    d4,d1

		move.l	d0,(a0)+
		move.l	d1,(a0)+

; Write second branch object (branch if YPOS < a_vdb)
; Note: LINK address is the same so preserve it

		andi.l  #$FF000007,d1           ; Mask off CC and YPOS
		ori.l   #O_BRGT,d1      	; $8000 = VC > YPOS
		move.w  a_vdb,d4                ; for YPOS
		lsl.w   #3,d4                   ; Make it bits 13-3
		or.w    d4,d1

		move.l	d0,(a0)+
		move.l	d1,(a0)+

; Write a standard MSCRN object
		move.l	d2,d0
		move.l	d3,d1

		ori.l  #MSCRN_HEIGHT<<14,d1       ; Height of image

		move.w  height,d4           	; Center MSCRN vertically
		sub.w   #MSCRN_HEIGHT,d4
		add.w   a_vdb,d4
		andi.w  #$FFFE,d4               ; Must be even
		lsl.w   #3,d4
		or.w    d4,d1                   ; Stuff YPOS in low phrase

		move.l	#_mscreen,d4
		lsl.l	#8,d4
		or.l	d4,d0

		move.l	d0,(a0)+
		move.l	d1,(a0)+
		movem.l	d0-d1,op_mscrn_update

; Second Phrase of MSCRN
		move.l	#MSCRN_PHRASES>>4,d0	; Only part of top LONG is IWIDTH
		move.l  #O_DEPTH16|O_NOGAP,d1   ; Bit Depth = 16-bit, Contiguous data

		move.w  width,d4            	; Get width in clocks
		lsr.w   #2,d4               	; /4 Pixel Divisor
		sub.w   #MSCRN_WIDTH,d4
		lsr.w   #1,d4
		or.w    d4,d1

		ori.l	#(MSCRN_PHRASES<<18)|(MSCRN_PHRASES<<28),d1	; DWIDTH|IWIDTH

		move.l	d0,(a0)+
		move.l	d1,(a0)+

; Write a STOP object at end of list
		clr.l   (a0)+
		move.l  #(STOPOBJ|O_STOPINTS),(a0)+

; Now return swapped list pointer in D0

		move.l  #op_mscrn_list,d0
		swap    d0

		movem.l (sp)+,d1-d4/a0
		rts

;***
; Procedure: UpdateList
;        Handle Video Interrupt and update object list fields
;        destroyed by the object processor.

UpdateList:
		move.l  a0,-(sp)

		move.l  #op_mscrn_list+MSCRN_OFF,a0

		move.l  op_mscrn_update,(a0)	; Phrase = d1.l/d0.l
		move.l  op_mscrn_update+4,4(a0)

		add.l	#1,ticks		; Increment ticks semaphore

		move.w  #$101,INT1      	; Signal we're done
		move.w  #$0,INT2

		move.l  (sp)+,a0
		rte


;
;***
;	ClearScreen
;

_ClearScrn::
	movem.l	d0-d1,-(sp)
	move.l	8+4(sp),d1
	move.l	#PITCH1 | PIXEL16 | WID320 | XADDPIX,d0
	move.l	d0,A1_FLAGS

; Point A1BASE to the data
	move.l	_v_bas_ad,d0
	move.l	d0,A1_BASE

; Set the pixel point to 0,0
	move.w	#0,d0			; y
	swap	d0
	move.w	#0,d0			; x
	move.l	d0,A1_PIXEL

; Set up the step size to -320 in x
; 1 in y
; The x step requires that the pixel pointer by 
	move.w	#1,d0			; y
	swap	d0
	move.w	#(-MSCRN_WIDTH),d0
	move.l	d0,A1_STEP

; Set up Counters register to 256 in x write long to clear upper
; 256 in y, or in y as a word

	move.w	#MSCRN_HEIGHT,d0		; y
	swap	d0
	move.w	#MSCRN_WIDTH,d0			; x
	move.l	d0,B_COUNT

; Put some data in the blitter for it to write
; This is a cheat I am using all 0 so there is 
; no need to word swap

	move.l	d1,B_PATD	
	move.l	d1,B_PATD+4	

; Now Turn IT ON !!!!!!!!!!!!!

; NO SOURCE DATA
; NO OUTER LOOP
; Turn on pattern data
; Allow outer loop update

	move.l	#PATDSEL|UPDA1,d0
	move.l	d0,B_CMD
	movem.l	(sp)+,d0-d1
	rts



;***  Data Section

	.data
	.phrase

_scrn_w:
	.dc.w    MSCRN_WIDTH		; Width of screen
_scrn_h:
	.dc.w    MSCRN_HEIGHT     	; Height of screen



setupKeybd:
	.dc.w	$7f, $f4, $ffff
setupMouse:
	.dc.w	$79, $98, $22, $ffff


;***  BSS Section / Starts at $4000 on Jaguar
	.bss
	.phrase
_mscreen:
	.ds.b MSCRN_WIDTH * MSCRN_HEIGHT * PPP / 2  ; memory for the screen

_supstk:
	.ds.b supsiz				; Super stack
_supstk_end:

	.phrase
_v_bas_ad:
   	.ds.l 1					; Screen pointer

		.dphrase
op_mscrn_list:  .ds.l   LISTSIZE*2  		; Object List
op_mscrn_update:.ds.l   2       		; One Phrase of MSCRN for Refresh
ticks:		.ds.l	1			; Incrementing # of ticks
a_hdb:  	.ds.w   1
a_hde:      	.ds.w   1
a_vdb:      	.ds.w   1
a_vde:      	.ds.w   1
width:      	.ds.w   1
height:     	.ds.w   1

		.long
olp2set:    	.ds.l   1           		; GPU Code Parameter


