;CPU time
;
;A cycle-accuracy test for NES emulators.  Tests all opcodes and page
;crossings on all applicable opcodes.
;
;Tested on a real NES.
;
;If this program is working correctly, a white box should appear
;in the upper left hand corner of the screen, and sorta "vibrate"
;back and forth a bit, but otherwise remain stationary.
;
;If no box appears, the emulator in question does not support mid-scanline
;PPU writes at all or correctly.
;
;If the box moves left, CPU cycles are missing somewhere, or the PPU is using
;too many cycles per frame.
;
;If the box moves right, the CPU is executing too many cycles, or the PPU
;is not using enough cycles per frame.
;
;Note that this test relys on the PPU taking 1/3rd CPU cycle less every other
;frame.  Failure of this will result in the box slowly moving left.
;
;Original program written by Quietust, (?)
;Modified by  kevtris, (Kevin H).
;


.org $C000
reset:          SEI
		CLD
		LDA #$00
		STA $2000
		STA $2001               ;kill PPU
		LDX #$04                ;wait 4 frames
ppuinit:        LDA $2002
		BPL ppuinit
		DEX
		BPL ppuinit
		TXS

		LDA $2002               ;clear VRAM
		LDX #$00
		STX $2006
		STX $2006

		LDX #$00
		LDY #$30
		LDA #$00
init_vram:      STA $2007
		DEX
		BNE init_vram
		DEY
		BNE init_vram

setpal:         LDX #$FF
		STX $2006
		INX
		STX $2006
		LDA #$3F
init_pal:       STA $2007
		INX
		CPX #$20
		BNE init_pal

		LDA #$C0
		STA $4017
		LDA #$00
		STA $4015       ;kill sound
		STA $2005
		STA $2005
		LDA #$80
		STA $2000       ;let PPU activate at next frame

forever:        JMP forever

.fill $C100-*,$00
nmi:            LDA #$14
		STA $2001
		LDX #$00
		STX $2000
		STX $2005
		STX $2005

wait1a:         DEX
		BNE wait1a
wait1b:         DEX
		BNE wait1b
wait1c:         DEX
		BNE wait1c      ;position the box on the screen

mainloop:                       ;total 29780
		LDX #$04        ;2
		LDA #$15        ;2

loop:           LDY #$14        ;2
		STA $2001       ;4
		STY $2001       ;4
wait2a:         DEY             ;40
		BNE wait2a      ;59
		NOP             ;2
		NOP             ;2
		LDY #$14        ;2
		STA $2001       ;4
		STY $2001       ;4
		LDY #$13        ;2
wait2b:         DEY             ;38
		BNE wait2b      ;56
		NOP             ;2
		NOP             ;2
		NOP             ;2
		NOP             ;2
		LDY #$14        ;2
		STA $2001       ;4
		STY $2001       ;4
wait2c:         DEY             ;40
		BNE wait2c      ;59
		DEX             ;2
		BNE loop        ;3/2      draw the box on the screen



		LDY #$15        ;2
wait3a:         DEX             ;512
		BNE wait3a      ;767
		DEY             ;44
		BNE wait3a      ;65

		
		;00h line   
		jsr blah         ;6+6
		ldy #000h        ;2
		cpy #000h        ;2
		cpx #000h        ;2 (18) [18] check
		
		;01h line
		ldx #000h        ;2 02h line
		stx 000h         ;3
		stx 001h         ;3
		ora (000h,x)     ;6 
		and (000h,x)     ;6
		eor (000h,x)     ;6
		adc (000h,x)     ;6
		sta (000h,x)     ;6
		lda (000h,x)     ;6
		cmp (000h,x)     ;6
		sbc (000h,x)     ;6 (56) [74]
		
		;02h line
		;(above)

		;03h line
		;(all invalid ops)

		;04h line
		bit 000h         ;3
		sty 000h         ;3
		ldy 000h         ;3
		cpy 000h         ;3
		cpx 000h         ;3 (15) [89]

		;05h line
		ora 000h         ;3
		and 000h         ;3
		eor 000h         ;3
		adc 000h         ;3
		sta 000h         ;3
		lda 000h         ;3
		cmp 000h         ;3
		sbc 000h         ;3 (24) [113]

		;06h line
		asl 000h         ;5
		rol 000h         ;5
		lsr 000h         ;5
		ror 000h         ;5
		stx 000h         ;3
		ldx 000h         ;3
		dec 000h         ;5
		inc 000h         ;5 (36) [149]

		;07h line
		;(all invalid ops)

		;08h line
		php              ;3
		plp              ;4
		pha              ;3
		pla              ;4
		dey              ;2
		tay              ;2
		iny              ;2
		inx              ;2 (21) [170]
		
		;09h line
		ora #000h        ;2
		and #000h        ;2
		eor #000h        ;2
		adc #000h        ;2
		lda #000h        ;2
		cmp #000h        ;2
		sbc #000h        ;2 (16) [186]

		;0ah line
		asl a            ;2
		rol a            ;2
		lsr a            ;2
		ror a            ;2
		txa              ;2
		tax              ;2
		dex              ;2
		nop              ;2 (16) [202]

		;0bh line
		;(all invalid ops)

		;0ch line
		bit 00300h       ;4
		jmp blah2        ;3
