;**************************************************************************
;*
;* text mode width test
;*
;**************************************************************************
	
	org $2000			   ;prg start
	
	icl "custom.i"

START:

	
	;

	sei				  ;disable irqs
	lda	#$00
	sta	NMIEN			  ;NMIEN all off 
	sta	DMACTL			  ;DMACTL all off

	;set display list (use shadow regs)
	
	lda	#<displayList
	sta	DLISTL	
	lda	#>displayList
	sta	DLISTH
	
	;set display list interrupt
	  
	lda	#<dli_irq
        sta	VDSLSTL           
        lda	#>dli_irq
        sta	VDSLSTH    
	
	;vertical blank interrupt 
	
	lda 	#>vbi_irq
	sta	VVBLKIH	
	lda 	#<vbi_irq
	sta	VVBLKIL	
	
	;os key remove
	
	lda	#<noKeyRead
        sta	VSERINL        
        lda	#>noKeyRead
        sta	VSERINH        
	
	;chbase
	
	lda	#$E0
	sta	CHBASE
	
	;color setup
	
	lda	#$0	
	sta	COLBK
	lda	#$a	
	sta	COLPF0
	lda	#$e	
	sta	COLPF1
	lda	#$8	
	sta	COLPF2
	lda	#$88				
	sta	COLPF3
				
	;disable player/missile dma
	
	lda	#$00
	sta	GRACTL
	
	;setup displays
	   
	lda	#DMACTL_DL|DMACTL_PF_NORMAL		
		
		;enable display list dma 			
		;playfield normal display (40)
			
	sta	DMACTL	;DMACTL
	
	lda	#$0
	sta	HSCROL
	
	;enable dli
	
	lda	#NMIEN_VBI|NMIEN_DLI
	sta	NMIEN	;VBI + DLI enbable
	
	;
	
	cli		;irq enable
	
	;*********************************************************
	;get ram top
	;*********************************************************
	
.define	RAMTOP  	$006A
	
	
	lda	#<ramTopStr
	sta	ZA0
	lda	#>ramTopStr
	sta	ZA0+1
	ldx	RAMTOP			;/4 = kBytes ($40 = 16kB, $40 = 32kB, $c0 = 48kB)
	jsr	valueToHex
	
	;check PORTB (is MMU (R/W) or only Joystick2/3 in (R))
	
	lda	PORTB
	tax
	eor	#$ff	;not
	sta	PORTB
	cpx	PORTB	;same date (write no work)
	beq	?noMMU
	lda	#1
	sta	hasMMU	;default zero
?noMMU	stx	PORTB	;restore
	
	;draw has mmu string
	
	lda	hasMMU
	beq	?noText
	lda	#<yesStr
	sta	ZA0
	lda	#>yesStr
	sta	ZA0+1
	jmp	?yesTextSet
	
?noText	lda	#<noStr
	sta	ZA0
	lda	#>noStr
	sta	ZA0+1
?yesTextSet	
	
	lda	#<hasMMUStr
	sta	ZA1
	lda	#>hasMMUStr
	sta	ZA1+1
	
	jsr	copyString
	
	;*********************************************************
	;check banks
	;*********************************************************
	
