	org 0x8000
	
tv_flag			equ 0x5c3c

	ld hl,video_offsets
	ld (next_video_ptr),hl
	xor a
	ld (video_count),a
	call 3435	; clear screen

	; set up text printing
	xor a
	ld (tv_flag),a

	; scan disk for the 'DivIDEOg\1' signature

	; set sector number to 0, LBA mode
	xor a
	ld (sector_number),a
	ld (sector_number+1),a
	ld (sector_number+2),a
	or 0x40
	ld (sector_number+3),a

	; read sectors until we get an error

scan_sectors
	call set_sector_number
	ld a,1
	out (0xab),a	; read one sector
	ld a,0x20	; READ SECTOR
	out (0xbf),a	; command reg

wait_ready
	in a,(0xbf)	; wait for 'ready' status
	and 0x80	; test bit 7
	jr nz,wait_ready
	
	; check for error
	in a,(0xa7)	; error reg
	bit 4,a	; if set, sector-out-of-range error occurred. TODO: use an AND instead
	jr nz, choose_video
	
	; check for user quit (Q key)
	ld bc,0xfbfe
	in a,(c)
	and 1
	jr z,choose_video

	ld b,signature_end - signature
	ld hl,sector_buffer
read_signature
	in a,(0xa3)
	ld (hl),a
	inc hl
	djnz read_signature
	
	; does signature match?
	ld hl,signature
	ld de,sector_buffer
	ld b,signature_end - signature
check_signature
	ld a,(de)
	cpi
	jr nz,ignore_sector
	inc de
	djnz check_signature
	
	; fetch initial sector count
	in a,(0xa3)
	ld l,a
	; fetch border colour
	in a,(0xa3)
	ld h,a
	push hl
	
	; skip 21 bytes (reserved for future use)
	ld b,21
skip_reserved
	in a,(0xa3)
	djnz skip_reserved
	
	ld b,32
read_video_name
	ld c,0xa3
	in a,(c)
	or a
	jr nz,read_video_name_nonzero
	ld a,' '
read_video_name_nonzero
	push bc
	rst 0x10
	pop bc
	djnz read_video_name
	
	call advance_sector
	ld de,(next_video_ptr)
	ld hl,sector_number
	ldi
	ldi
	ldi
	ldi
	pop hl	; recall initial-sector-count and border colour
	ld a,l
	ld (de),a
	inc de
	ld a,h
	ld (de),a
	inc de
	inc de
	inc de	; align video entries on 8 byte boundaries
	
	ld (next_video_ptr),de
	ld hl,video_count
	inc (hl)
	jp scan_sectors
	
ignore_sector
	call advance_sector
	jp scan_sectors
	
; video chooser
choose_video
	xor a
	ld (video_number),a
	call highlight_video
choose_video_lp
	; check for Q key
	ld bc,0xfbfe
	in a,(c)
	and 1
	jr z,key_q
	; check for A key
	ld bc,0xfdfe
	in a,(c)
	and 1
	jr z,key_a
	; check for space key
	ld bc,0x7ffe
	in a,(c)
	and 1
	jr z,key_space
	jr choose_video_lp

key_q
	ld a,(video_number)
	or a
	jr z, choose_video_lp
	call unhighlight_video
	ld hl,video_number
	dec (hl)
	call highlight_video
	call wait_nokey
	jr choose_video_lp
key_a
	ld a,(video_number)
	inc a
	ld hl,video_count
	cp (hl)
	jr z,choose_video_lp

	ld a,(video_number)
	call unhighlight_video
	ld hl,video_number
	inc (hl)
	call highlight_video
	call wait_nokey
	jr choose_video_lp
	
wait_nokey	; wait until none of Q, A, space are pressed
	ld bc,0x79fe
	in a,(c)
	and 1
	jr z,wait_nokey
	ret
	
key_space
	; translate video number into lookup position in table
	ld a,(video_number)
	ld l,a
	ld h,0
	add hl,hl
	add hl,hl
	add hl,hl
	ld de,video_offsets
	add hl,de
	; now hl points to the start sector of the video data
	push hl	; also want to point ix there, so that we can grab the initial sector count and border colour
	pop ix
	ld de,sector_number
	ldi
	ldi
	ldi
	ldi
	
