; CGX-Direct driver (need 352x262 8 bit screen)
; External Video Driver for
; Flaming Plus/4 emulator for the Amiga
;
; version 1.1
; 1.2: added MODULO support (08.07.99)
; 1.3: added config support (12.07.99)

TRUE	equ	1
FALSE	equ	0
        INCDIR	Include3.1:

	INCLUDE exec/types.i
	INCLUDE	exec/memory.i
	INCLUDE	exec_lib.i
	INCLUDE	utility/tagitem.i
	INCLUDE	intuition/intuition.i
	INCLUDE	intuition_lib.i
	INCLUDE	intuition/screens.i
	INCLUDE graphics/modeid.i
	INCLUDE	graphics/rastport.i
;	INCLUDE	macros.i
	INCLUDE	libraries/cybergraphics_lib.i
	INCLUDE	cybergraphics/cybergraphics.i
	INCLUDE	dos_lib.i
	INCLUDE	dos/dostags.i
	INCLUDE	dos/dosextens.i
	INCLUDE	dos/var.i



;*** Handler structure

 STRUCTURE vxd_handler,0

  LONG intuibase
  LONG dosbase
  LONG myscr
  LONG mywin
  LONG planes
  WORD xsize
  WORD ysize
  LONG palette
  LONG palette32
  LONG emuscr
  WORD bytesperrow
  LONG cybbase
  LONG screendim
 LABEL	vxd_handler_SIZEOF


JSRLIB	MACRO
	jsr	_LVO\1(a6)
	ENDM

;*** Let's begin

	moveq.l	#0,d0
	rts

	dc.b "FLAMINGOXVD"
	dc.b "1"

	dc.l Name
	dc.l Author
	dc.w 1
	dc.w 3

	dc.l drv_Init
	dc.l drv_Done
	dc.l drv_Configure
	dc.l drv_OpenScreen
	dc.l drv_CloseScreen
	dc.l drv_Refresh

Name:	dc.b	"CGX-Direct External Video Driver 1.3 (12.07.99)",0
Author:	dc.b	"László (pH03N1x) Török",0

	EVEN

;*** Functions

drv_Init:
	movem.l	a0-a1,-(sp)	;Saving infos
	move.l  4.w,a6		;Alloc memory for handler
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	move.l	#vxd_handler_SIZEOF,d0
	JSRLIB	AllocVec
	movem.l	(sp)+,a0-a1	;Recover infos
        tst.l	d0
	beq.b	b1		;No mem
	movea.l	d0,a2

        move.l	4(a0),dosbase(a2)	;Saving dos.library base
        move.l	8(a0),intuibase(a2)	;Saving intuition.library base

        movem.l	d0,-(sp)
	move.l	dosbase(a2),a6		;Reading config file
	move.l	#configfile,d1		;Config file is pretty simple:
	move.l	#MODE_OLDFILE,d2	;only a screenmode number
	JSRLIB	Open
	tst.l	d0
	beq.b	.2			;Failed open
	move.l	d0,d1
	move.l	(sp),a0
	lea	screendim(a0),a0
	move.l	a0,d2
	moveq.l	#4,d3
	movem.l	d0,-(sp)
	JSRLIB	Read			;Reading the 4 bytes
	cmp.l	#4,d0
	beq.b	.3
	move.l	(sp),a0			;Failed: set 0 instead garbage
	move.l	#0,screendim(a0)

.3	movem.l	(sp)+,d1
	JSRLIB	Close

.2	movem.l	(sp)+,d0

b1	move.l	#err_nomem,d1		;Ignored, if D0 not 0
	rts				;Result in D0 available for now

drv_Done:
	movea.l	a0,a1
	tst.l	a1
	beq.b	c1
	move.l	4.w,a6
	JSRLIB	FreeVec		;Deallocate handler
c1
	rts


drv_Configure:			;Configure
				;A simple screenmode requester appears
	movem.l	a0,-(sp)

	move.l	a0,a5
	move.l	screendim(a5),ScrDisplayID

	moveq	#$00,d0
	moveq	#$00,d1
	move.w	xsize(a5),d0
	move.w	ysize(a5),d1

	move.l	d0,cgfxmodewidth
	move.l	d1,cgfxmodeheight

	move.l	4.w,a6
	lea	cyblib(pc),a1
	moveq	#40,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,cybbase(a5)
	beq.b	configbug

	move.l	cybbase(a5),a6
	lea	cybreqtags(pc),a1
	jsr	_LVOCModeRequestTagList(a6)

	cmp.l	#INVALID_ID,d0
	bne.b	config2

	move.l	(4).w,a6
	move.l	cybbase(a5),a1
	jsr	_LVOCloseLibrary(a6)
	clr.l	cybbase(a5)

