org #100
run #100

;**** CPM BOOT SECTOR FACE A***

nolist



write "bin/boot_sector.bin"

amsdos		EQU 1

read_key	EQU #BB09

IFNOT amsdos
	Read_Sector	EQU #BE89
ENDIF

IF amsdos
	boot_sector	EQU #C7
ELSE
	boot_sector	EQU #C2
ENDIF

.entry

IF amsdos
	ld HL,(#BE7D)	;get current drive address
	ld A,(HL)
	ld (current_drive),A

	ld C,7                      ;disk rom
	ld DE,directory             ;lowest useable byte of memory
	ld HL,&B0FF                 ;highest useable byte of memory
	call #BCCE		    ;initialise disk rom

	;get read sector
	call read_sector_init

	ld HL,(#BE7D)	;get current drive address
	ld A,(current_drive)
	ld (HL),A

ELSE
	xor A
	ld (current_drive),A
ENDIF

	add 65
	ld (boot_txt_drive),A
;init screen and show boot message
	;call #BBFF		;reinit screen pack
	;ld A,2
	;call #BC0E

	ld HL,boot_txt
	call print_txt

	;call check_ram

;sector 1
	ld 	HL,directory
IF amsdos
	ld A,(current_drive)
	ld E,A
	ld D,0
ELSE
	ld 	DE,0
ENDIF
	ld 	C,boot_sector
	call    Read_Sector	;read sector

	ld 	HL,directory+512
IF amsdos
	ld A,(current_drive)
	ld E,A
	ld D,0
ELSE
	ld 	DE,0
ENDIF
	ld 	C,boot_sector+1
	call    Read_Sector	;read sector

	;try to find boot file
	call find_boot_file

	jp nc,no_boot_found

	;no get to two next digits to compute address

	ld A,(HL)
	call get_digit	;compute first digit
	add A,A	;2
	add A,A	;4
	add A,A	;8
	add A,A	;16
	ld B,A
	inc HL	;5
	ld A,(HL)
	call get_digit		;compute second digit
	or B

	ld B,A
	ld C,0
	push BC			;put run address on stack
	ld (current_write),BC	;where to write

	ld BC,run_loader	;go on config first !
	push BC

	ld DE,10	; we advanced only 1 digit
	add HL,DE

	;name finished
	ld A,(HL)
	and 1  ;must be on side 0 !
	jr nz,no_boot_found

;ok , found boot file
	push HL
	ld HL,boot_txt_found
	call print_txt
	pop HL

	inc HL ;track
	ld A,(HL)
	ld (current_track),A
	inc HL ;sector
	ld A,(HL)
	ld (current_sector),A

	inc HL ;size
	ld E,(HL)
	inc HL
	ld D,(HL)
	ld (bytes_to_read),DE

	;do the loading
.loading_loop
	ld HL,(bytes_to_read)	;check if we still have bytes to read
	ld DE,512		;sub 512 to byte to read
	or A			;cleanup carry
	sbc HL,DE
	push AF			;save flags

	ld (bytes_to_read),HL	;update bytes to read
	
	ld HL,(current_write)	;read sector
	ld A,(current_track)
	ld D,A

IF amsdos
	ld A,(current_drive)
	ld E,A
ELSE
	ld 	E,0
ENDIF

	ld A,(current_sector)
	ld 	C,A		;sector
	call    Read_Sector	;read sector
	
	pop AF
	ld A,0	;current drive
	ret C	;if data to read > 0 then end
	ret Z	;if data to read =0 then end

	;next address
	ld HL,(current_write)
	ld DE,512
	add HL,DE
	ld (current_write),HL

	;next sector
	ld A,(current_sector)
	inc A
	cp #CB
	jr c,next_sector_ok

	ld HL,current_track	;next track
	inc (HL)

	ld A,#C1		;return base zector
.next_sector_ok
	ld (current_sector),A
	jr loading_loop

;set up to run loader
.run_loader
	di
	ld BC,#7F8C+2 ;mode 2 + no roms
	out (C),C
current_drive	EQU	$+1
	ld A,0
	ret

.no_boot_found	
	ld HL,boot_txt_notfound
	call print_txt
.notfound
	jr $

.current_write
	dw 0
.current_track
	db 0
.current_sector
	db 0
.bytes_to_read
	dw 0


.get_digit
	cp 65
	jr nc,get_digit_letter

	sub 48
	ret

.get_digit_letter
	sub 65
	ret
	
	
;.current_drive
;		db	0

;**************************
;*** FIND BOOTABLE FILE ***
;**************************

.find_boot_file
	ld IX,directory	
	ld DE,16
	ld B,64	;64 entries
.find_boot_file_loop
	bit 2,(IX+11)	;flag bit 2 = bootable file
	jr z,find_boot_file_next

	push IX
	pop HL	;return address on HL
	scf	;found it !
	ld A,(IX+11)	;save flags
	ret
	
.find_boot_file_next
	add IX,DE
	djnz find_boot_file_loop

	or A	;no carry = no boot file !
	ret

.print_txt
	ret
	ld A,(HL)
	bit 7,A
	push AF
	and 127
	call #BB5A
	pop AF
	ret nz
	inc HL
	jr print_txt

IF amsdos
.read_sector_init
	ld HL,read_sector_command
	call #bcd4
	ld (read_sector_address),HL
	ld A,C
	ld (read_sector_address+2),A
	ret

.read_sector
	rst 3
	dw read_sector_address
	ret
.read_sector_address
	ds 3,0
.read_sector_command
	db 4+128
ENDIF

.boot_txt
	;db 7,4,2,28,0,1,1,29,1,1,28,1,26,26
	db "FDC/FS - Starting up...",10,10,13
	db "booting from "
.boot_txt_drive
	db "A:"
	db 10,10,13 OR 128
.boot_txt_found
	str "boot file found !"
.boot_txt_notfound
	str "boot file not found !"

.check_ram
	ld BC,#7FC4
	ld HL,#4000
	ld D,4
.check_ram_loopA
	out (C),C
	ld (HL),C
	inc C
	dec D
	jr nz,check_ram_loopA

	ld DE,#0400
.check_ram_loopB
	dec C
	out (C),C
	ld A,(#4000)
	cp C
	jr nz,check_ram_module_fail
	inc E
	dec D
	jr nz,check_ram_loopB

	ld A,#C0
	out (C),A

	ret
	
.check_ram_module_fail
	ld HL,ram_fail
	call print_txt
	jr $
	
.ram_fail
	str "this game requires 128K ram !"
list
.directory

		