blah2:          jmp (blah3)      ;5
blah3:          .dw blah4
blah4:          sty 00300h       ;4
		ldy 00300h       ;4
		cpy 00300h       ;4
		cpx 00300h       ;4 (28) [230]
		
		;0dh line
		ora 00300h       ;4
		and 00300h       ;4
		eor 00300h       ;4
		adc 00300h       ;4
		sta 00300h       ;4
		lda 00300h       ;4
		cmp 00300h       ;4
		sbc 00300h       ;4 (32) [262]
		JMP mainloop2a   ;3        wait out the rest of the frame
		
.fill $C200-*,$00

mainloop2a:     ;0eh line
		asl 00300h       ;6
		rol 00300h       ;6
		lsr 00300h       ;6
		ror 00300h       ;6
		stx 00300h       ;4
		ldx 00300h       ;4
		dec 00300h       ;6
		inc 00300h       ;6 (47) [309]

		;0fh line
		;(all invalid ops)

		;test this here... BRK and RTI
		.db 00h,00h      ;7+6 (13) [322]
		
		;10h line
		lda #001h       ;2  clear zero, clear sign
		clc             ;2  clear carry
		clv             ;2  clear overflow
		bpl blah5       ;3  taken
blah5:          bmi blah5       ;2  not taken
		bvc blah6       ;3  taken
blah6:          bvs blah6       ;2  not taken
		bcc blah7       ;3  taken
blah7:          bcs blah7       ;2  not taken
		bne blah8       ;3  taken
blah8:          beq blah8       ;2  not taken (26) [348]
		
		lda #0ffh       ;2
		pha             ;3
		plp             ;4  set all the flags
		bmi blah9       ;3  taken
blah9:          bpl blah9       ;2  not taken
		bvs blah10      ;3  taken
blah10:         bvc blah10      ;2  not taken
		bcs blah11      ;3  taken
blah11:         bcc blah11      ;2  not taken
		beq blah12      ;3  taken
blah12:         bne blah12      ;2  not taken (29) [377]

		jmp page1a      ;3

.fill $C2c0-*,$00

page1a:         bmi page2a      ;4
page1b:         bvs page2b      ;4
page1c:         bcs page2c      ;4
page1d:         beq page2d      ;4
page1e:         bpl page2e      ;4
page1f:         bvc page2f      ;4
page1g:         bcc page2g      ;4
page1h:         bne page2h      ;4


.fill $C300-*,$00

page2a:         jmp page1b      ;3
page2b:         jmp page1c      ;3
page2c:         jmp page1d      ;3 (28) [405]
page2d:         lda #001h       ;2  clear zero, clear sign
		clc             ;2  clear carry
		clv             ;2  clear overflow
		jmp page1e      ;3
