2019-07-06 13:53:36 +01:00
|
|
|
use super::ioregs::consts::*;
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
use crate::bit::BitIndex;
|
|
|
|
use crate::num::FromPrimitive;
|
|
|
|
|
|
|
|
#[derive(Debug, Primitive)]
|
|
|
|
enum BGMode {
|
|
|
|
Mode0 = 0,
|
|
|
|
Mode1 = 1,
|
|
|
|
Mode2 = 2,
|
|
|
|
Mode3 = 3,
|
|
|
|
Mode4 = 4,
|
|
|
|
Mode5 = 5,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct DisplayControl {
|
|
|
|
bg_mode: BGMode,
|
|
|
|
display_frame: usize,
|
|
|
|
hblank_interval_free: bool,
|
|
|
|
obj_character_vram_mapping: bool, // true - 1 dimentional, false - 2 dimentional
|
|
|
|
forced_blank: bool,
|
|
|
|
disp_bg0: bool,
|
|
|
|
disp_bg1: bool,
|
|
|
|
disp_bg2: bool,
|
|
|
|
disp_bg3: bool,
|
|
|
|
disp_obj: bool,
|
|
|
|
disp_window0: bool,
|
|
|
|
disp_window1: bool,
|
|
|
|
disp_obj_window: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<u16> for DisplayControl {
|
|
|
|
fn from(v: u16) -> Self {
|
|
|
|
DisplayControl {
|
|
|
|
bg_mode: BGMode::from_u8(v.bit_range(0..2) as u8).unwrap(),
|
|
|
|
// bit 3 is unused
|
|
|
|
display_frame: v.bit(4) as usize,
|
|
|
|
hblank_interval_free: v.bit(5),
|
|
|
|
obj_character_vram_mapping: v.bit(6),
|
|
|
|
forced_blank: v.bit(7),
|
|
|
|
disp_bg0: v.bit(8),
|
|
|
|
disp_bg1: v.bit(9),
|
|
|
|
disp_bg2: v.bit(10),
|
|
|
|
disp_bg3: v.bit(11),
|
|
|
|
disp_obj: v.bit(12),
|
|
|
|
disp_window0: v.bit(13),
|
|
|
|
disp_window1: v.bit(14),
|
|
|
|
disp_obj_window: v.bit(15),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct DisplayStatus {
|
|
|
|
vblank_flag: bool,
|
|
|
|
hblank_flag: bool,
|
|
|
|
vcount_flag: bool,
|
|
|
|
vblank_irq_enable: bool,
|
|
|
|
hblank_irq_enable: bool,
|
|
|
|
vcount_irq_enable: bool,
|
|
|
|
vcount_setting: u8,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<u16> for DisplayStatus {
|
|
|
|
fn from(v: u16) -> Self {
|
|
|
|
DisplayStatus {
|
|
|
|
vblank_flag: v.bit(0),
|
|
|
|
hblank_flag: v.bit(1),
|
|
|
|
vcount_flag: v.bit(2),
|
|
|
|
vblank_irq_enable: v.bit(3),
|
|
|
|
hblank_irq_enable: v.bit(4),
|
|
|
|
vcount_irq_enable: v.bit(5),
|
|
|
|
// bits 6-7 are unused in GBA
|
|
|
|
vcount_setting: v.bit_range(8..15) as u8,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct Lcd {
|
|
|
|
cycles: usize,
|
|
|
|
current_scanline: usize, // VCOUNT
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Lcd {
|
|
|
|
const DISPLAY_WIDTH: usize = 240;
|
|
|
|
const DISPLAY_HEIGHT: usize = 160;
|
|
|
|
|
|
|
|
pub fn new() -> Lcd {
|
|
|
|
Lcd {
|
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EmuIoDev for Lcd {
|
2019-07-06 23:33:54 +01:00
|
|
|
fn step(&mut self, cycles: usize, sysbus: &mut SysBus) -> (usize, Option<Interrupt>) {
|
2019-07-06 13:53:36 +01:00
|
|
|
self.cycles += cycles;
|
|
|
|
|
2019-07-06 23:33:54 +01:00
|
|
|
// let mut dispcnt = DisplayControl::from(sysbus.ioregs.read_reg(REG_DISPCNT));
|
|
|
|
// let mut dispstat = DisplayStatus::from(sysbus.ioregs.read_reg(REG_DISPSTAT));
|
2019-07-06 13:53:36 +01:00
|
|
|
|
|
|
|
// TODO
|
2019-07-06 23:33:54 +01:00
|
|
|
(0, None)
|
2019-07-06 13:53:36 +01:00
|
|
|
}
|
|
|
|
}
|