configbug:
	suba.l	a0,a0
	move.l	intuibase(a5),a6
	jsr	_LVODisplayBeep(a6)
	lea	4(sp),sp
	rts

config2:
	move.l	d0,screendim(a5)
	
	move.l	dosbase(a5),a6		;Writing config file
	move.l	#configfile,d1		;Config file is pretty simple:
	move.l	#MODE_NEWFILE,d2	;only a screenmode number
	JSRLIB	Open
	tst.l	d0
	beq.b	.1			;Failed open
	move.l	d0,d1
	move.l	(sp),a0
	lea	screendim(a0),a0
	move.l	a0,d2
	moveq.l	#4,d3
	movem.l	d0,-(sp)
	JSRLIB	Write			;Writing the 4 bytes

	movem.l	(sp)+,d1		;We don't care too much on
	JSRLIB	Close			;success...

.1
	move.l	(4).w,a6
	move.l	cybbase(a5),a1
	jsr	_LVOCloseLibrary(a6)
	clr.l	cybbase(a5)

	movem.l	(sp)+,a0
	rts



drv_OpenScreen:
	movea.l a0,a5

	move.l	screendim(a0),ScrDisplayID

	move.w	(a1)+,xsize(a5)
	move.w	(a1)+,ysize(a5)
	move.l	(a1)+,palette(a5)

	move.l	4.w,a6
	lea	cyblib(pc),a1
	moveq	#40,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,cybbase(a5)
	beq.w	e0

	move.w	xsize(a5),cybwidth+2
	move.w	ysize(a5),cybheight+2

	tst.l	ScrDisplayID(pc)
	bne.b	modeisready

	moveq	#$00,d0
	moveq	#$00,d1
	move.w	xsize(a5),d0
	move.w	ysize(a5),d1

	lea	cybmodetags(pc),a0
	move.l	cybbase(a5),a6
	jsr	_LVOBestCModeIDTagList(a6)
	move.l	d0,ScrDisplayID

modeisready:
	move.l	4.w,a6
	move.l	#MEMF_PUBLIC,d1
	move.l	#128*3*4+8,d0
	JSRLIB	AllocVec
	move.l	d0,palette32(a5)	;Convert palette to 32 bit per gun
	beq.w	e1
	movea.l	d0,a0
        move.l	palette(a5),a1
	move.w	#128,(a0)+
	move.w	#$0,(a0)+
	move.l	#128*3-1,d2
e2	moveq.l	#0,d0
	move.b	(a1)+,d0
	swap	d0
	asl.l	#8,d0
	move.l	d0,(a0)+
	dbf	d2,e2
	move.l	#0,(a0)
	move.w	xsize(a5),width+2
	move.w	ysize(a5),height+2
	move.l	palette32(a5),pal

        suba.l	a0,a0			;No newscreen stuct
        lea	scrtags,a1
	movea.l	intuibase(a5),a6
	JSRLIB	OpenScreenTagList

	move.l	d0,wscr
	move.l	d0,myscr(a5)
	beq.b	e1


	move.l	d0,a1
	lea	sc_RastPort(a1),a1
	move.l	rp_BitMap(a1),a0
	lea	cgfxlocktags(pc),a1
	move.l	cybbase(a5),a6
	jsr	_LVOLockBitMapTagList(a6)	;d0 = lock

	move.l	gfxboarddirectmem(pc),emuscr(a5)
	
	move.l	d0,a0				;bitlock
	jsr	_LVOUnLockBitMap(a6)

	movea.l	intuibase(a5),a6
	move.w	xsize(a5),wwidth+2
	move.w	ysize(a5),wheight+2
	suba.l	a0,a0
	lea	wintags,a1
	JSRLIB	OpenWindowTagList
	move.l	d0,mywin(a5)
	beq.b	e1
	movea.l	d0,a1

	move.l  wd_UserPort(a1),d0		;IDCMP port
	move.l	emuscr(a5),d2			;chunky buffer
	move.l	GfxBoardBitmapWidth(pc),d3	;modulo (CV64 miatt ez az egyeduli korrekt mod)

	sub.w	xsize(a5),d3			;modulo fix
	
