	Page	58,132
	Title	GITA.ASM	ANTIC emulator
;******************************************************************************
;
;   Name:	GITA
;
;   Group:	Emulator
;
;   Revision:	0.00
;
;   Date:  07-13-94
;
;   Author: Michael Munoz
;
;******************************************************************************
;
;  Module Functional Description:
;
;	This routine implements player/missle graphics
;
;
;******************************************************************************
;
;  Changes:
;
;    DATE     REVISION				DESCRIPTION
;  --------   --------	-------------------------------------------------------
;
;******************************************************************************
	Page
;
;  Public Declarations
;
	Public	Player_Missle
	Public	Gita_Update
	Public	Gita_ram
	Public  Gita_nmiflag
	Public	PM_Data
;  External Declarations
;
	Extrn	Antic_pc:Word
	Extrn	Antic_evcount:Word
	Extrn	Antic_memscan:Word
	Extrn	Antic_vscrol:Byte
	Extrn	Antic_sc:Byte
	Extrn	Video_Pntr_Cur:Word
	Extrn	Video_Pntr_Old:Word
	Extrn	sTOP:Word
	Extrn	sBOT:Word
	Extrn	COUNT_Table:Byte
	Extrn	Flag_Encode:Byte
	Extrn	Exit:Near
;
;  LOCAL Equates
;
;
;  Define any include files needed
;
	Include 	Macros.inc	; Include the macro definitions
	Include 	Equates.inc	; Include the equate definitions
	Include		Atari.inc	; Atari equates

;	MACROS

Clear_Data	macro
local Clear_Loop
	mov	di,255d
Clear_Loop:
	mov     Byte Ptr PM_Data[di],0
	dec	di
	jne	Clear_Loop
	endm

	.286c				; Include 80286 instructions
	Page
;
;  Define the emulator code segment
;
Emulate Segment Word Public 'EMULATE'   ; Emulator code segment
	Assume	cs:Emulate, ds:Nothing, es:Nothing

;Memory for GITA
Gita_nmiflag	DB	0
scan_line	DW	0
index_i		DW	0
index_k		DW	0
repeat_line	DB	0
PM_Offset	DW	0
PMwidth		DW	0
Stat_all	DB	0
Stat_P0		DB	0
Stat_P1		DB	0
Stat_P2		DB	0
Stat_P3		DB	0
p0base		DW	0
p1base		DW	0
p2base		DW	0
p3base		DW	0
mbase		DW	0
width_M0	DB	0
width_M1	DB	0
width_M2	DB	0
width_M3	DB	0
width_P0	DB	0
width_P1	DB	0
width_P2	DB	0
width_P3	DB	0

;******************************************************************************
;
;	Update Gita pseudo registers
;
;	Entry:
;	al: data
;       di: EA
;
;	uses: di,ax
;
;******************************************************************************
 Gita_Update	Proc	Near
	cmp	di,HITCLR		;do we need to clear all collisions
	jne	Gita_Update_Speak	;no
	mov	di,M0PF			; starting address of collision regs
	mov	ax,08h
Gloop:
	mov	Word Ptr [di],0
	add	di,2
	dec	ax
	jne	Gloop
	ret
Gita_Update_Speak:
	cmp	di,CONSOL
	jne	Gita_Update_Exit
	shr	al,3
	out	061h,al			; write to speaker
Gita_Update_Exit:
	and	di,01fh			;update antic ram space...
	mov	Gita_ram[di],al		;just in case
	ret
 Gita_Update	Endp

;******************************************************************************
;
;	Write Player/Missle data to the IBM display
;
;	Entry:
;
;	uses: di,ax,bx, bp
;
;******************************************************************************
	Even
Player_Missle	Proc	Near
; see if we need to display anything
	cmp	cs:Antic_sc,0			; did Antic display anything?
	jne	Check_GRACTL
	jmp	Player_Missle_Done		; no, exit
Check_GRACTL:
	; See if DMA from Antic to Gita is Enabled
	mov	di,LB_GRACTL			; player/missile enabled?
	mov	al,Gita_ram[di]			; get the bits in GRACTL
	test	al,B1 or B0			; test bits 1 and 0
	jne	Check_PMBASE_Valid
	jmp 	Player_Missle_Done		; if 0, nothing to display

Check_PMBASE_Valid:
	; get the player missle pointer
	mov	di,LB_PMBASE
	mov	bh,Antic_ram[di]
	xor	bl,bl				; pmabase*256
	cmp	bh,0              		; base cannot be zero
	jne	Check_On_Screen
	jmp	Player_Missle_Done

Check_On_Screen:
	mov	ax,cs:Antic_evcount		; is the current scan line
	cmp	ax,32d				; on the screen
	jge	On_Top_Screen
	jmp	Player_Missle_Done		; no, exit