.define	BANK1_IDENT	$12	
.define	BANK2_IDENT	$34
.define	BANK3_IDENT	$56
.define	BANK4_IDENT	$78
.define BANK_ADR	$4000+2048	;skip tileset
	
	ldx	#%00		;bank 0
	jsr	setBank
	lda	#BANK1_IDENT
	sta	BANK_ADR
	
	ldx	#%01		;bank 1
	jsr	setBank
	lda	#BANK2_IDENT
	sta	BANK_ADR
	
	ldx	#%10		;bank 2
	jsr	setBank
	lda	#BANK3_IDENT
	sta	BANK_ADR
	
	ldx	#%11		;bank 3
	jsr	setBank
	lda	#BANK3_IDENT
	sta	BANK_ADR
	
	ldx	#%100		;bank normal
	jsr	setBank
	lda	#0		;clear
	sta	BANK_ADR
	
	;
	
	ldx	#%00		;bank 0
	jsr	setBank
	lda	BANK_ADR
	cmp	#BANK1_IDENT
	bne	?bankFail
	inc	bankCount
	
	ldx	#%01		;bank 1
	jsr	setBank
	lda	BANK_ADR
	cmp	#BANK2_IDENT
	bne	?bankFail
	inc	bankCount
	
	ldx	#%10		;bank 2
	jsr	setBank
	sta	PORTB
	lda	BANK_ADR
	cmp	#BANK3_IDENT
	bne	?bankFail
	inc	bankCount
	
	ldx	#%11		;bank 3
	jsr	setBank
	sta	PORTB
	lda	BANK_ADR
	cmp	#BANK3_IDENT
	bne	?bankFail
	inc	bankCount
	
?bankFail

	ldx	#%100		;bank normal
	jsr	setBank
	lda	#0		;clear
	sta	BANK_ADR
	
	;print bank count
	
	lda	#<bankCountStr
	sta	ZA0
	lda	#>bankCountStr
	sta	ZA0+1
	ldx	bankCount
	jsr	valueToHex

.define	BANK_IDENT	$57
	
	;*********************************************************
	;os rom as ram ?
	;*********************************************************
	
	lda	PORTB
	and	#$fe		;bit 0 = 0 RAM
	sta	PORTB
	
	lda	#BANK_IDENT
	sta	$C000
	lda	$C000
	cmp	#BANK_IDENT
	bne	?noOSASRAM
	inc	hasOSASRAM
?noOSASRAM

	lda	PORTB
	ora	#$1		;bit 0 = 1 OS
	sta	PORTB
	
	lda	#0
	sta	$C000		;clear
		
	;draw has mmu string
	
	lda	hasOSASRAM
	beq	?noText2
	lda	#<yesStr
	sta	ZA0
	lda	#>yesStr
	sta	ZA0+1
	jmp	?yesText2Set
	
?noText2	
	lda	#<noStr
	sta	ZA0
	lda	#>noStr
	sta	ZA0+1
?yesText2Set	
	
	lda	#<hasOSASRAMStr
	sta	ZA1
	lda	#>hasOSASRAMStr
	sta	ZA1+1
	
	jsr	copyString
	
	;*********************************************************
	;basic rom as ram ?
	;*********************************************************
	
	lda	PORTB
	ora	#$2		;bit 1 = 1 RAM
	sta	PORTB
	
	lda	#BANK_IDENT
	sta	$A000
	lda	$A000
	cmp	#BANK_IDENT
	bne	?noBSASRAM
	inc	hasBSASRAM
?noBSASRAM

	lda	PORTB
	and	#$fd		;bit 1 = 0 Basic
	sta	PORTB
	
	lda	#0
	sta	$A000		;clear
	
	;
	
	;draw has mmu string
	
	lda	hasBSASRAM
	beq	?noText3
	lda	#<yesStr
	sta	ZA0
	lda	#>yesStr
	sta	ZA0+1
	jmp	?yesText3Set
	
?noText3	
	lda	#<noStr
	sta	ZA0
	lda	#>noStr
	sta	ZA0+1
?yesText3Set	
	
	lda	#<hasBSASRAMStr
	sta	ZA1
	lda	#>hasBSASRAMStr
	sta	ZA1+1
	
	jsr	copyString

	
loop
	
	;Wait VBlank

?WaitVC0
        lda	VCOUNT		
        beq	?WaitVC0   	
?WaitVCnot0
        lda	VCOUNT		
        bne	?WaitVCnot0   
	
	
	jmp loop			;end
	
hasMMU		.byte	0
hasOSASRAM	.byte	0
hasBSASRAM	.byte	0
yesStr		.byte	"YES",0
noStr		.byte	"NO",0

