mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-23 21:29:28 +00:00
pdmonboard: enable periodic video updates.
This commit is contained in:
parent
339db4a078
commit
d4ecb77b24
@ -123,6 +123,8 @@ uint32_t AMIC::read(uint32_t reg_start, uint32_t offset, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch(offset) {
|
switch(offset) {
|
||||||
|
case AMICReg::Ariel_Config:
|
||||||
|
return this->def_vid->get_vdac_config();
|
||||||
case AMICReg::Video_Mode:
|
case AMICReg::Video_Mode:
|
||||||
return this->def_vid->get_video_mode();
|
return this->def_vid->get_video_mode();
|
||||||
case AMICReg::Monitor_Id:
|
case AMICReg::Monitor_Id:
|
||||||
@ -223,7 +225,7 @@ void AMIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
|
|||||||
this->def_vid->set_clut_color(value);
|
this->def_vid->set_clut_color(value);
|
||||||
break;
|
break;
|
||||||
case AMICReg::Ariel_Config:
|
case AMICReg::Ariel_Config:
|
||||||
this->def_vid->vdac_config(value);
|
this->def_vid->set_vdac_config(value);
|
||||||
break;
|
break;
|
||||||
case AMICReg::Video_Mode:
|
case AMICReg::Video_Mode:
|
||||||
this->def_vid->set_video_mode(value);
|
this->def_vid->set_video_mode(value);
|
||||||
|
@ -21,6 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
/** @file PDM on-board video emulation. */
|
/** @file PDM on-board video emulation. */
|
||||||
|
|
||||||
|
#include <core/timermanager.h>
|
||||||
#include <cpu/ppc/ppcmmu.h>
|
#include <cpu/ppc/ppcmmu.h>
|
||||||
#include <devices/memctrl/hmc.h>
|
#include <devices/memctrl/hmc.h>
|
||||||
#include <devices/video/pdmonboard.h>
|
#include <devices/video/pdmonboard.h>
|
||||||
@ -37,6 +38,7 @@ PdmOnboardVideo::PdmOnboardVideo()
|
|||||||
this->blanking = 0x80;
|
this->blanking = 0x80;
|
||||||
this->crtc_on = false;
|
this->crtc_on = false;
|
||||||
this->vdac_mode = 8;
|
this->vdac_mode = 8;
|
||||||
|
this->pixel_depth = 0;
|
||||||
|
|
||||||
// get pointer to the Highspeed Memory controller
|
// get pointer to the Highspeed Memory controller
|
||||||
this->hmc_obj = dynamic_cast<HMC*>(gMachineObj->get_comp_by_name("HMC"));
|
this->hmc_obj = dynamic_cast<HMC*>(gMachineObj->get_comp_by_name("HMC"));
|
||||||
@ -75,18 +77,24 @@ void PdmOnboardVideo::set_pixel_depth(uint8_t depth)
|
|||||||
{
|
{
|
||||||
static uint8_t pix_depths[8] = {1, 2, 4, 8, 16, 0xFF, 0xFF, 0xFF};
|
static uint8_t pix_depths[8] = {1, 2, 4, 8, 16, 0xFF, 0xFF, 0xFF};
|
||||||
|
|
||||||
this->pixel_depth = pix_depths[depth];
|
uint8_t new_pix_depth = pix_depths[depth];
|
||||||
if (this->pixel_depth == 0xFF) {
|
if (new_pix_depth == 0xFF) {
|
||||||
ABORT_F("PDM-Video: invalid pixel depth code %d specified!", depth);
|
ABORT_F("PDM-Video: invalid pixel depth code %d specified!", depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_pix_depth != this->pixel_depth) {
|
||||||
|
this->pixel_depth = new_pix_depth;
|
||||||
|
this->set_depth_internal(this->active_width);
|
||||||
|
LOG_F(INFO, "PDM-Video: pixel depth changed to %dbpp", new_pix_depth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdmOnboardVideo::vdac_config(uint8_t mode)
|
void PdmOnboardVideo::set_vdac_config(uint8_t mode)
|
||||||
{
|
{
|
||||||
if (mode != 8) {
|
this->vdac_mode = mode;
|
||||||
LOG_F(WARNING, "Unknown Ariel Config code 0x%X", mode);
|
if ((mode & 0xF8) != 8) {
|
||||||
|
LOG_F(WARNING, "Ariel control changed to unknown value 0x%X", mode);
|
||||||
}
|
}
|
||||||
this->vdac_mode = 8; // 1 bpp, master mode, no overlay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdmOnboardVideo::set_clut_index(uint8_t index)
|
void PdmOnboardVideo::set_clut_index(uint8_t index)
|
||||||
@ -110,9 +118,29 @@ void PdmOnboardVideo::set_clut_color(uint8_t color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdmOnboardVideo::set_depth_internal(int pitch)
|
||||||
|
{
|
||||||
|
switch (this->pixel_depth) {
|
||||||
|
case 1:
|
||||||
|
this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
|
||||||
|
this->convert_frame_1bpp(dst_buf, dst_pitch);
|
||||||
|
};
|
||||||
|
this->fb_pitch = pitch >> 3; // one byte contains 8 pixels
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
this->convert_fb_cb = [this](uint8_t* dst_buf, int dst_pitch) {
|
||||||
|
this->convert_frame_8bpp(dst_buf, dst_pitch);
|
||||||
|
};
|
||||||
|
this->fb_pitch = pitch; // one byte contains 1 pixel
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ABORT_F("PDM-Video: pixel depth %d not implemented yet!", this->pixel_depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PdmOnboardVideo::enable_video_internal()
|
void PdmOnboardVideo::enable_video_internal()
|
||||||
{
|
{
|
||||||
int new_width, new_height;
|
int new_width, new_height, hori_blank, vert_blank;
|
||||||
|
|
||||||
// ensure all video parameters contain safe values
|
// ensure all video parameters contain safe values
|
||||||
switch(this->video_mode) {
|
switch(this->video_mode) {
|
||||||
@ -131,26 +159,36 @@ void PdmOnboardVideo::enable_video_internal()
|
|||||||
case PdmVideoMode::Portrait:
|
case PdmVideoMode::Portrait:
|
||||||
new_width = 640;
|
new_width = 640;
|
||||||
new_height = 870;
|
new_height = 870;
|
||||||
|
hori_blank = 192;
|
||||||
|
vert_blank = 48;
|
||||||
this->pixel_clock = 57283200;
|
this->pixel_clock = 57283200;
|
||||||
break;
|
break;
|
||||||
case PdmVideoMode::Rgb12in:
|
case PdmVideoMode::Rgb12in:
|
||||||
new_width = 512;
|
new_width = 512;
|
||||||
new_height = 384;
|
new_height = 384;
|
||||||
|
hori_blank = 128;
|
||||||
|
vert_blank = 23;
|
||||||
this->pixel_clock = 15667200;
|
this->pixel_clock = 15667200;
|
||||||
break;
|
break;
|
||||||
case PdmVideoMode::Rgb13in:
|
case PdmVideoMode::Rgb13in:
|
||||||
new_width = 640;
|
new_width = 640;
|
||||||
new_height = 480;
|
new_height = 480;
|
||||||
|
hori_blank = 256;
|
||||||
|
vert_blank = 45;
|
||||||
this->pixel_clock = 31334400;
|
this->pixel_clock = 31334400;
|
||||||
break;
|
break;
|
||||||
case PdmVideoMode::Rgb16in:
|
case PdmVideoMode::Rgb16in:
|
||||||
new_width = 832;
|
new_width = 832;
|
||||||
new_height = 624;
|
new_height = 624;
|
||||||
|
hori_blank = 320;
|
||||||
|
vert_blank = 43;
|
||||||
this->pixel_clock = 57283200;
|
this->pixel_clock = 57283200;
|
||||||
break;
|
break;
|
||||||
case PdmVideoMode::VGA:
|
case PdmVideoMode::VGA:
|
||||||
new_width = 640;
|
new_width = 640;
|
||||||
new_height = 480;
|
new_height = 480;
|
||||||
|
hori_blank = 160;
|
||||||
|
vert_blank = 45;
|
||||||
this->pixel_clock = 25175000;
|
this->pixel_clock = 25175000;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -171,16 +209,18 @@ void PdmOnboardVideo::enable_video_internal()
|
|||||||
this->active_width = new_width;
|
this->active_width = new_width;
|
||||||
this->active_height = new_height;
|
this->active_height = new_height;
|
||||||
|
|
||||||
switch(this->pixel_depth) {
|
this->set_depth_internal(new_width);
|
||||||
case 1:
|
|
||||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
// set up video refresh timer
|
||||||
this->convert_frame_1bpp(dst_buf, dst_pitch);
|
double refresh_rate_hz = (double)(this->pixel_clock) / (new_width + hori_blank) / (new_height + vert_blank);
|
||||||
};
|
LOG_F(INFO, "PDM-Video: refresh rate set to %f Hz", refresh_rate_hz);
|
||||||
this->fb_pitch = new_width >> 3; // one byte contains 8 pixels
|
uint64_t refresh_interval = static_cast<uint64_t>(1.0f / refresh_rate_hz * NS_PER_SEC + 0.5);
|
||||||
break;
|
TimerManager::get_instance()->add_cyclic_timer(
|
||||||
default:
|
refresh_interval,
|
||||||
ABORT_F("PDM-Video: pixel depth %d not implemented yet!", this->pixel_depth);
|
[this]() {
|
||||||
|
this->update_screen();
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this->update_screen();
|
this->update_screen();
|
||||||
|
|
||||||
|
@ -54,11 +54,15 @@ public:
|
|||||||
|
|
||||||
void set_video_mode(uint8_t new_mode);
|
void set_video_mode(uint8_t new_mode);
|
||||||
void set_pixel_depth(uint8_t depth);
|
void set_pixel_depth(uint8_t depth);
|
||||||
void vdac_config(uint8_t config);
|
void set_vdac_config(uint8_t config);
|
||||||
|
uint8_t get_vdac_config() {
|
||||||
|
return this->vdac_mode;
|
||||||
|
};
|
||||||
void set_clut_index(uint8_t index);
|
void set_clut_index(uint8_t index);
|
||||||
void set_clut_color(uint8_t color);
|
void set_clut_color(uint8_t color);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void set_depth_internal(int pitch);
|
||||||
void enable_video_internal();
|
void enable_video_internal();
|
||||||
void disable_video_internal();
|
void disable_video_internal();
|
||||||
void convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch);
|
void convert_frame_1bpp(uint8_t *dst_buf, int dst_pitch);
|
||||||
|
Loading…
Reference in New Issue
Block a user