On_Top_Screen:
	cmp	ax,232d
	jl	On_Screen
	jmp	Player_Missle_Done		; off bottom of screen
On_Screen:

PM_Display_Start:
	; I guess were going to need to use these registers
	pusha

	mov	bp,cs:Video_Pntr_Old		; get start of IBM display

	; one scan line or two scan lines
	mov	di,LB_DMACTL
	mov	al,Antic_ram[di]
	test	al,B4
	je	Two_Scan_Lines
	add	bx,300h				; start of PM data
	mov	cx,100h				; each player is 256 bytes
	mov	cs:repeat_line,1		; no repeat
	mov	al,cs:Antic_sc
	xor	ah,ah
	mov	index_i,ax			; setup scan line loop index
	jmp	Over_Two_Scan_Lines
Two_Scan_Lines:
	add	bx,180h
	mov	cx,80h
	mov	cs:repeat_line,2		; repeat scan line
	mov	al,cs:Antic_sc
	xor	ah,ah
	shr	ax,1				; divide by 2
	jne	Not_Zero
	inc	ax
Not_Zero:
	mov	index_i,ax			; setup scan line loop index
Over_Two_Scan_Lines:

; get the base address for the players and missles
	add	bx,cs:Antic_evcount
	sub	bx,8d
	mov	cs:mbase,bx
	add     bx,cx
	mov	cs:p0base,bx
	add     bx,cx
	mov	cs:p1base,bx
	add     bx,cx
	mov	cs:p2base,bx
	add     bx,cx
	mov	cs:p3base,bx

	; Ignore Priority register (for now)
	; Write Players and missles to screen in the following order:
	; p3,m3,p2,m2,p1,m2,p0,m0

	mov	cs:Stat_all,0		; see if any
	mov	ah,0h
	mov	bx,0d0h
	; See which players need to be written
Check_P3:
	mov	cs:Stat_P3,0            ; assume no player write
	mov 	di,LB_HPOSP3
	mov	al,Gita_ram[di]
	cmp	ax,10h			; Is Player off left side screen?
	jle	Check_P2		; jmp if off screen
	cmp	bx,ax			; Is player off right side of screen?
	jle	Check_P2		; jmp if off screen
	mov	cs:Stat_P3,1		; enable player write
	mov	cs:Stat_all,1
Check_P2:
	mov	cs:Stat_P2,0            ; assume no player write
	mov 	di,LB_HPOSP2
	mov	al,Gita_ram[di]
	cmp	ax,10h			; Is Player off left side screen?
	jle	Check_P1		; jmp if off screen
	cmp	bx,ax			; Is player off right side of screen?
	jle	Check_P1		; jmp if off screen
	mov	cs:Stat_P2,1		; enable player write
	mov	cs:Stat_all,1
Check_P1:
	mov	cs:Stat_P1,0            ; assume no player write
	mov 	di,LB_HPOSP1
	mov	al,Gita_ram[di]
	cmp	ax,10h			; Is Player off left side screen?
	jle	Check_P0		; jmp if off screen
	cmp	bx,ax			; Is player off right side of screen?
	jle	Check_P0		; jmp if off screen
	mov	cs:Stat_P1,1		; enable player write
	mov	cs:Stat_all,1
Check_P0:
	mov	cs:Stat_P0,0            ; assume no player write
	mov 	di,LB_HPOSP0
	mov	al,Gita_ram[di]
	cmp	ax,10d			; Is Player off left side screen?
	jle	End_Check		; jmp if off screen
	cmp	bx,ax			; Is player off right side of screen?
	jle	End_Check		; jmp if off screen
	mov	cs:Stat_P0,1		; enable player write
	mov	cs:Stat_all,1
End_Check:

	cmp	cs:Stat_all,0
	jne	Get_Width
	jmp	PM_Display_Done
Get_Width:

	; get width of each missle bit
	mov	di,LB_SIZEM
	mov	al,Gita_ram[di]
	mov	ah,al
	and	ah,3
	add	ah,1
	mov	cs:width_M0,ah
	shr	al,2
	mov	ah,al
	and	ah,3
	add	ah,1
	mov	cs:width_M1,ah
	shr	al,2
	mov	ah,al
	and	ah,3
	add	ah,1
	mov	cs:width_M2,ah
	shr	al,2
	mov	ah,al
	and	ah,3
	add	ah,1
	mov	cs:width_M3,ah

	; get width for each player bit
	mov	di,LB_SIZEP0
	mov	al,Gita_ram[di]
	inc	al
	mov	cs:width_P0,al
	mov	di,LB_SIZEP1
	mov	al,Gita_ram[di]
	inc	al
	mov	cs:width_P1,al
	mov	di,LB_SIZEP2
	mov	al,Gita_ram[di]
	inc	al
	mov	cs:width_P2,al
	mov	di,LB_SIZEP3
	mov	al,Gita_ram[di]
	inc	al
	mov	cs:width_P3,al

