
; falcon init/deinit code
; evil/dhs
; march 19, 1999
;
; videl store/restore by chris/aura & scandion/mugwumps
; syncfix vbl-patch by sage/escape
;
; the code for save and restore the screenmode has been tested with:
; - all standard resolutions (st and falcon modes)
; - screenblaster extended modes
; - blowup soft extended modes (even extended res in stshift mode!)
; - blowup hard 1 extended modes
; - blowup hard 2 extended modes
; - centscreen extended modes
; - vi2 extended modes
; - screenwonder extended modes
; - videlity extended modes
;
; the rest of the code sets up a screen in stram and 
; put the screenpointer to it. it does it the 'clean' way
; with mxalloc() for stram reservation. it makes the application
; accept fastram without problems.
;
; for customizing the videomodes, download "Screenpain" from
; http://dhs.atari.org filesection.
; 
; assembles with gen and assemble (and probably others as well)
; tablength 8

		section	text

init_program:
		move.l	4(sp),a5		;address to basepage
		move.l	$0c(a5),d0		;length of text segment
		add.l	$14(a5),d0		;length of data segment
		add.l	$1c(a5),d0		;length of bss segment
		add.l	#$1000,d0		;length of stackspace
		add.l	#$100,d0		;length of basepage
		move.l	a5,d1			;address to basepage
		add.l	d0,d1			;end of program
		and.l	#-2,d1			;make address even
		move.l	d1,sp			;new stackspace
		move.l	d0,-(sp)		;mshrink()
		move.l	a5,-(sp)		;
		move.w	d0,-(sp)		;
		move.w	#$4a,-(sp)		;
		trap	#1			;
		lea	12(sp),sp		;

		move.w	#0,-(sp)		;mxalloc() reserve stram for screen
		move.l	#320*240*2+256,-(sp)	;size of screen in bytes +256
		move.w	#$44,-(sp)		;
		trap	#1			;
		addq.l	#8,sp			;
		tst.l	d0			;check if there is stram enough
		beq.w	exit_nostram		;nope

		add.l	#256,d0			;align screen by 256 bytes
		clr.b	d0			;
		move.l	d0,screen_adr		;

		move.l	screen_adr,a0		;clear screen
		move.w	#320*240*2/64-1,d7	;
.clrloop:	rept	16			;
		clr.l	(a0)+			;
		endr				;
		dbra	d7,.clrloop		;

		clr.l	-(sp)			;get into supervisormode
		move.w	#32,-(sp)		;
		trap	#1			;
		addq.l	#6,sp			;
		lea.l	$ffff9800,a0		;save falcon palette
		lea.l	save_pal,a1		;
		move.w	#256-1,d7		;
.colloop:	move.l	(a0)+,(a1)+		;
		dbra	d7,.colloop		;
		movem.l	$ffff8240,d0-d7		;save st palette
		movem.l	d0-d7,(a1)		;

		lea.l	save_video,a0		;store videomode
		move.l	$ffff8200.w,(a0)+	;vidhm
		move.w	$ffff820c.w,(a0)+	;vidl
		move.l	$ffff8282.w,(a0)+	;h-regs
		move.l	$ffff8286.w,(a0)+	;
		move.l	$ffff828a.w,(a0)+	;
		move.l	$ffff82a2.w,(a0)+	;v-regs
		move.l	$ffff82a6.w,(a0)+	;
		move.l	$ffff82aa.w,(a0)+	;
		move.w	$ffff82c0.w,(a0)+	;vco
		move.w	$ffff82c2.w,(a0)+	;c_s
		move.l	$ffff820e.w,(a0)+	;offset
		move.w	$ffff820a.w,(a0)+	;sync
		move.b  $ffff8256.w,(a0)+	;p_o
		clr.b   (a0)			;test of st(e) or falcon mode
		cmp.w   #$b0,$ffff8282.w	;hht kleiner $b0?
		sle     (a0)+			;flag setzen
		move.w	$ffff8266.w,(a0)+	;f_s
		move.w	$ffff8260.w,(a0)+	;st_s

		move.l	screen_adr,d0		;set screen address
		move.b	d0,d1			;
		lsr.w   #8,d0			;
		move.b  d0,$ffff8203.w		;
		swap    d0			;
		move.b  d0,$ffff8201.w		;
		move.b  d1,$ffff820d.w		;
		move.l	d0,save_stack		;

		lea.l	$ffff9800,a0		;save falcon palette
		lea.l	save_pal,a1		;
		move.w	#256-1,d7		;