e0:	move.l	#err_cyblib,d1
	rts


e1	move.l	#err_noscr,d1
	rts

drv_CloseScreen:

	move.l	a0,a5
	
	tst.l	cybbase(a5)
	beq.b	nemcyb
	move.l	(4).w,a6
	move.l	cybbase(a5),a1
	jsr	_LVOCloseLibrary(a6)
	clr.l	cybbase(a5)

nemcyb:	move.l	intuibase(a5),a6
	move.l	mywin(a5),a0
	tst.l	a0
	beq.b	f1
	JSRLIB	CloseWindow

f1	move.l	myscr(a5),a0
	tst.l	a0
	beq.b	f2
	JSRLIB	CloseScreen

f2	movea.l	palette32(a5),a1
        tst.l	a1
	beq.b	f3
	move.l	4.w,a6
	JSRLIB	FreeVec		;Deallocate translated palette

f3:	move.l	d0,emuscr(a5)	;They were already freed
	move.l	d0,palette32(a5)
	move.l	d0,myscr(a5)
	move.l	d0,mywin(a5)

	rts

drv_Refresh:

	move.l	emuscr(a0),d0
        RTS

;*** Constants


cyblib:		dc.b	"cybergraphics.library",0


scrtags:
	dc.l    SA_Width
width:	dc.l	0
	dc.l	SA_Height
height:	dc.l	0
	dc.l	SA_Depth,8
	dc.l	SA_Colors32
pal:	dc.l	0
	dc.l	SA_Title,scrtitle
	dc.l	SA_ShowTitle,FALSE
	dc.l	SA_DisplayID

ScrDisplayID:
	dc.l	0

	dc.l	SA_Type,CUSTOMSCREEN
	dc.l	SA_AutoScroll,TRUE
	dc.l	SA_Overscan,OSCAN_STANDARD
	dc.l	SA_Quiet,TRUE
	dc.l	TAG_DONE

wintags:
	dc.l    WA_Left,0
	dc.l	WA_Top,0
	dc.l	WA_Width
wwidth:	dc.l	0
	dc.l	WA_Height
wheight:	dc.l    0
	dc.l	WA_IDCMP,IDCMP_RAWKEY
	dc.l    WA_Title,0
	dc.l	WA_Backdrop,TRUE
	dc.l	WA_RMBTrap,TRUE
	dc.l	WA_Borderless,TRUE
	dc.l	WA_NoCareRefresh,TRUE
	dc.l	WA_CustomScreen
wscr:	dc.l    0
	dc.l	WA_SimpleRefresh,TRUE
	dc.l	WA_Activate,TRUE
	dc.l	TAG_DONE

scrtitle:	dc.b	'Flamingo Plus/4 emulator screen',0
		EVEN

configfile:	dc.b	'cgfx.cfg',0
		EVEN
		
cybmodetags:
		dc.l	CYBRBIDTG_Depth,8
		dc.l	CYBRBIDTG_NominalWidth
cybwidth:	dc.l	0		
		dc.l	CYBRBIDTG_NominalHeight
cybheight:	dc.l	0
		dc.l	TAG_END


cgfxlocktags:	dc.l	LBMI_BASEADDRESS
		dc.l	gfxboarddirectmem
		dc.l	LBMI_BYTESPERROW
		dc.l	GfxBoardBitmapWidth	

		dc.l	TAG_END

gfxboarddirectmem:
		dc.l	0
GfxBoardBitmapWidth:
		dc.l	0

cybreqtags:	
		dc.l	CYBRMREQ_MinWidth
cgfxmodewidth:	dc.l	0		
		dc.l	CYBRMREQ_MinHeight
cgfxmodeheight:	dc.l	0
		dc.l	CYBRMREQ_MinDepth
cgfxmodedepth:	dc.l	8
		dc.l	CYBRMREQ_MaxDepth
cgfxmaxdepth:	dc.l	8
		dc.l	CYBRMREQ_CModelArray
cgfxpixform:	dc.l	cybreqcolors256
		dc.l	TAG_END

cybreqcolors256:
		dc.l	PIXFMT_LUT8
		dc.l	TAG_END


;*** Errors

err_nomem:
	dc.b	'Run out of memory',0
err_noscr:
	dc.b	'Cannot open screen',0
err_cyblib:
	dc.b	'Cannot open cybergraphics.library v40+',0

