Files
open-roms/src/kernal/init/fda3.ioinit.s
T

195 lines
4.1 KiB
ArmAsm

;; #LAYOUT# STD * #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
}
!ifdef CONFIG_KEYBOARD_C65_OR_CAPS_LOCK {
lda #$02
sta C65_EXTKEYS_DDR ; output for most keys, input for CAPS LOCK bit
}
; 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