Construct_Players_Loop:
	xor	ch,ch
       Clear_Data

Construct_P3:
	; write player 3
	cmp	Stat_P3,1		; is player three visible?
	jne	Construct_P2		; if not, try player 2
	mov	di,LB_HPOSP3		; get the horizontal position
	mov	bl,Gita_ram[di]		; of player 3
	xor	bh,bh
	mov	di,p3base		; copy pmbase to di
	mov	dh,[di]			; get player display byte
	mov	dl,8			; loop to display each bit
Bit_Loop_P3:
	mov	cl,width_P3             ; get width of player bits
	rcl	dh,1                    ; get player bit in carry
	jnc	No_Display_P3           ; if it's zero, display nothing
Pixel_Loop_P3:
	mov	Byte Ptr PM_Data[bx],LB_COLPM3  ; write the color
	inc	bx
	dec	cl
	jne	Pixel_Loop_P3
	jmp	Next_Bit_P3
No_Display_P3:
	add	bx,cx
Next_Bit_P3:
	dec	dl
	jne	Bit_Loop_P3

Construct_P2:
	; write player 2
	cmp	Stat_P2,1
	jne	Construct_P1
	mov	di,LB_HPOSP2
	mov	bl,Gita_ram[di]
	xor	bh,bh
	mov	di,p2base		; get pmbase
	mov	dh,[di]			; get player byte
	mov	dl,8			; for each bit
Bit_Loop_P2:
	mov	cl,width_P2
	rcl	dh,1
	jnc	No_Display_P2
Pixel_Loop_P2:
	mov	Byte Ptr PM_Data[bx],LB_COLPM2
	inc	bx
	dec	cl
	jne	Pixel_Loop_P2
	jmp	Next_Bit_P2
No_Display_P2:
	add	bx,cx
Next_Bit_P2:
	dec	dl
	jne	Bit_Loop_P2

Construct_P1:
	; write player 1
	cmp	Stat_P1,1
	jne	Construct_P0
	mov	di,LB_HPOSP1
	mov	bl,Gita_ram[di]
	xor	bh,bh
	mov	di,p1base		; get pmbase
	mov	dh,[di]			; get player byte
	mov	dl,8			; for each bit
Bit_Loop_P1:
	mov	cl,width_P1
	rcl	dh,1
	jnc	No_Display_P1
Pixel_Loop_P1:
	mov	Byte Ptr PM_Data[bx],LB_COLPM1
	inc	bx
	dec	cl
	jne	Pixel_Loop_P1
	jmp	Next_Bit_P1
No_Display_P1:
	add	bx,cx
Next_Bit_P1:
	dec	dl
	jne	Bit_Loop_P1

Construct_P0:
	; write player 0
	cmp	Stat_P0,1
	jne	Construct_End
	mov	di,LB_HPOSP0
	mov	bl,Gita_ram[di]
	xor	bh,bh
	mov	di,p0base		; get pmbase
	mov	dh,[di]			; get player byte
	mov	dl,8			; for each bit
Bit_Loop_P0:
	mov	cl,width_P0
	rcl	dh,1
	jnc	No_Display_P0
Pixel_Loop_P0:
	mov	Byte Ptr PM_Data[bx],LB_COLPM0
	inc	bx
	dec	cl
	jne	Pixel_Loop_P0
	jmp	Next_Bit_P0
No_Display_P0:
	add	bx,cx
Next_Bit_P0:
	dec	dl
	jne	Bit_Loop_P0

Construct_End:
	mov	al,repeat_line
	xor	ah,ah
	mov     index_k,ax

Repeat_Scan_Loop:

	mov	si,30h			; start of pm display
	xor	bh,bh			; set bh to 0
Write_Data_Loop:
	mov	bl,PM_Data[si]
	cmp	bl,0
	je	No_Write		; nothing to write
	mov	al,Gita_ram[bx]		; get color
	mov	es:[bp],al
	mov	es:[bp+1],al
No_Write:
	add	bp,2
	inc	si
	cmp	si,0d0h			; end of pm display
	jne	Write_Data_Loop

	dec	index_k			; loop for double scan lines
	je	Repeat_Scan_Done
	jmp	Repeat_Scan_Loop
Repeat_Scan_Done:
	inc	cs:mbase
	inc	cs:p0base
	inc	cs:p1base
	inc	cs:p2base
	inc	cs:p3base
	dec	index_i
	je	Construct_Players_Done
	jmp	Construct_Players_Loop
Construct_Players_Done:

PM_Display_Done:
	popa
Player_Missle_Done:
	ret
Player_Missle	endp
;*****************************************************************************
;
;	Define the end of the Emulator Code Segment
;
;******************************************************************************
Emulate Ends
	End				; End of the Hardware module
