;; #LAYOUT# STD *        #TAKE
;; #LAYOUT# CRT KERNAL_0 #TAKE
;; #LAYOUT# M65 KERNAL_0 #TAKE
;; #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT
;; #LAYOUT# X16 *        #IGNORE
;; #LAYOUT# *   *        #IGNORE

;
; Official Kernal routine, described in:
;
; - [RG64] C64 Programmers Reference Guide   - page 285
; - [CM64] Computes Mapping the Commodore 64 - page 238
;
; CPU registers that has to be preserved (see [RG64]): none
;


IOINIT:

!ifdef SEGMENT_M65_KERNAL_0 {

	jsr map_KERNAL_1
	jsr (VK1__IOINIT)
	jmp m65dos_init 	               ; end by initializing the MEGA65 internal DOS

IOINIT_skip_DOS:

	jsr map_KERNAL_1
	jsr (VK1__IOINIT)
	jmp map_NORMAL

} else {

	;
	; First initialize the CPU port, to make sure we have correct memory map
	;

	; We want BASIC and KERNAL ROMs mapped, and datasette motor off
	; (https://www.c64-wiki.com/wiki/Zeropage)
	; Work around for VICE bug: Writing $00 before $01 results in rubbish in $01
	; after. https://sourceforge.net/p/vice-emu/bugs/1057/

	ldx #$27
	stx CPU_R6510
	ldx #$2F                           ; checked real ROM value
	stx CPU_D6510

	;
	; Now prevent the CIAs from generating interrupts, who knows what damage they can do
	;

	; Disable IRQ generation for both CIAs - see [CM64], page 149

	ldx #$7F
	stx CIA1_ICR ; $DC0D
	stx CIA2_ICR ; $DD0D

	; See discussion here:
	; https://www.lemon64.com/forum/viewtopic.php?t=41744&sid=e294c254db2ba671cde643f100aae341
	; It seems that initializing this register to $7F is the best idea - UDTIM key scanning
	; also leaves this at $7F

	stx CIA1_PRA ; $DC00

	;
	; Silence the SID chip(s), depending on the configuration - we want them silent ASAP
	;

	lda #$00

!ifndef CONFIG_MB_M65 {

	; First the standard chip (skip if it is covered by whole $D4XX range)

!ifndef CONFIG_SID_D4XX {
	sta SID_SIGVOL
}

	; Silence manually configured 2nd and 3rd SIDs

!ifdef CONFIG_SID_2ND_ADDRESS {
	sta SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS
}

!ifdef CONFIG_SID_3RD_ADDRESS {
	sta SID_SIGVOL - __SID_BASE + CONFIG_SID_3RD_ADDRESS
}
	; Silence whole D4XX, D5XX, D6XX, D7XX ranges (if configured)

!ifdef CONFIG_SID_DX_RANGE {

	ldy #$00
@1:

!ifdef CONFIG_SID_D4XX {
	sta SID_SIGVOL + $000, Y
}
!ifdef CONFIG_SID_D5XX {
	sta SID_SIGVOL + $100, Y
}
!ifdef CONFIG_SID_D6XX {
	sta SID_SIGVOL + $200, Y
}
!ifdef CONFIG_SID_D7XX {
	sta SID_SIGVOL + $300, Y
}

	tya
	clc
	adc #$20
	tay
	bne @1

} ; CONFIG_SID_D4XX_OR_D5XX

} else { ; CONFIG_MB_M65

	; MEGA65 specific handling - it contains 4 SIDs

	sta SID_SIGVOL + __SID_R1_OFFSET
	sta SID_SIGVOL + __SID_R2_OFFSET
	sta SID_SIGVOL + __SID_L1_OFFSET
	sta SID_SIGVOL + __SID_L2_OFFSET

}

	;
	; Now continue the CIAs initialization
	;

	; For CIA #1 we need port A as output and port B as input to scan the keyboard

	ldx #$FF
	stx CIA1_DDRA    ; $DC02
	inx
	stx CIA1_DDRB    ; $DC03
	stx CIA2_DDRB    ; $DD03  ; XXX this port is used for RS-232, value here is most likely wrong!

!ifdef HAS_128_POSSIBILITY {

 	; Disable C128 extra keys - just to be sure they will not interfere with anything

 	stx VIC_XSCAN                      ; store $FF

 	; Disable the C128 2MHz mode, it prevents VIC-II display from working correctly

 	inx
	stx VIC_CLKRATE                    ; store $00
}

	; Set DDR on CIA2 for IEC bus, VIC-II banking (see [CM64], $DDOO description on page 193)
	lda #$3F
	sta CIA2_DDRA    ; $DD02

	; Checked using VICE that original ROM initializes timers this way
	ldx #$08
	stx CIA1_CRB     ; $DC0F
	stx CIA2_CRA     ; $DD0E
	stx CIA2_CRB     ; $DD0F

	; Set VIC-II bank - at least the 'Operacja Proboszcz' game needs this within IOINIT
	; Checked on original ROMs, that it sets bit #2 (RS-232 output) high

	ldx #%00000111 ; XXX adapt this to IEC idle state, JMP at the end won't be needed
	stx CIA2_PRA     ; $DD00

	; Put something sane in the IRQ timer
	jsr setup_irq_timer

	; Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
	ldx #$11
	stx CIA1_CRA     ; $DC0E

	; Enable timer interrupt
	ldx #$81
	stx CIA1_ICR     ; $DC0D

!ifdef CONFIG_IEC {

	; Set IEC bus to its initial idle state
	jmp iec_set_idle

} else {

	rts
}


} ; ROM layout
