(** * Copyright (c) 2016, Fabien Freling * All rights reserved. * * This source code is licensed under the BSD 2-clause license found in the * LICENSE file at the top level directory of this source tree. *) (** Interrupt Master Enable flag *) let gIME = ref false let ie_addr = 0xFFFF let if_addr = 0xFFF0 type t = | V_Blank | LCD_Stat | Timer | Serial | Joypad let get_flag_mask = function | V_Blank -> 0b00000001 | LCD_Stat -> 0b00000010 | Timer -> 0b00000100 | Serial -> 0b00001000 | Joypad -> 0b00010000 (** Return the list of interrupt flags sorted by priority. *) let get_flags byte = let nth_interrupt i = match i with | 0 -> V_Blank | 1 -> LCD_Stat | 2 -> Timer | 3 -> Serial | 4 -> Joypad | _ -> failwith "Invalid interrupt index." in let rec get_flag byte i accu = match i with | 0 | 1 | 2 | 3 | 4 -> if Bit.is_set byte i then let interrupt = nth_interrupt i in get_flag byte (i + 1) (interrupt :: accu) else get_flag byte (i + 1) accu | _ -> List.rev accu in get_flag byte 0 [] (** Interrupt Enable *) let get_IE mem = Memory.get mem ie_addr |> int_of_char (** Interrupt Flag *) let get_IF mem = Memory.get mem if_addr |> int_of_char let reset_IF_flag flag mem = let if_reg = get_IF mem in let flag_mask = get_flag_mask flag in let new_if_reg = if_reg land (lnot flag_mask) |> char_of_int in Memory.set mem if_addr new_if_reg