play_video
	; clear screen (to black on black)
	ld hl,0x4000
	ld de,0x4001
	ld bc,0x1aff
	ld (hl),l
	ldir
	ld bc,0x7ffd	; clear second screen too
	ld a,0x17
	out (c),a
	ld hl,0xc000
	ld de,0xc001
	ld bc,0x1aff
	ld (hl),l
	ldir
	
	ld a,(ix+5)	; retrieve border colour
	out (254),a
	
	; set up AY for sample playback
	ld bc,0xfffd
	ld a,7	; AY mixer channel
	out (c),a
	ld bc,0xbffd
	ld a,0x3f	; set all channels to 'muted' (always high)
	out (c),a
	ld bc,0xfffd
	ld a,8	; volume channel A
	out (c),a

	; start interrupts
	di
	ld a,0xbc
	ld i,a
	im 2
	ei
	
	ld iy,sector_number
	ld l,(ix+4)	; retrieve initial-sector-count byte
	ld ixh,0xbe	; address of INI jump table
	xor a	; so that the initial OR L will test zero-ness of L
	jp next_frame	; start the loop!

advance_sector
	; increment sector
	ld hl,sector_number
	inc (hl)
	ret nz
	inc hl
	inc (hl)
	ret nz
	inc hl
	inc (hl)
	ret nz
	inc hl
	inc (hl)
	ret
	
set_sector_number
	ld ix,sector_number
	ld a,(ix)
	out (0xaf),a
	ld a,(ix+1)
	out (0xb3),a
	ld a,(ix+2)
	out (0xb7),a
	ld a,(ix+3)
	out (0xbb),a
	ret
	
highlight_video
	ld a,(video_number)
	or 0xc0
	ld l,a
	ld h,0x02
	add hl,hl
	add hl,hl
	add hl,hl
	add hl,hl
	add hl,hl
	ld b,32
highlight_vid_lp
	set 6,(hl)
	inc hl
	djnz highlight_vid_lp
	ret

unhighlight_video
	ld a,(video_number)
	or 0xc0
	ld l,a
	ld h,0x02
	add hl,hl
	add hl,hl
	add hl,hl
	add hl,hl
	add hl,hl
	ld b,32
unhighlight_vid_lp
	res 6,(hl)
	inc hl
	djnz unhighlight_vid_lp
	ret
	
sector_number
	db 0,0,0,0
	
signature
	db "DivIDEog",1
signature_end
	
next_video_ptr	; where in video_offsets to place the next one
	dw 0

video_number	; currently selected video index
	db 0
	
video_count
	db 0
video_offsets
	ds 24*8
	
sector_buffer
	ds 512
	
	; null interrupt routine
	org 0xbbbb
	ei
	ret
	
	; interrupt table
	org 0xbc00
	rept 257
		db 0xbb
	endm

	org 0xbd80
exit
	im 1
	ld bc,0x7ffd
	ld a,0x10
	out (c),a
	ret
next_frame
	or l
	jr z,exit
	out (0xab),a	; sector count register

	ld a,(iy+0)
	out (0xaf),a	; LBA 0..7
	add a,l
	ld (iy+0),a
	
	ld a,(iy+1)
	out (0xb3),a	; LBA 8..15
	adc a,0
	ld (iy+1),a
	
	ld a,(iy+2)
	out (0xb7),a	; LBA 16..23
	adc a,0
	ld (iy+2),a
	
	ld a,(iy+3)
	out (0xbb),a	; LBA 24..28
	adc a,0
	ld (iy+3),a

	ld a,0x20	; command for READ SECTORS
	out (0xbf),a
	
;	xor a	; border colour change - use for debugging
;	out (254),a
	halt
;	ld a,2
;	out (254),a
video_page
	ld a,0x17
	xor 0x0a	; toggle between page 5 shown/page 7 in memory and page 7 shown/page 5 in memory
	ld (video_page+1),a
	ld bc,0x7ffd
	out (c),a
	ld c,0xa3	; IDE data register
	ld e,0x3f	; used to reset B register out of contended port ranges
	jp wait_ready_2	; entry point to reading chunks

	org 0xbe00
	jr next_frame
	rept 126
		ini
	endm
	
wait_ready_2
	in a,(0xbf)	; wait for 'ready' status	; T=11
	add a,a	; test bit 7; will carry if set (meaning not ready)	; T=4
	jr c,wait_ready_2	; T=7 (most of the time the branch won't be taken)
	
	in l,(c)	; read address (or number of sectors in next frame)	; T=12
	in h,(c)	; T=12
	in a,(0xa3)	; read delta length (or 0 for next frame); T=11
	ld ixl,a	; T=8 (assuming it's four more than LD L,A)
	ld b,e	; ensures b is in range 0..63 (provided delta is length <64), avoiding contended port reads	; T=4
; sample playback
	in a,(c)	; returns 10x0nnnn where nnnn = sample volume		; T=12 (in a,(0xa3) would be 11 tstates but previous value of A is likely to be >0xc0 and therefore a contended port read
	out (0xfd),a	; AY chip is preconfigured to write to register 8	; T=11
	
	jp (ix)	; T=8

; Tstates per packet = 100+INIs (say 18.625T each, if there's an average of 2.625T contention)