.colloop:	move.l	(a0)+,(a1)+		;
		dbra	d7,.colloop		;
		movem.l	$ffff8240,d0-d7		;save st palette
		movem.l	d0-d7,(a1)		;

		lea.l	save_video,a0		;store videomode
		move.l	$ffff8200.w,(a0)+	;vidhm
		move.w	$ffff820c.w,(a0)+	;vidl
		move.l	$ffff8282.w,(a0)+	;h-regs
		move.l	$ffff8286.w,(a0)+	;
		move.l	$ffff828a.w,(a0)+	;
		move.l	$ffff82a2.w,(a0)+	;v-regs
		move.l	$ffff82a6.w,(a0)+	;
		move.l	$ffff82aa.w,(a0)+	;
		move.w	$ffff82c0.w,(a0)+	;vco
		move.w	$ffff82c2.w,(a0)+	;c_s
		move.l	$ffff820e.w,(a0)+	;offset
		move.w	$ffff820a.w,(a0)+	;sync
		move.b  $ffff8256.w,(a0)+	;p_o
		clr.b   (a0)			;test of st(e) or falcon mode
		cmp.w   #$b0,$ffff8282.w	;hht kleiner $b0?
		sle     (a0)+			;flag setzen
		move.w	$ffff8266.w,(a0)+	;f_s
		move.w	$ffff8260.w,(a0)+	;st_s

		move.l	screen_adr,d0		;set screen address
		move.b	d0,d1			;
		lsr.w   #8,d0			;
		move.b  d0,$ffff8203.w		;
		swap    d0			;
		move.b  d0,$ffff8201.w		;
		move.b  d1,$ffff820d.w		;

		move.w	#$59,-(sp)		;check monitortype
		trap	#14			;
		addq.l	#2,sp			;

		tst.w	d0			;if mono, exit directly
		beq.w	exit_mono		;
		cmp.w	#2,d0			;check for vga
		beq.s	.vga			;if vga, set vga
		bra.s	.rgb			;if not vga, default to rgb/tv
		
.vga:		move.l	#$c6008D,$ffff8282.w	;vga 60Hz 320*240 hicolour
		move.l	#$1502ac,$ffff8286.w	;saved by screenspain
		move.l	#$8D0097,$ffff828a.w	;
		move.l	#$41903ff,$ffff82a2.w	;
		move.l	#$3f003D,$ffff82a6.w	;
		move.l	#$3fD0415,$ffff82aa.w	;
		move.w	#$200,$ffff820a.w	;
		move.w	#$186,$ffff82c0.w	;
		clr.w	$ffff8266.w		;
		move.w	#$100,$ffff8266.w	;
		move.w	#$5,$ffff82c2.w		;
		move.w	#$140,$ffff8210.w	;
		bra.s	.video_done
.rgb:		move.l	#$c700a0,$ffff8282.w	;rgb 50Hz 320*240 hicolour
		move.l	#$1f0003,$ffff8286.w	;saved by screenspain
		move.l	#$9b00ab,$ffff828a.w	;
		move.l	#$2710265,$ffff82a2.w	;
		move.l	#$2f0059,$ffff82a6.w	;
		move.l	#$239026b,$ffff82aa.w	;
		move.w	#$200,$ffff820a.w	;
		move.w	#$185,$ffff82c0.w	;
		clr.w	$ffff8266.w		;
		move.w	#$100,$ffff8266.w	;
		move.w	#$0,$ffff82c2.w		;
		move.w	#$140,$ffff8210.w	;
.video_done:

main_program:

; ----------------------------------------------
		move.w	#7,-(sp)		;wait for keypress
		trap	#1			;
		addq.l	#2,sp			;
; ----------------------------------------------



exit_program:	lea.l	save_video,a0		;restore video
		clr.w   $ffff8266.w		;falcon-shift clear
		move.l	(a0)+,$ffff8200.w	;videobase_address:h&m
		move.w	(a0)+,$ffff820c.w	;l
		move.l	(a0)+,$ffff8282.w	;h-regs
		move.l	(a0)+,$ffff8286.w	;
		move.l	(a0)+,$ffff828a.w	;
		move.l	(a0)+,$ffff82a2.w	;v-regs
		move.l	(a0)+,$ffff82a6.w	;
		move.l	(a0)+,$ffff82aa.w	;
		move.w	(a0)+,$ffff82c0.w	;vco
		move.w	(a0)+,$ffff82c2.w	;c_s
		move.l	(a0)+,$ffff820e.w	;offset
		move.w	(a0)+,$ffff820a.w	;sync
	        move.b  (a0)+,$ffff8256.w	;p_o
	        tst.b   (a0)+   		;st(e) comptaible mode?
        	bne.s   .ok
		move.l	a0,-(sp)		;wait for vbl
		move.w	#37,-(sp)		;to avoid syncerrors
		trap	#14			;in falcon monomodes
		addq.l	#2,sp			;
		movea.l	(sp)+,a0		;
	       	move.w  (a0),$ffff8266.w	;falcon-shift
		bra.s	.video_restored
.ok:		move.w  2(a0),$ffff8260.w	;st-shift
		lea.l	save_video,a0
		move.w	32(a0),$ffff82c2.w	;c_s
		move.l	34(a0),$ffff820e.w	;offset		
.video_restored:

		lea.l	$ffff9800,a0		;restore falcon palette
		lea.l	save_pal,a1		;
		move.w	#256-1,d7		;
.loop2:		move.l	(a1)+,(a0)+		;
		dbra	d7,.loop2		;
		movem.l	(a1),d0-d7		;restore st palette
		movem.l	d0-d7,$ffff8240		;

		move.l	save_stack,-(sp)	;exit super
		move.w	#32,-(sp)		;
		trap	#1			;
		addq.l	#6,sp			;
exit_nostram:
exit_mono:	clr.w	-(sp)			;exit
		trap	#1			;


		section	bss

screen_adr:	ds.l	1			;screen address
save_video:	ds.b	32+12+2			;videl save
save_pal:	ds.l	256+8			;palette save
save_stack:	ds.l	1			;userstack save