page2e:         jmp page1f      ;3
page2f:         jmp page1g      ;3
page2g:         jmp page1h      ;3 (34) [439]
page2h:         ;11h line
		lda #0ffh       ;2
		sta 000h        ;3
		lda #003h       ;2
		sta 001h        ;3   point to 03ffh
		ldy #000h       ;2
		ora (000h),y    ;5
		and (000h),y    ;5
		eor (000h),y    ;5
		adc (000h),y    ;5
		sta (000h),y    ;5
		lda (000h),y    ;5
		cmp (000h),y    ;5
		sbc (000h),y    ;5
		iny             ;2
		ora (000h),y    ;6
		and (000h),y    ;6
		eor (000h),y    ;6
		adc (000h),y    ;6
		sta (000h),y    ;6
		lda (000h),y    ;6
		cmp (000h),y    ;6
		sbc (000h),y    ;6 (102) [541]

		;12h line
		;(all invalid ops)

		;13h line
		;(all invalid ops)

		;14h line
		ldx #000h       ;2
		sty 000h,x      ;4
		ldy 000h,x      ;4 (10) [551]

		;15h line
		ora 000h,x      ;4
		and 000h,x      ;4
		eor 000h,x      ;4
		adc 000h,x      ;4
		sta 000h,x      ;4
		lda 000h,x      ;4
		cmp 000h,x      ;4
		sbc 000h,x      ;4 (32) [583]

		;16h line
		asl 000h,x      ;6
		rol 000h,x      ;6
		lsr 000h,x      ;6
		ror 000h,x      ;6
		stx 000h,y      ;4
		ldx 000h,y      ;4
		dec 000h,x      ;6
		inc 000h,x      ;6 (44) [627]

		;17h line
		;(all invalid ops)

		;18h line
		clc             ;2
		sec             ;2
		sei             ;2
		tya             ;2
		clv             ;2
		cld             ;2
		sed             ;2 (14) [641]

		;19h line
		ldy #000h       ;2
		ora 03ffh,y     ;4
		and 03ffh,y     ;4
		eor 03ffh,y     ;4
		adc 03ffh,y     ;4
		sta 03ffh,y     ;5
		lda 03ffh,y     ;4
		cmp 03ffh,y     ;4
		sbc 03ffh,y     ;4
		iny             ;2
		ora 03ffh,y     ;5
		and 03ffh,y     ;5
		eor 03ffh,y     ;5
		adc 03ffh,y     ;5
		sta 03ffh,y     ;5
		lda 03ffh,y     ;5
		cmp 03ffh,y     ;5
		sbc 03ffh,y     ;5 (83) [724]

		;1ah line
		tsx             ;2
		txs             ;2 (4) [728]

		;1bh line
		;(all invalid ops)

		;1ch line
		ldy 0300h,x     ;4 (4) [732]

		;1dh line
		ldx #000h       ;2
		ora 03ffh,x     ;4
		and 03ffh,x     ;4
		eor 03ffh,x     ;4
		adc 03ffh,x     ;4
		sta 03ffh,x     ;5
		lda 03ffh,x     ;4
		cmp 03ffh,x     ;4
		sbc 03ffh,x     ;4
		inx             ;2
		ora 03ffh,x     ;5
		and 03ffh,x     ;5
		eor 03ffh,x     ;5
		adc 03ffh,x     ;5
		sta 03ffh,x     ;5
		lda 03ffh,x     ;5
		cmp 03ffh,x     ;5
		sbc 03ffh,x     ;5 (83) [815]
		jmp mainloop2b  ;3

.fill $C400-*,$00

mainloop2b:

		;1eh line
		ldx #000h       ;2
		asl 03ffh,x     ;7
		rol 03ffh,x     ;7
		lsr 03ffh,x     ;7
		ror 03ffh,x     ;7
		ldx 03ffh,y     ;4
		ldx #000h       ;2
		dec 03ffh,x     ;7
		inc 03ffh,x     ;7
		inx             ;2
		ldx 03ffh,y     ;5 (60) [875]

		;1fh line
		;(all invalid ops)



		LDX #$73        ;2
wait3b:         DEX             ;230
		BNE wait3b      ;344 [576]
		
		nop
		nop
		nop

		jmp mainloop2
		

		
		


blah:           rts

.fill $C500-*,$00

mainloop2:                      ;total 29781
		LDX #$04        ;2
		LDA #$15        ;2
loop2:          LDY #$14        ;2
		STA $2001       ;4
		STY $2001       ;4
wait4a:         DEY             ;40
		BNE wait4a      ;59
		NOP             ;2
		NOP             ;2
		LDY #$14        ;2
		STA $2001       ;4
		STY $2001       ;4
		LDY #$13        ;2
wait4b:         DEY             ;38
		BNE wait4b      ;56
		NOP             ;2
		NOP             ;2
		NOP             ;2
		NOP             ;2
		LDY #$14        ;2
		STA $2001       ;4
		STY $2001       ;4
wait4c:         DEY             ;40
		BNE wait4c      ;59
		DEX             ;2
		BNE loop2       ;3/2

		LDY #$16        ;2
wait5a:         DEX             ;512
		BNE wait5a      ;767
		DEY             ;44
		BNE wait5a      ;65

		LDX #$20        ;2
wait5b:         DEX             ;66
		BNE wait5b      ;98
		NOP             ;2
		JMP mainloop    ;3

irq:            RTI

.fill $FFFA-*,$00
.org $FFFA                              ;interrupt vectors
.dw nmi
.dw reset
.dw irq

.end
