Skip to content

Commit

Permalink
start working on lcd commands
Browse files Browse the repository at this point in the history
  • Loading branch information
celerizer committed Oct 15, 2024
1 parent 25f7055 commit a2739c0
Showing 1 changed file with 169 additions and 4 deletions.
173 changes: 169 additions & 4 deletions devices/lcd.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,56 @@
#include "../dma.h"
#include "lcd.h"
#include "../types.h"

static const char *name = "128x64 LCD device";
static const h8_device_id type = H8_DEVICE_LCD;

typedef union
{
H8_BITFIELD_4
(
/** Hardcoded chip ID */
h8_u8 id : 4,

/** Whether the device is busy with a reset. Unimplemented */
h8_u8 res : 1,

/** Whether the device is on */
h8_u8 on : 1,

/** Whether the device is busy with a command. Unimplemented */
h8_u8 bsy : 1
) flags;
h8_u8 raw;
} h8_lcd_sr_t;

typedef struct
{
h8_u8 vram[128 * 64];
h8_bool selected;
h8_bool mode;
h8_u8 command;
h8_bool second_byte;

h8_u8 x, y;

/** @todo What is this? */
h8_bool icon_enable;

/** If true, displays all pixels on regardless of VRAM contents */
h8_bool all_on;

h8_bool inverse_display;

h8_bool power_save;

/** If true, the display will sleep when power save is enabled.
* If false, the display will standby. */
h8_bool power_save_mode_sleep;

h8_bool x_flip, y_flip;

h8_lcd_sr_t status;
} h8_lcd_t;

#define H8_LCD_MODE_CMD 0
Expand All @@ -32,16 +74,136 @@ void h8_lcd_read(h8_device_t *device, h8_byte_t *dst)
{
h8_lcd_t *m_lcd = device->device;

/** @todo */
dst->u = m_lcd->vram[0];
if (m_lcd->mode)
dst->u = m_lcd->status.raw;
else
/** @todo */
dst->u = 0;
}

void h8_lcd_write(h8_device_t *device, h8_byte_t *dst, const h8_byte_t value)
{
h8_lcd_t *m_lcd = device->device;

/** @todo */
m_lcd->vram[0] = value.u;
if (!m_lcd->second_byte)
{
m_lcd->command = value.u;
switch (m_lcd->command)
{
/** Set Column Address bit0-3 */
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
m_lcd->x = (m_lcd->x & B01110000) | value.u;
break;
/** Set Column Address bit4-6 */
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
m_lcd->x = (m_lcd->x & B00001111) | ((value.u & B00000111) << 4);
break;
case 0xA2:
m_lcd->icon_enable = FALSE;
break;
case 0xA3:
m_lcd->icon_enable = TRUE;
break;
case 0xA4:
m_lcd->status.flags.on = FALSE;
break;
case 0xA5:
m_lcd->status.flags.on = TRUE;
break;
case 0xA6:
m_lcd->inverse_display = FALSE;
break;
case 0xA7:
m_lcd->inverse_display = TRUE;
break;
case 0xA8:
m_lcd->power_save_mode_sleep = FALSE;
break;
case 0xA9:
m_lcd->power_save_mode_sleep = TRUE;
break;
case 0xB0:
case 0xB1:
case 0xB2:
case 0xB3:
case 0xB4:
case 0xB5:
case 0xB6:
case 0xB7:
case 0xB8:
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF:
m_lcd->y = (value.u & B00001111) * 8;
break;
case 0xC0:
case 0xC1:
case 0xC2:
case 0xC3:
case 0xC4:
case 0xC5:
case 0xC6:
case 0xC7:
m_lcd->y_flip = FALSE;
break;
case 0xC8:
case 0xC9:
case 0xCA:
case 0xCB:
case 0xCC:
case 0xCD:
case 0xCE:
case 0xCF:
m_lcd->y_flip = TRUE;
break;
case 0xE1:
m_lcd->power_save = FALSE;
break;
/** Software Reset */
case 0xE2:
/** @todo set defaults */
break;
default:
break;
}
}
else
{
switch (m_lcd->command)
{
default:
break;
}
m_lcd->second_byte = FALSE;
}

*dst = value;
}

void h8_lcd_init(h8_device_t *device)
Expand All @@ -50,6 +212,9 @@ void h8_lcd_init(h8_device_t *device)
{
h8_lcd_t *m_lcd = h8_dma_alloc(sizeof(h8_lcd_t), TRUE);

m_lcd->status.flags.on = TRUE;
m_lcd->status.flags.id = 0x08;

device->device = m_lcd;
device->read = h8_lcd_read;
device->write = h8_lcd_write;
Expand Down

0 comments on commit a2739c0

Please sign in to comment.