bankCount	.byte	0


;************************************************************
;* 	
;* setBank
;*
;* x NBB 
;* N=1 Normal N = 0 Extra Use Bank BB
;*
;* trash x, ZD0
;*
;************************************************************

setBank
	lda	PORTB	
	and	#$e3
	sta	ZD0
	txa
	asl
	asl
	ora	ZD0
	sta	PORTB
	rts
	
;************************************************************
;* 	
;* copyString (0 terminated max 255 bytes)
;*
;* ZA0 = string in ptr
;* ZA1 = string out ptr
;*
;************************************************************	

copyString

	pha
	tya
	pha
	ldy	#0
?copy	lda	(ZA0),y
	beq	?copyEnd
	sta	(ZA1),y
	iny
	jmp	?copy
	
?copyEnd
	pla
	tay
	pla
	
	rts
	
;************************************************************
;* 	
;* valueToHex
;* 
;* x   = value
;* ZA0 = string ptr (2 bytes)
;*
;* trash y
;*
;************************************************************	
	
valueToHex

	ldy	#0
	txa
	lsr
	lsr
	lsr
	lsr	;top nibble
	jsr	?nibbleToChar
	sta	(ZA0),y
	iny
	txa
	and	#$f
	jsr	?nibbleToChar
	sta	(ZA0),y
	
	rts

?nibbleToChar
	cmp	#10
	bcc	?i0to9
	clc
	adc	#"A"-10
	rts
?i0to9	
	add	#"0"
	rts
	
;************************************************
;*
;* dummy
;*
;************************************************
	
noKeyRead	
	rts
	
;************************************************
;*
;* vertical blank interrupt (immidiate, x,y regs save bei os rom)
;*
;************************************************

vbi_irq

	;
	
	lda	#0
	sta	dliCounter
	
	;prolog (like XITVBL)
	
	pla					  
	tay
	pla					  
	tax
	pla					  
	rti
			
;************************************************
;*
;* display list interrupt
;*
;************************************************

dli_irq

	;prolog

        pha 
	txa	
	pha
	tya	
	pha

	inc	dliCounter
	
	;epilog
	
        pla					  
	tay
	pla					  
	tax
	pla
        rti   	;direct (no stack used)
	
dliCounter	.byte	0
		
; display list

	;7	6	5	4	3	2	1	0
	;DLI	LMS	VSCROLL	HSCOLL	Mode
	;
	;Mode 0 Blank lines 7..4 is count+1 of blank lines
	;Mode 1 JMP (use with LMS to set destination)
	;Mode $2-$f is ANTIC mode

	.align $400
	
displayList	 
	.byte 0			;Mode 0
	.byte $70		;8 blank lines	
	.byte $70		;8 blank lines
	.byte $c0  		;DLI 8 blank lines
	.byte $47,<charData,>charData   	;Mode 7 + LMS	 
	.byte $7   
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $7
	.byte $41,<displayList,>displayList ; wait vblank, restart same display list on next frame	
	
	org	$4000
	 
	;note here its a 8x16 pixel mode
	
charData

	;20 chars per screen width (20*8 = 160Pixel)
	;12 char height (12*16 = 192 (/2))

	;        --------------------////////////////////

	.byte	">------------------<"
	.byte	"                    "
	.byte	" RAMTOP       = $"
ramTopStr	
	.byte	"   "	
	.byte	" HAS MMU      = "
hasMMUStr
	.byte	"    "
	.byte	" XE 16K BANKS = $"
bankCountStr
	.byte   "   "
	.byte   " OSROM AS RAM = "
hasOSASRAMStr
	.byte   "    "
	.byte	" BSROM AS RAM = "
hasBSASRAMStr	
	.byte	"    "
	.byte	"                    "
	.byte	"                    "
	.byte	"                    "	
	.byte	"                    "
	.byte	"                    "	
	.byte	">------------------<"
	
