From: John Hodge Date: Sat, 10 May 2014 02:50:06 +0000 (+0800) Subject: UDI - Adding an attempt at a BochsGA UDI GFX driver X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=57ba49ade7a43d94ee2b4aa20f716df3b504c48c;p=tpg%2Facess2.git UDI - Adding an attempt at a BochsGA UDI GFX driver NOTE: The UDI gfx binding is not finalised, and there are staged changes to the spec. --- diff --git a/UDI/drivers/gfx_bochs/bochsga_common.h b/UDI/drivers/gfx_bochs/bochsga_common.h new file mode 100644 index 00000000..b956900c --- /dev/null +++ b/UDI/drivers/gfx_bochs/bochsga_common.h @@ -0,0 +1,72 @@ +/* + * UDI Bochs Graphics Driver + * By John Hodge (thePowersGang) + * + * bochsga_common.c + * - Common definitions + */ +#ifndef _BOCHSGA_COMMON_H_ +#define _BOCHSGA_COMMON_H_ + +/** + * Definitions to match udiprops.txt + * \{ + */ +#define BOCHSGA_META_BUS 1 +#define BOCHSGA_META_GFX 2 + +#define BOCHSGA_OPS_DEV 1 +#define BOCHSGA_OPS_GFX 2 + +#define BOCHSGA_CB_BUS_BIND 1 +#define BOCHSGA_CB_GFX_BIND 2 +#define BOCHSGA_CB_GFX_STATE 3 +#define BOCHSGA_CB_GFX_RANGE 4 +#define BOCHSGA_CB_GFX_COMMAND 5 + +#define BOCHSGA_MSGNUM_PROPUNK 1001 +/** + * \} + */ + +#include "bochsga_pio.h" +#include "bochsga_engines.h" + +typedef struct { + udi_ubit32_t width; + udi_ubit32_t height; + udi_index_t op_idx; +} engine_t; + +/** + * Region data + */ +typedef struct +{ + udi_cb_t *active_cb; + struct { + udi_index_t pio_index; + } init; + + udi_pio_handle_t pio_handles[N_PIO]; + + udi_boolean_t output_enable; + struct { + udi_ubit32_t width; + udi_ubit32_t height; + udi_ubit8_t bitdepth; + udi_index_t engine; + } outputstate; + struct { + udi_ubit32_t max_width; // 1024 or 1280 + udi_ubit32_t max_height; // 768 or 1024 + } limits; + + engine_t engines[N_ENGINES]; +} rdata_t; + +#define BOCHSGA_MIN_WIDTH 360 +#define BOCHSGA_MIN_HEIGHT 240 + +#endif + diff --git a/UDI/drivers/gfx_bochs/bochsga_core.c b/UDI/drivers/gfx_bochs/bochsga_core.c new file mode 100644 index 00000000..c851b072 --- /dev/null +++ b/UDI/drivers/gfx_bochs/bochsga_core.c @@ -0,0 +1,472 @@ +/* + * UDI Bochs Graphics Driver + * By John Hodge (thePowersGang) + * + * bochsga_core.c + * - Core Code + */ +#define UDI_VERSION 0x101 +#define UDI_GFX_VERSION 0x101 +#include +#include +#include +#define DEBUG_ENABLED 1 +#include "../helpers.h" +#include "../helpers_gfx.h" +#include "bochsga_common.h" + +// --- Management Metalang +void bochsga_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level) +{ + rdata_t *rdata = UDI_GCB(cb)->context; + //udi_trace_write(rdata->init_context, UDI_TREVENT_LOCAL_PROC_ENTRY, 0, ); + + // TODO: Set up region data + + udi_usage_res(cb); +} + +void bochsga_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level) +{ + rdata_t *rdata = UDI_GCB(cb)->context; + udi_instance_attr_list_t *attr_list = cb->attr_list; + + switch(enumeration_level) + { + case UDI_ENUMERATE_START: + case UDI_ENUMERATE_START_RESCAN: + cb->attr_valid_length = attr_list - cb->attr_list; + udi_enumerate_ack(cb, UDI_ENUMERATE_OK, BOCHSGA_OPS_GFX); + break; + case UDI_ENUMERATE_NEXT: + udi_enumerate_ack(cb, UDI_ENUMERATE_DONE, 0); + break; + } +} +void bochsga_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID) +{ +} +void bochsga_final_cleanup_req(udi_mgmt_cb_t *cb) +{ +} +// --- +void bochsga_bus_dev_channel_event_ind(udi_channel_event_cb_t *cb); +void bochsga_bus_dev_bus_bind_ack(udi_bus_bind_cb_t *cb, udi_dma_constraints_t dma_constraints, udi_ubit8_t perferred_endianness, udi_status_t status); +void bochsga_bus_dev_bind__pio_map(udi_cb_t *cb, udi_pio_handle_t new_pio_handle); +void bochsga_bus_dev_bind__intr_chanel(udi_cb_t *gcb, udi_channel_t new_channel); +void bochsga_bus_dev_bus_unbind_ack(udi_bus_bind_cb_t *cb); + +void bochsga_bus_dev_channel_event_ind(udi_channel_event_cb_t *cb) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + switch(cb->event) + { + case UDI_CHANNEL_CLOSED: + break; + case UDI_CHANNEL_BOUND: { + rdata->active_cb = gcb; + udi_bus_bind_cb_t *bus_bind_cb = UDI_MCB(cb->params.parent_bound.bind_cb, udi_bus_bind_cb_t); + udi_bus_bind_req( bus_bind_cb ); + // continue at bochsga_bus_dev_bus_bind_ack + return; } + } +} +void bochsga_bus_dev_bus_bind_ack(udi_bus_bind_cb_t *cb, + udi_dma_constraints_t dma_constraints, udi_ubit8_t perferred_endianness, udi_status_t status) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + // Set up PIO handles + rdata->init.pio_index = -1; + bochsga_bus_dev_bind__pio_map(gcb, UDI_NULL_PIO_HANDLE); + // V V V V +} +void bochsga_bus_dev_bind__pio_map(udi_cb_t *gcb, udi_pio_handle_t new_pio_handle) +{ + rdata_t *rdata = gcb->context; + if( rdata->init.pio_index != -1 ) + { + rdata->pio_handles[rdata->init.pio_index] = new_pio_handle; + } + + rdata->init.pio_index ++; + if( rdata->init.pio_index < N_PIO ) + { + const struct s_pio_ops *ops = &bochsga_pio_ops[rdata->init.pio_index]; + udi_pio_map(bochsga_bus_dev_bind__pio_map, gcb, + ops->regset_idx, ops->base_offset, ops->length, + ops->trans_list, ops->list_length, + UDI_PIO_LITTLE_ENDIAN, 0, 0 + ); + return ; + } + + udi_channel_event_complete( UDI_MCB(rdata->active_cb, udi_channel_event_cb_t), UDI_OK); + // = = = = = +} +void bochsga_bus_dev_bus_unbind_ack(udi_bus_bind_cb_t *cb) +{ +} +void bochsga_bus_dev_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status) +{ +} +void bochsga_bus_dev_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb) +{ +} +// --- +// GFX Provider ops +void bochsga_gfx_channel_event_ind(udi_channel_event_cb_t *cb) +{ + // No operation +} +void bochsga_gfx_bind_req(udi_gfx_bind_cb_t *cb) +{ + // TODO: ACK bind if nothing already bound +} +void bochsga_gfx_unbind_req(udi_gfx_bind_cb_t *cb) +{ + // TODO: Release internal state? +} +void bochsga_gfx_set_connector_req$pio(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t status, udi_ubit16_t result) +{ + udi_gfx_state_cb_t *cb = UDI_MCB(gcb, udi_gfx_state_cb_t); + udi_gfx_set_connector_ack(cb); +} +void bochsga_gfx_set_connector_req(udi_gfx_state_cb_t *cb, udi_ubit32_t value) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + switch(cb->attribute) + { + case UDI_GFX_PROP_ENABLE: + if( rdata->output_enable != !!value ) + { + rdata->output_enable = !!value; + udi_pio_trans(bochsga_gfx_set_connector_req$pio, gcb, + rdata->pio_handles[BOCHSGA_PIO_ENABLE], rdata->output_enable, NULL, &rdata->outputstate); + return ; + } + udi_gfx_set_connector_ack(cb); + return; + // Change input engine + // - + case UDI_GFX_PROP_INPUT: + if( rdata->outputstate.engine != value ) + { + // Validate + if( !(0 <= value && value <= N_ENGINES) ) { + udi_gfx_set_connector_ack(cb /*, UDI_STAT_NOT_SUPPORTED*/); + return ; + } + + // Change saved bitdepth (requires cycling enable) + rdata->outputstate.engine = value; + rdata->outputstate.bitdepth = bochsga_engine_defs[value].bitdepth; + } + udi_gfx_set_connector_ack(cb); + return; + // Alter output dimensions + case UDI_GFX_PROP_WIDTH: + if( value % 8 != 0 ) { + // Qemu doesn't like resolutions not a multiple of 8 + return ; + } + if( !(320 <= value && value <= rdata->limits.max_width) ) { + return ; + } + rdata->outputstate.width = value; + udi_pio_trans(bochsga_gfx_set_connector_req$pio, gcb, + rdata->pio_handles[BOCHSGA_PIO_ENABLE], rdata->output_enable, NULL, &rdata->outputstate); + return; + case UDI_GFX_PROP_HEIGHT: + if( !(240 <= value && value <= rdata->limits.max_height) ) { + return ; + } + rdata->outputstate.height = value; + udi_pio_trans(bochsga_gfx_set_connector_req$pio, gcb, + rdata->pio_handles[BOCHSGA_PIO_ENABLE], rdata->output_enable, NULL, &rdata->outputstate); + return; + } + CONTIN(bochsga_gfx_set_connector_req, udi_log_write, + (UDI_TREVENT_LOG, UDI_LOG_INFORMATION, BOCHSGA_OPS_GFX, 0, BOCHSGA_MSGNUM_PROPUNK, __func__, cb->attribute), + (udi_status_t status) + ); + udi_gfx_state_cb_t *cb = UDI_MCB(cb, udi_gfx_state_cb_t); + udi_gfx_set_connector_ack(cb /*, UDI_STAT_NOT_SUPPORTED*/); +} +void bochsga_gfx_get_connector_req(udi_gfx_state_cb_t *cb) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + switch(cb->attribute) + { + case UDI_GFX_PROP_ENABLE: + udi_gfx_get_connector_ack(cb, !!rdata->output_enable); + return; + case UDI_GFX_PROP_INPUT: + udi_gfx_get_connector_ack(cb, rdata->outputstate.bitdepth/8-1); + return; + case UDI_GFX_PROP_WIDTH: + udi_gfx_get_connector_ack(cb, rdata->outputstate.width); + return; + case UDI_GFX_PROP_HEIGHT: + udi_gfx_get_connector_ack(cb, rdata->outputstate.height); + return; + case UDI_GFX_PROP_CONNECTOR_TYPE: + udi_gfx_get_connector_ack(cb, UDI_GFX_CONNECTOR_HIDDEN); + return; + case UDI_GFX_PROP_SIGNAL: + udi_gfx_get_connector_ack(cb, UDI_GFX_SIGNAL_INTEGRATED); + return; + } + CONTIN(bochsga_gfx_get_connector_req, udi_log_write, + (UDI_TREVENT_LOG, UDI_LOG_INFORMATION, BOCHSGA_OPS_GFX, 0, BOCHSGA_MSGNUM_PROPUNK, __func__, cb->attribute), + (udi_status_t status) + ); + udi_gfx_state_cb_t *cb = UDI_MCB(cb, udi_gfx_state_cb_t); + udi_gfx_get_connector_ack(cb, 0); +} +void bochsga_gfx_range_connector_req(udi_gfx_range_cb_t *cb) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + switch(cb->attribute) + { + case UDI_GFX_PROP_ENABLE: + // 2 values: 0 and 1 + gfxhelpers_return_range_set(udi_gfx_range_connector_ack, cb, 2, 0, 1); + return; + case UDI_GFX_PROP_INPUT: + // 0--3 with a step of 1 + gfxhelpers_return_range_simple(udi_gfx_range_connector_ack, cb, 0, 3, 1); + return; + case UDI_GFX_PROP_WIDTH: + gfxhelpers_return_range_simple(udi_gfx_range_connector_ack, cb, + BOCHSGA_MIN_WIDTH, rdata->limits.max_width, 8); // qemu restricts to 8 step + return; + case UDI_GFX_PROP_HEIGHT: + gfxhelpers_return_range_simple(udi_gfx_range_connector_ack, cb, + BOCHSGA_MIN_HEIGHT, rdata->limits.max_height, 8); // step of 8 for neatness + return; + case UDI_GFX_PROP_CONNECTOR_TYPE: + gfxhelpers_return_range_fixed(udi_gfx_range_connector_ack, cb, UDI_GFX_CONNECTOR_HIDDEN); + return; + case UDI_GFX_PROP_SIGNAL: + gfxhelpers_return_range_fixed(udi_gfx_range_connector_ack, cb, UDI_GFX_SIGNAL_INTEGRATED); + return; + } + CONTIN(bochsga_gfx_range_connector_req, udi_log_write, + (UDI_TREVENT_LOG, UDI_LOG_INFORMATION, BOCHSGA_OPS_GFX, 0, BOCHSGA_MSGNUM_PROPUNK, __func__, cb->attribute), + (udi_status_t status) + ); + udi_gfx_range_cb_t *cb = UDI_MCB(cb, udi_gfx_range_cb_t); + udi_gfx_range_connector_ack(cb); +} +// --- Engine Manipulation --- +void bochsga_gfx_set_engine_req(udi_gfx_state_cb_t *cb, udi_ubit32_t value) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + if( cb->subsystem >= N_ENGINES ) { + udi_gfx_get_engine_ack(cb, 0); + return; + } + + engine_t *engine = &rdata->engines[cb->subsystem]; + + switch(cb->attribute) + { + case UDI_GFX_PROP_WIDTH: + engine->width = value; + udi_gfx_set_engine_ack(cb); + return; + case UDI_GFX_PROP_HEIGHT: + engine->height = value; + udi_gfx_set_engine_ack(cb); + return; + case UDI_GFX_PROP_OPERATOR_INDEX: + if( value >= bochsga_engine_defs[cb->subsystem].op_map.op_count ) { + // Bad value + udi_gfx_set_engine_ack(cb); + return; + } + engine->op_idx = value; + udi_gfx_set_engine_ack(cb); + return; + } + CONTIN(bochsga_gfx_set_engine_req, udi_log_write, + (UDI_TREVENT_LOG, UDI_LOG_INFORMATION, BOCHSGA_OPS_GFX, 0, BOCHSGA_MSGNUM_PROPUNK, __func__, cb->attribute), + (udi_status_t status) + ); + udi_gfx_state_cb_t *cb = UDI_MCB(cb, udi_gfx_state_cb_t); + udi_gfx_set_engine_ack(cb); +} +void bochsga_gfx_get_engine_req(udi_gfx_state_cb_t *cb) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + if( cb->subsystem >= N_ENGINES ) { + udi_gfx_get_engine_ack(cb, 0); + return; + } + + const engine_t *engine = &rdata->engines[cb->subsystem]; + const engine_static_t *engine_def = &bochsga_engine_defs[cb->subsystem]; + + switch(cb->attribute) + { + case UDI_GFX_PROP_ENABLE: + udi_gfx_get_engine_ack(cb, 1); + return; + + case UDI_GFX_PROP_INPUT: + udi_gfx_get_engine_ack(cb, -1); + return; + + case UDI_GFX_PROP_WIDTH: + udi_gfx_get_engine_ack(cb, engine->width); + return; + case UDI_GFX_PROP_HEIGHT: + udi_gfx_get_engine_ack(cb, engine->height); + return; + + case UDI_GFX_PROP_OPERATOR_INDEX: + udi_gfx_get_engine_ack(cb, engine->op_idx); + return; + case UDI_GFX_PROP_OPERATOR_OPCODE: + case UDI_GFX_PROP_OPERATOR_ARG_1: + case UDI_GFX_PROP_OPERATOR_ARG_2: + case UDI_GFX_PROP_OPERATOR_ARG_3: + udi_gfx_get_engine_ack(cb, gfxhelpers_get_engine_op(&engine_def->op_map, engine->op_idx, cb->attribute)); + return; + } + CONTIN(bochsga_gfx_get_engine_req, udi_log_write, + (UDI_TREVENT_LOG, UDI_LOG_INFORMATION, BOCHSGA_OPS_GFX, 0, BOCHSGA_MSGNUM_PROPUNK, __func__, cb->attribute), + (udi_status_t status) + ); + udi_gfx_state_cb_t *cb = UDI_MCB(cb, udi_gfx_state_cb_t); + udi_gfx_get_engine_ack(cb, 0); +} +void bochsga_gfx_range_engine_req(udi_gfx_range_cb_t *cb) +{ + udi_cb_t *gcb = UDI_GCB(cb); + rdata_t *rdata = gcb->context; + + if( cb->subsystem >= N_ENGINES ) { + udi_gfx_range_engine_ack(cb); + return; + } + + engine_t *engine = &rdata->engines[cb->subsystem]; + const engine_static_t *engine_def = &bochsga_engine_defs[cb->subsystem]; + + switch(cb->attribute) + { + case UDI_GFX_PROP_ENABLE: + gfxhelpers_return_range_fixed(udi_gfx_range_engine_ack, cb, 1); + return; + case UDI_GFX_PROP_INPUT: + gfxhelpers_return_range_fixed(udi_gfx_range_engine_ack, cb, -1); + return; + + case UDI_GFX_PROP_OPERATOR_INDEX: + gfxhelpers_return_range_simple(udi_gfx_range_engine_ack, cb, 0, engine->op_idx-1, 1); + return; + case UDI_GFX_PROP_OPERATOR_OPCODE: + case UDI_GFX_PROP_OPERATOR_ARG_1: + case UDI_GFX_PROP_OPERATOR_ARG_2: + case UDI_GFX_PROP_OPERATOR_ARG_3: + gfxhelpers_return_range_fixed(udi_gfx_range_engine_ack, cb, + gfxhelpers_get_engine_op(&engine_def->op_map, engine->op_idx, cb->attribute)); + return; + } + CONTIN(bochsga_gfx_range_engine_req, udi_log_write, + (UDI_TREVENT_LOG, UDI_LOG_INFORMATION, BOCHSGA_OPS_GFX, 0, BOCHSGA_MSGNUM_PROPUNK, __func__, cb->attribute), + (udi_status_t status) + ); + udi_gfx_range_cb_t *cb = UDI_MCB(cb, udi_gfx_range_cb_t); + udi_gfx_range_engine_ack( cb ); +} +void bochsga_gfx_command_req(udi_gfx_command_cb_t *cb) +{ + // Need to parse the GLX stream +} + +// ==================================================================== +// - Management ops +udi_mgmt_ops_t bochsga_mgmt_ops = { + bochsga_usage_ind, + bochsga_enumerate_req, + bochsga_devmgmt_req, + bochsga_final_cleanup_req +}; +udi_ubit8_t bochsga_mgmt_op_flags[4] = {0,0,0,0}; +// - Bus Ops +udi_bus_device_ops_t bochsga_bus_dev_ops = { + bochsga_bus_dev_channel_event_ind, + bochsga_bus_dev_bus_bind_ack, + bochsga_bus_dev_bus_unbind_ack, + bochsga_bus_dev_intr_attach_ack, + bochsga_bus_dev_intr_detach_ack +}; +udi_ubit8_t bochsga_bus_dev_ops_flags[5] = {0}; +// - GFX provider ops +udi_gfx_provider_ops_t bochsga_gfx_ops = { + bochsga_gfx_channel_event_ind, + bochsga_gfx_bind_req, + bochsga_gfx_unbind_req, + bochsga_gfx_set_connector_req, + bochsga_gfx_set_engine_req, + bochsga_gfx_get_connector_req, + bochsga_gfx_get_engine_req, + bochsga_gfx_range_connector_req, + bochsga_gfx_range_engine_req, + bochsga_gfx_command_req +}; +udi_ubit8_t bochsga_gfx_ops_flags[10] = {0}; +// -- +udi_primary_init_t bochsga_pri_init = { + .mgmt_ops = &bochsga_mgmt_ops, + .mgmt_op_flags = bochsga_mgmt_op_flags, + .mgmt_scratch_requirement = 0, + .enumeration_attr_list_length = 0, + .rdata_size = sizeof(rdata_t), + .child_data_size = 0, + .per_parent_paths = 0 +}; +udi_ops_init_t bochsga_ops_list[] = { + { + BOCHSGA_OPS_DEV, BOCHSGA_META_BUS, UDI_BUS_DEVICE_OPS_NUM, + 0, + (udi_ops_vector_t*)&bochsga_bus_dev_ops, + bochsga_bus_dev_ops_flags + }, + { + BOCHSGA_OPS_GFX, BOCHSGA_META_GFX, UDI_GFX_PROVIDER_OPS_NUM, + 0, + (udi_ops_vector_t*)&bochsga_gfx_ops, + bochsga_gfx_ops_flags + }, + {0} +}; +udi_cb_init_t bochsga_cb_init_list[] = { + {BOCHSGA_CB_BUS_BIND, BOCHSGA_META_BUS, UDI_BUS_BIND_CB_NUM, 0, 0,NULL}, + {BOCHSGA_CB_GFX_BIND, BOCHSGA_META_GFX, UDI_GFX_BIND_CB_NUM, 0, 0,NULL}, + {BOCHSGA_CB_GFX_STATE, BOCHSGA_META_GFX, UDI_GFX_STATE_CB_NUM, 0, 0,NULL}, + {BOCHSGA_CB_GFX_RANGE, BOCHSGA_META_GFX, UDI_GFX_RANGE_CB_NUM, 0, 0,NULL}, + {BOCHSGA_CB_GFX_COMMAND, BOCHSGA_META_GFX, UDI_GFX_COMMAND_CB_NUM, 0, 0,NULL}, + {0} +}; +const udi_init_t udi_init_info = { + .primary_init_info = &bochsga_pri_init, + .ops_init_list = bochsga_ops_list, + .cb_init_list = bochsga_cb_init_list, +}; diff --git a/UDI/drivers/gfx_bochs/bochsga_engines.h b/UDI/drivers/gfx_bochs/bochsga_engines.h new file mode 100644 index 00000000..48323d28 --- /dev/null +++ b/UDI/drivers/gfx_bochs/bochsga_engines.h @@ -0,0 +1,34 @@ +/* + * + */ + +#define BOCHSGA_ENGINE_PROP_BUFFER (UDI_GFX_PROP_CUSTOM+0) + +// === CONSTANTS === +const gfxhelpers_op_t bochsga_engine_ops_8bpp[] = { +}; +const gfxhelpers_op_t bochsga_engine_ops_32bpp[] = { + {UDI_GFX_OPERATOR_RGB, 1, 2, 3}, // #0 Output RGB from ops #1,#2,#3 + {UDI_GFX_OPERATOR_SEG, 4, 16, 8}, // #1 Extract 8 bits from bit 16 of #4 + {UDI_GFX_OPERATOR_SEG, 4, 8, 8}, // #2 8 bits from ofs 8 of #4 + {UDI_GFX_OPERATOR_SEG, 4, 0, 8}, // #3 8 bits from ofs 0 of #4 + {UDI_GFX_OPERATOR_BUFFER, 5, 6, 32}, // #4 32 bits from buffer #5 ofs #6 + {UDI_GFX_OPERATOR_ATTR, 0, BOCHSGA_ENGINE_PROP_BUFFER, 0}, // #5 Buffer index + {UDI_GFX_OPERATOR_MAD, 7, 8, 9}, // #6 Get offset (#8 * #7 + #9) + {UDI_GFX_OPERATOR_ATTR, 0, UDI_GFX_PROP_SOURCE_WIDTH, 0}, // #7 Read buffer width + {UDI_GFX_OPERATOR_Y, 0, 0, 0}, // #8 Y coordinate + {UDI_GFX_OPERATOR_X, 0, 0, 0} // #9 X coordinate +}; + +typedef struct { + udi_ubit8_t bitdepth; + gfxhelpers_op_map_t op_map; +} engine_static_t; + +const engine_static_t bochsga_engine_defs[] = { + {.bitdepth = 8, .op_map = {ARRAY_COUNT(bochsga_engine_ops_8bpp), bochsga_engine_ops_8bpp}}, + {.bitdepth = 16}, + {.bitdepth = 24}, + {.bitdepth = 32, .op_map = {ARRAY_COUNT(bochsga_engine_ops_8bpp), bochsga_engine_ops_32bpp}}, +}; +#define N_ENGINES ARRAY_COUNT(bochsga_engine_defs) diff --git a/UDI/drivers/gfx_bochs/bochsga_pio.h b/UDI/drivers/gfx_bochs/bochsga_pio.h new file mode 100644 index 00000000..f5ddf265 --- /dev/null +++ b/UDI/drivers/gfx_bochs/bochsga_pio.h @@ -0,0 +1,22 @@ +/* + * TODO + */ +#ifndef _BOCHSGA_PIO_H_ +#define _BOCHSGA_PIO_H_ + +udi_pio_trans_t bochsga_pio_enable[] = { + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0}, + }; + +enum { + BOCHSGA_PIO_ENABLE, +}; + +const struct s_pio_ops bochsga_pio_ops[] = { + [BOCHSGA_PIO_ENABLE] = UDIH_PIO_OPS_ENTRY(bochsga_pio_enable, 0, UDI_PCI_BAR_2, 0x400, 0xB*2), +// UDIH_PIO_OPS_ENTRY(bochsga_pio_enable, 0, UDI_PCI_BAR_2, 0x400, 0xB*2), + }; +#define N_PIO (sizeof(bochsga_pio_ops)/sizeof(struct s_pio_ops)) + +#endif + diff --git a/UDI/drivers/gfx_bochs/udiprops.txt b/UDI/drivers/gfx_bochs/udiprops.txt new file mode 100644 index 00000000..8b43d5c1 --- /dev/null +++ b/UDI/drivers/gfx_bochs/udiprops.txt @@ -0,0 +1,43 @@ +properties_version 0x101 +supplier 1 +contact 2 +name 3 +shortname bochsga +release 5 1.0 + +requires udi 0x101 +requires udi_physio 0x101 +requires udi_bridge 0x101 +requires udi_gfx 0x101 + +meta 1 udi_bridge +meta 2 udi_gfx +#meta 3 udi_gio + +parent_bind_ops 1 0 1 1 # bridge, rgn 0, ops 1, cb 1 +child_bind_ops 2 0 2 # Provider +#parent_bind_ops 3 0 2 3 # GIO bound to 3D provider + +#enumerates 102 1 1 3 gio_type string software3d + +# - Classic non-PCI version +device 100 1 bus string system sysbus_io_addr_lo ubit32 0x01CE sysbus_io_size ubit32 2 sysbys_mem_addr_lo ubit32 0xE0000000 sysbus_mem_size 0x400000 +# - PCI Version (Non-indexed registers at offset 0x500 in BAR2 MMIO) +device 101 1 bus string pci pci_vendor_id ubit32 0x1234 pci_device_id ubit32 0x1111 pci_base_class ubit32 0x03 pci_sub_clais ubit32 0x00 pci_prog_if ubit32 0x00 + +# Messages +message 1 John Hodge (thePowersGang) +message 2 udi@mutabah.net +message 3 Bochs Graphics Adapter +message 5 BochsGA +message 100 BochsGA ISA Device +message 101 BochsGA PCI Device + +message 1001 "Unknown property passed to %s: %i" + +module bochsga +region 0 + +# Source-only udiprops +compile_options -Wall +source_files bochsga_core.c diff --git a/UDI/drivers/helpers.h b/UDI/drivers/helpers.h new file mode 100644 index 00000000..9b827b3d --- /dev/null +++ b/UDI/drivers/helpers.h @@ -0,0 +1,65 @@ +/* + * UDI Driver helper macros + */ +#ifndef _UDI_HELPERS_H_ +#define _UDI_HELPERS_H_ + +#if DEBUG_ENABLED +# define DEBUG_OUT(fmt, v...) udi_debug_printf("%s: "fmt"\n", __func__ ,## v) +#else +# define DEBUG_OUT(...) do{}while(0) +#endif + +#define ARRAY_COUNT(arr) (sizeof(arr)/sizeof(arr[0])) + +#define __EXPJOIN(a,b) a##b +#define _EXPJOIN(a,b) __EXPJOIN(a,b) +#define _EXPLODE(params...) params +#define _ADDGCB(params...) (udi_cb_t *gcb, params) +#define CONTIN(suffix, call, args, params) extern void _EXPJOIN(suffix##$,__LINE__) _ADDGCB params;\ + call( _EXPJOIN(suffix##$,__LINE__), gcb, _EXPLODE args); } \ + void _EXPJOIN(suffix##$,__LINE__) _ADDGCB params { \ + rdata_t *rdata = gcb->context; + +/* Copied from http://projectudi.cvs.sourceforge.net/viewvc/projectudi/udiref/driver/udi_dpt/udi_dpt.h */ +#define UDIH_SET_ATTR_BOOLEAN(attr, name, val) \ + udi_strcpy((attr)->attr_name, (name)); \ + (attr)->attr_type = UDI_ATTR_BOOLEAN; \ + (attr)->attr_length = sizeof(udi_boolean_t); \ + UDI_ATTR32_SET((attr)->attr_value, (val)) + +#define UDIH_SET_ATTR32(attr, name, val) \ + udi_strcpy((attr)->attr_name, (name)); \ + (attr)->attr_type = UDI_ATTR_UBIT32; \ + (attr)->attr_length = sizeof(udi_ubit32_t); \ + UDI_ATTR32_SET((attr)->attr_value, (val)) + +#define UDIH_SET_ATTR_ARRAY8(attr, name, val, len) \ + udi_strcpy((attr)->attr_name, (name)); \ + (attr)->attr_type = UDI_ATTR_ARRAY8; \ + (attr)->attr_length = (len); \ + udi_memcpy((attr)->attr_value, (val), (len)) + +#define UDIH_SET_ATTR_STRING(attr, name, val, len) \ + udi_strcpy((attr)->attr_name, (name)); \ + (attr)->attr_type = UDI_ATTR_STRING; \ + (attr)->attr_length = (len); \ + udi_strncpy_rtrim((char *)(attr)->attr_value, (val), (len)) +#define UDIH_SET_ATTR_STRFMT(attr, name, maxlen, fmt, v...) \ + udi_strcpy((attr)->attr_name, (name)); \ + (attr)->attr_type = UDI_ATTR_STRING; \ + (attr)->attr_length = udi_snprintf((char *)(attr)->attr_value, (maxlen), (fmt) ,## v ) + +/** + * \brief UDI PIO Helpers + */ +struct s_pio_ops { + udi_pio_trans_t *trans_list; + udi_ubit16_t list_length; + udi_ubit16_t pio_attributes; + udi_ubit32_t regset_idx; + udi_ubit32_t base_offset; + udi_ubit32_t length; +}; +#define UDIH_PIO_OPS_ENTRY(list, attr, regset, base, len) {list, ARRAY_COUNT(list), attr, regset, base, len} +#endif diff --git a/UDI/drivers/helpers_gfx.h b/UDI/drivers/helpers_gfx.h new file mode 100644 index 00000000..f4d9bcff --- /dev/null +++ b/UDI/drivers/helpers_gfx.h @@ -0,0 +1,62 @@ +/* + * UDI Driver Helper Macros + * + * GFX-specific helpers + */ +#ifndef _HELPERS_GFX_H_ +#define _HELPERS_GFX_H_ + +typedef struct { + udi_index_t op; + udi_ubit32_t arg_1; + udi_ubit32_t arg_2; + udi_ubit32_t arg_3; +} gfxhelpers_op_t; + +typedef struct { + udi_index_t op_count; + const gfxhelpers_op_t *ops; +} gfxhelpers_op_map_t; + +static inline udi_ubit32_t gfxhelpers_get_engine_op( + const gfxhelpers_op_map_t *map, udi_index_t index, udi_index_t prop + ) +{ + if( index >= map->op_count ) { + return 0; + } + switch(prop) { + case UDI_GFX_PROP_OPERATOR_OPCODE: return map->ops[index].op; + case UDI_GFX_PROP_OPERATOR_ARG_1: return map->ops[index].arg_1; + case UDI_GFX_PROP_OPERATOR_ARG_2: return map->ops[index].arg_2; + case UDI_GFX_PROP_OPERATOR_ARG_3: return map->ops[index].arg_3; + } + return 0; +} + +static inline void gfxhelpers_return_range_simple( + udi_gfx_range_connector_ack_op_t *callback, udi_gfx_range_cb_t *cb, + udi_ubit32_t min, udi_ubit32_t max, udi_ubit32_t step + ) +{ + +} + +static inline void gfxhelpers_return_range_set( + udi_gfx_range_connector_ack_op_t *callback, udi_gfx_range_cb_t *cb, + udi_ubit32_t count, ... + ) +{ + +} + +static inline void gfxhelpers_return_range_fixed( + udi_gfx_range_connector_ack_op_t *callback, udi_gfx_range_cb_t *cb, + udi_ubit32_t value + ) +{ + gfxhelpers_return_range_simple(callback, cb, value, value, 1); +} + +#endif + diff --git a/UDI/gfx_spec_issues.txt b/UDI/gfx_spec_issues.txt new file mode 100644 index 00000000..e97aea4f --- /dev/null +++ b/UDI/gfx_spec_issues.txt @@ -0,0 +1,31 @@ + + +- Indexed engine operator list (would be better as second set of calls) + > Arguments can be passed using custom attributes +- GL-centric operations (would be better with read_buffer/write_buffer calls) +- No status returned from operations most +- Input data format specifcation + > Engine operator list specifies it, but in an abstract way (which would require quite smart code to determine) + > Doable though, but having a RO property on the engine that notes if it uses a standard pixel format would be nice + + +Engine inspection API: +> Readonly? Property for number of operations + - Readonly because modifcation of the count is not possible + - Attributes can be read, so that's your config mechanisim +> udi_gfx_engine_getop_req(udi_gfx_state_cb_t *cb); +> udi_gfx_engine_getop_ack(udi_gfx_state_cb_t *cb, udi_ubit8_t operation, udi_ubit32_t arg1, udi_ubit32_t arg2, udi_ubit32_t arg3); + + +Buffer manipulation API: + + struct { + udi_cb_t gcb; + udi_index_t buffer_idx; + udi_ubit32_t offset; + udi_buffer_t *data; + } udi_gfx_buffer_cb_t; + +> udi_gfx_buffer_write_req(udi_gfx_buffer_cb_t *cb); +> udi_gfx_buffer_write_ack(udi_gfx_buffer_cb_t *cb, udi_status_t status); +> (OPTIONAL) udi_gfx_buffer_read_req(udi_gfx_buffer_cb_t *cb); diff --git a/UDI/include/udi_gfx.h b/UDI/include/udi_gfx.h new file mode 100644 index 00000000..d9fbcb22 --- /dev/null +++ b/UDI/include/udi_gfx.h @@ -0,0 +1,563 @@ +/** + * Summary: udi_gfx.h + * Contains the graphics metalanguage interface details + * + * Author: + * Marcel Sondaar + * + * License: + * + * + * Source: + * https://www.d-rift.nl/combuster/mos3/?p=viewsource&file=/include/common/udi_gfx.h + */ + +// note that the specification, and thus, the contents of this file is not fixed. + +#ifndef __UDI_GFX_H__ +#define __UDI_GFX_H__ + +#include + +#ifndef UDI_GFX_VERSION +#error "UDI_GFX_VERSION not defined." +#elif UDI_GFX_VERSION != 0x101 +#error "UDI_GFX_VERSION not supported." +#endif + +/** + * Enumeration: UDI_GFX_PROP + * Lists the various UDI properties + */ + +// General state properties +/* Constant: UDI_GFX_PROP_ENABLE + * + * Valid values: + * 0 - disabled + * 1 - enabled + * + * Ranges: + * Hardwired 1, or 0-1 + * + * The connector or engine is enabled (nonzero) or disabled (zero). A disabled + * engine forwards all data from the previous stage unmodified. A disabled + * connector does not send any data over the connector. Drivers may power down + * the physical counterparts of disabled components to preserve power, and users + * should expect delays when enabling connectors or components representing + * framebuffers. Disabling is however not recommended for sprite layers, which + * may repeatedly be enabled and disabled. A disabled component can still have + * its state changed, and the driver must complete all commands and other state + * changes as expected, regardless of disabled or power state. The valid ranges + * reported for this property may be 1 (always enabled) or 0-1 (either enabled + * or disabled). + */ +#define UDI_GFX_PROP_ENABLE 0 +/* Constant: UDI_GFX_PROP_INPUT + * + * Valid values: + * Any valid engine ID, provided no dependency cycles are created, or -1 + * + * Ranges: + * Any non-empty set of valid values. Often hardwired. + * + * Points to the engine that is processed before this unit. In the case of a + * connector, it points to the last engine in a pipeline, and each engine points + * to the next engine in the sequence. A value of -1 indicates a source that + * only yields black pixels. Implementations must not allow cyclic structures. + * Changing this value may reallocate resources, and engines that are no longer + * referenced may lose their data (but not their state) when it is not part of + * any pipeline. If preservation is required, the ENABLE state should be used + * instead. Valid ranges includes one or more from the list of engines and -1 + * combined. In most cases, this property can not be modified. + */ +#define UDI_GFX_PROP_INPUT 1 +/* Constant: UDI_GFX_PROP_WIDTH + * + * Valid values: + * Any non-zero positive number. + * + * Ranges: + * Contains at least one valid value. Often only multiples of UNIT_WIDTH + * or a power of two are allowed. May be hardwired. + * + * Contains the amount of pixels in the horizontal direction. For connectors, + * this is the amount of data pixels rendered horizontally. For engines, this + * is the width in pixels of the image. Pixels requested from an engine outside + * the range (0..width-1) are defined according to the + * property. In some cases, hardware may support only fixed combinations of + * width and height. In such cases, changing the width will also change the + * height to a corresponding valid number. Valid ranges include any values + * strictly above zero. For connectors, expect large continuous ranges, large + * ranges with a certain modulus, a limited number of fixed values, or a + * constant value. + */ +#define UDI_GFX_PROP_WIDTH 2 +/* Constant: UDI_GFX_PROP_HEIGHT + * + * Valid values: + * Any non-zero positive number. + * + * Ranges: + * Contains at least one valid value. Often only multiples of UNIT_HEIGHT + * or a power of two are allowed. May be hardwired. + * + * Contains the amount of pixels in the vertical direction. Functions similar + * to the width property, but changing it will not alter the width property, + * and it's range at any time contains the valid range for the currently + * selected width. + */ +#define UDI_GFX_PROP_HEIGHT 3 + +/* Constant: UDI_GFX_PROP_CUSTOM + * The first property index of the driver's custom range. These are not assigned + * directly assigned by the UDI specification, but may be specified in the + * operator tree. + */ +#define UDI_GFX_PROP_CUSTOM 1024 + +// engine properties + +/* Constant: UDI_GFX_PROP_CLIP + * + * Valid values: + * 0 - points outside width x height are passed from next stage + * 1 - the engine's contents is tiled with size width x height + * 2 - points outside the width overflow into the y coordinate + * 3 - points outside the height overflow into the x coordinate + * + * Ranges: + * Hardwired zero for connectors. Any non-empty subset for engines, usually + * hardwired. + * + * For engines, contains the behaviour for pixels requested outside the width + * and height of the engine. Can be either 0 (pass from next stage), 1 (the + * coordinates are wrapped modulus the height and width), 2 (the coordinates + * overflow onto the next scanline horizontally, and wrap vertically), 3 (the + * coordinates overflow onto the next column vertically, and wrap horizontally). + * Valid ranges contain one or more of these options. For overlays and sprites, + * a value 0 is common. For framebuffers, 2 is the most common value. For + * connectors, this property is always 0 since they do not store pixel data + */ +#define UDI_GFX_PROP_CLIP 4 + +/* Constant: UDI_GFX_PROP_UNIT_WIDTH + * + * Valid values: + * Any non-zero positive value + * + * Ranges: + * Any non-empty set of valid values. May be hardwired to 1 for + * framebuffers, or a range of small values for hardware scaling, or any + * larger hardwired number or set for tiling engines. + * + * Tiles are used to indicate that the hardware groups sets of pixels and have + * each group share certain properties, i.e. color or tile index, or share the + * same chroma subsample with only a different intensity. If the engine has no + * such grouping, or shares all properties over the entire contents, the value + * of this property should be 1. Some tile examples include rescaling, where a + * tile width of 2 indicates a pixel doubling in X direction, or in text mode + * where a tile width of 8 or 9 corresponds with the width of common bitmap + * fonts + */ +#define UDI_GFX_PROP_UNIT_WIDTH 5 + +/* Constant: UDI_GFX_PROP_UNIT_HEIGHT + * + * Valid values: + * Any non-zero positive value + * + * Ranges: + * Any non-empty set of valid values. May be hardwired to 1 for + * framebuffers, or a range of small values for hardware scaling, or any + * larger hardwired number or set for tiling engines. + * + * See , but for the Y direction. Common values are + * 1-2 for framebuffers (doublescanning on or off), identical to the tile + * width, or mostly independent. + */ +#define UDI_GFX_PROP_UNIT_HEIGHT 6 + +#define UDI_GFX_PROP_TRANSLATEX 7 +#define UDI_GFX_PROP_TRANSLATEY 8 +#define UDI_GFX_PROP_SOURCE_WIDTH 12 +#define UDI_GFX_PROP_SOURCE_HEIGHT 13 +#define UDI_GFX_PROP_GL_VERSION 14 +#define UDI_GFX_PROP_GLES_VERSION 15 +#define UDI_GFX_PROP_STATE_BLOCK 16 +/** + * Each engine consists of 1 or more operators + */ +#define UDI_GFX_PROP_OPERATOR_INDEX 17 //!< Index of operator to inspect/manipulate +#define UDI_GFX_PROP_OPERATOR_OPCODE 18 //!< Operation performed by operator +#define UDI_GFX_PROP_OPERATOR_ARG_1 19 //!< argument 1 +#define UDI_GFX_PROP_OPERATOR_ARG_2 20 //!< argument 2 +#define UDI_GFX_PROP_OPERATOR_ARG_3 21 //!< argument 3 +#define UDI_GFX_PROP_COLOR_BITS 22 +#define UDI_GFX_PROP_GL_TARGET 23 +#define UDI_GFX_PROP_INPUTX 25 +#define UDI_GFX_PROP_INPUTY 26 + +// properties for removal: +#define UDI_GFX_PROP_STORE_COUNT 24 // not generic +#define UDI_GFX_PROP_STORE_WIDTH 9 // not generic +#define UDI_GFX_PROP_STORE_HEIGHT 10 // not generic +#define UDI_GFX_PROP_STORE_BITS 11 // not generic +#define UDI_GFX_PROP_PALETTE 1024 // optional, can be derived from the operator tree +#define UDI_GFX_PROP_BUFFER 1025 // optional, can be derived from the operator tree +#define UDI_GFX_PROP_TILESHEET 1026 // optional, can be derived from the operator tree + +// connector properties +#define UDI_GFX_PROP_SIGNAL 23 +#define UDI_GFX_PROP_CONNECTOR_TYPE 24 +#define UDI_GFX_PROP_VGA_H_FRONT_PORCH 25 +#define UDI_GFX_PROP_VGA_H_BACK_PORCH 26 +#define UDI_GFX_PROP_VGA_H_SYNC 27 +#define UDI_GFX_PROP_VGA_V_FRONT_PORCH 28 +#define UDI_GFX_PROP_VGA_V_BACK_PORCH 29 +#define UDI_GFX_PROP_VGA_V_SYNC 30 +#define UDI_GFX_PROP_DOT_CLOCK 31 +#define UDI_GFX_PROP_VGA_H_SYNC_POL 32 +#define UDI_GFX_PROP_VGA_V_SYNC_POL 33 + +/** + * Enumeration: UDI_GFX_SIGNAL + * Lists the various signal types + */ +#define UDI_GFX_SIGNAL_HIDDEN 0 +#define UDI_GFX_SIGNAL_INTEGRATED 0 +#define UDI_GFX_SIGNAL_RGBHV 1 +#define UDI_GFX_SIGNAL_RGBS 2 +#define UDI_GFX_SIGNAL_RGSB 3 +#define UDI_GFX_SIGNAL_YPBPR 4 +#define UDI_GFX_SIGNAL_DVID 5 +#define UDI_GFX_SIGNAL_YUV 6 +#define UDI_GFX_SIGNAL_YIQ 7 +#define UDI_GFX_SIGNAL_Y_UV 8 +#define UDI_GFX_SIGNAL_Y_IQ 9 +#define UDI_GFX_SIGNAL_HDMI 10 +#define UDI_GFX_SIGNAL_TEXT 11 +#define UDI_GFX_SIGNAL_CUSTOM 12 + +/** + * Enumeration: UDI_GFX_CONNECTOR + * Lists the various external connectors + */ +#define UDI_GFX_CONNECTOR_HIDDEN 0 +#define UDI_GFX_CONNECTOR_VGA 1 +#define UDI_GFX_CONNECTOR_DVI 2 +#define UDI_GFX_CONNECTOR_SVIDEO 3 +#define UDI_GFX_CONNECTOR_COMPONENT 4 +#define UDI_GFX_CONNECTOR_HDMI 5 +#define UDI_GFX_CONNECTOR_RF 6 +#define UDI_GFX_CONNECTOR_SCART 7 +#define UDI_GFX_CONNECTOR_COMPOSITE 8 + +/** + * Enumeration: UDI_GFX_OPERATOR + * Lists the display output operator + * + * a1/a2/a3 represents taking the output of a previous operation + * v1/v2/v3 represents the literal value of that argument + */ +#define UDI_GFX_OPERATOR_RGB 0 // output = (color) red(a1) + green(a2) + blue(a3) (each component is UDI_GFX_PROP_COLOR_BITS +#define UDI_GFX_OPERATOR_YUV 1 // output = (color) Y(a1) + U(a2) + V(a3) +#define UDI_GFX_OPERATOR_YIQ 2 // output = (color) Y(a1) + I(a2) + Q(a3) +#define UDI_GFX_OPERATOR_I 3 // output = (color) intensity(a1) +#define UDI_GFX_OPERATOR_ALPHA 4 // output = (color) a1 + alpha(a2) +#define UDI_GFX_OPERATOR_ADD 5 // output = a1 + a2 + v3 +#define UDI_GFX_OPERATOR_SUB 6 // output = a1 - a2 - v3 +#define UDI_GFX_OPERATOR_MUL 7 // output = a1 * a2 +#define UDI_GFX_OPERATOR_DIV 8 // output = a1 / a2 +#define UDI_GFX_OPERATOR_MAD 9 // output = a1 * a2 + a3 +#define UDI_GFX_OPERATOR_FRC 10 // output = (a1 * a2) / a3 +#define UDI_GFX_OPERATOR_SHR 11 // output = a1 >> (a2 + v3) +#define UDI_GFX_OPERATOR_SHL 12 // output = a1 << (a2 + v3) +#define UDI_GFX_OPERATOR_ROR 13 // output = a1 >> a2 (over a3 bits) +#define UDI_GFX_OPERATOR_ROL 14 // output = a1 << a2 (over a3 bits) +#define UDI_GFX_OPERATOR_SAR 15 // output = a1 >> a2 (width is a3 bits, i.e. empties are filled with bit a3-1) +#define UDI_GFX_OPERATOR_SAL 16 // output = a1 <<< (a2 + v3) (empties filled with bit 0) +#define UDI_GFX_OPERATOR_AND 17 // output = a1 & a2 +#define UDI_GFX_OPERATOR_OR 18 // output = a1 | a2 | v3 +#define UDI_GFX_OPERATOR_NOT 19 // output = ~a1 +#define UDI_GFX_OPERATOR_XOR 20 // output = a1 ^ a2 ^ v3 +#define UDI_GFX_OPERATOR_NEG 21 // output = -a1 +#define UDI_GFX_OPERATOR_SEG 22 // output = (a1 >> v2) & (2**v3-1) (select v3 bits starting from bit v2) +#define UDI_GFX_OPERATOR_RANGE 23 // output = (a1 > a2) ? a2 : ((a1 < a3) ? a3 : a1) +#define UDI_GFX_OPERATOR_CONST 24 // output = v1 +#define UDI_GFX_OPERATOR_ATTR 25 // output = property[a1 + v2] +#define UDI_GFX_OPERATOR_SWITCH 26 // output = output[(a1 % v3) + v2] +#define UDI_GFX_OPERATOR_BUFFER 27 // output = buffer[a1][a2] (buffer is v3 bits per entry) +#define UDI_GFX_OPERATOR_X 28 // output = output x pixel +#define UDI_GFX_OPERATOR_Y 29 // output = output y pixel +#define UDI_GFX_OPERATOR_TX 30 // output = horizontal tile index belonging to output pixel +#define UDI_GFX_OPERATOR_TY 31 // output = vertical tile index belonging to output pixel +#define UDI_GFX_OPERATOR_TXOFF 32 // output = horizontal offset from start of tile +#define UDI_GFX_OPERATOR_TYOFF 33 // output = vertical offset from start of tile +#define UDI_GFX_OPERATOR_INPUT 34 // output = input engine[x][y] component v1 +#define UDI_GFX_OPERATOR_DINPUT 35 // output = input engine[a1][a2] component v3 + + + +// Constant: UDI_GFX_PROVIDER_OPS_NUM +// the ops number used for the graphics driver +#define UDI_GFX_PROVIDER_OPS_NUM 1 + +// Constant: UDI_GFX_CLIENT_OPS_NUM +// the ops number used for the graphics application +#define UDI_GFX_CLIENT_OPS_NUM 2 + +// Structure: udi_gfx_bind_cb_t +// Contains the operations of a driver binding request +typedef struct { + // Variable: gcb + // The main control block + udi_cb_t gcb; +} udi_gfx_bind_cb_t; +#define UDI_GFX_BIND_CB_NUM 1 + +// Function: udi_block_bind_req +// function pointer prototype for connecting to a block device +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_bind_req_op_t (udi_gfx_bind_cb_t *cb ); +udi_gfx_bind_req_op_t udi_gfx_bind_req; + +// Function: udi_gfx_bind_ack +// function pointer prototype for acknowledging a connection request +// +// in: +// cb - A pointer to a +// sockets - The number of addressable socket components +// engines - The number of addressable engine components +// status - The result of the bind operation +// +typedef void udi_gfx_bind_ack_op_t (udi_gfx_bind_cb_t *cb, udi_index_t sockets, udi_index_t engines, udi_status_t status ); +udi_gfx_bind_ack_op_t udi_gfx_bind_ack; + +// Function: udi_gfx_unbind_req +// function pointer prototype for disconnecting a block device +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_unbind_req_op_t (udi_gfx_bind_cb_t *cb ); +udi_gfx_unbind_req_op_t udi_gfx_unbind_req; + +// Function: udi_gfx_unbind_ack +// function pointer prototype for connecting to a block device +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_unbind_ack_op_t (udi_gfx_bind_cb_t *cb ); +udi_gfx_unbind_ack_op_t udi_gfx_unbind_ack; + +// Structure: udi_gfx_state_cb_t +// Contains the operations of a read/write transaction +typedef struct { + // Variable: gcb + // The main control block + udi_cb_t gcb; + udi_ubit32_t subsystem; + udi_ubit32_t attribute; +} udi_gfx_state_cb_t; +#define UDI_GFX_STATE_CB_NUM 2 + +// Function: udi_gfx_set_engine_req +// function pointer prototype for setting an engine state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_set_engine_req_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value); +udi_gfx_set_engine_req_op_t udi_gfx_set_engine_req; + +// Function: udi_gfx_set_connector_req +// function pointer prototype for setting an connector state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_set_connector_req_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value); +udi_gfx_set_connector_req_op_t udi_gfx_set_connector_req; + +// Function: udi_gfx_set_engine_ack +// function pointer prototype for setting an engine state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_set_engine_ack_op_t (udi_gfx_state_cb_t *cb ); +udi_gfx_set_engine_ack_op_t udi_gfx_set_engine_ack; + +// Function: udi_gfx_set_connector_ack +// function pointer prototype for setting an engine state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_set_connector_ack_op_t (udi_gfx_state_cb_t *cb ); +udi_gfx_set_connector_ack_op_t udi_gfx_set_connector_ack; + +// Function: udi_gfx_get_engine_req +// function pointer prototype for setting an engine state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_get_engine_req_op_t (udi_gfx_state_cb_t *cb ); +udi_gfx_get_engine_req_op_t udi_gfx_get_engine_req; + +// Function: udi_gfx_get_connector_req +// function pointer prototype for setting an connector state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_get_connector_req_op_t (udi_gfx_state_cb_t *cb ); +udi_gfx_get_connector_req_op_t udi_gfx_get_connector_req; + +// Function: udi_gfx_get_engine_ack +// function pointer prototype for setting an engine state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_get_engine_ack_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value); +udi_gfx_get_engine_ack_op_t udi_gfx_get_engine_ack; + +// Function: udi_gfx_get_connector_ack +// function pointer prototype for setting an engine state +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_get_connector_ack_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value); +udi_gfx_get_connector_ack_op_t udi_gfx_get_connector_ack; + + +// Structure: udi_gfx_range_cb_t +// Contains the operations of a range request transaction +typedef struct { + // Variable: gcb + // The main control block + udi_cb_t gcb; + udi_ubit32_t subsystem; + udi_ubit32_t attribute; + udi_buf_t * rangedata; +} udi_gfx_range_cb_t; +#define UDI_GFX_RANGE_CB_NUM 3 + +// Function: udi_gfx_range_engine_req +// function pointer prototype for getting an engine property range +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_range_engine_req_op_t (udi_gfx_range_cb_t *cb ); +udi_gfx_range_engine_req_op_t udi_gfx_range_engine_req; + +// Function: udi_gfx_range_connector_req +// function pointer prototype for getting a connector property range +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_range_connector_req_op_t (udi_gfx_range_cb_t *cb ); +udi_gfx_range_connector_req_op_t udi_gfx_range_connector_req; + +// Function: udi_gfx_range_engine_ack +// function pointer prototype for replying an engine property range +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_range_engine_ack_op_t (udi_gfx_range_cb_t *cb ); +udi_gfx_range_engine_ack_op_t udi_gfx_range_engine_ack; + +// Function: udi_gfx_range_connector_ack +// function pointer prototype for replying a connector property range +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_range_connector_ack_op_t (udi_gfx_range_cb_t *cb ); +udi_gfx_range_connector_ack_op_t udi_gfx_range_connector_ack; + + +// Structure: udi_gfx_command_cb_t +// Contains the operations of a command sequence +typedef struct { + // Variable: gcb + // The main control block + udi_cb_t gcb; + udi_buf_t * commanddata; +} udi_gfx_command_cb_t; +#define UDI_GFX_COMMAND_CB_NUM 4 + +// Function: udi_gfx_command +// function pointer prototype for sending command data +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_command_req_op_t (udi_gfx_command_cb_t *cb ); +udi_gfx_command_req_op_t udi_gfx_command_req; + +// Function: udi_gfx_command_ack +// function pointer prototype for sending command data +// +// in: +// cb - A pointer to a +// +typedef void udi_gfx_command_ack_op_t (udi_gfx_command_cb_t *cb); +udi_gfx_command_ack_op_t udi_gfx_command_ack; + +/* Structure: udi_gfx_provider_ops_t + The graphics metalanguage e*ntry points (provider side) + */ +typedef const struct { + udi_channel_event_ind_op_t *channel_event_ind_op; + udi_gfx_bind_req_op_t *gfx_bind_req_op; + udi_gfx_unbind_req_op_t *gfx_unbind_req_op; + udi_gfx_set_connector_req_op_t *gfx_set_connector_req_op; + udi_gfx_set_engine_req_op_t *gfx_set_engine_req_op; + udi_gfx_get_connector_req_op_t *gfx_get_connector_req_op; + udi_gfx_get_engine_req_op_t *gfx_get_engine_req_op; + udi_gfx_range_connector_req_op_t *gfx_range_connector_req_op; + udi_gfx_range_engine_req_op_t *gfx_range_engine_req_op; + udi_gfx_command_req_op_t *gfx_command_op; +} udi_gfx_provider_ops_t; + +/* Structure: udi_gfx_client_ops_t + * The graphics metalanguage entry points (client side) + */ +typedef const struct { + udi_channel_event_ind_op_t *channel_event_ind_op; + udi_gfx_bind_ack_op_t *udi_gfx_bind_ack; + udi_gfx_unbind_ack_op_t *udi_gfx_unbind_ack; + udi_gfx_set_connector_ack_op_t *udi_gfx_set_connector_ack; + udi_gfx_set_engine_ack_op_t *udi_gfx_set_engine_ack; + udi_gfx_get_connector_ack_op_t *udi_gfx_get_connector_ack; + udi_gfx_get_engine_ack_op_t *udi_gfx_get_engine_ack; + udi_gfx_range_connector_ack_op_t *udi_gfx_range_connector_ack; + udi_gfx_range_engine_ack_op_t *udi_gfx_range_engine_ack; + udi_gfx_command_ack_op_t *udi_gfx_command_ack; +} udi_gfx_client_ops_t; + + +// temporary +#ifndef UDI_ANNOY_ME +void EngineReturnSimpleRange (int source, int index, int prop, int first, int last, int modulus); +void ConnectorReturnSimpleRange (int source, int index, int prop, int first, int last, int modulus); +void EngineReturnConstantRange (int source, int index, int prop, int value); +void ConnectorReturnConstantRange (int source, int index, int prop, int value); +void EngineReturnBooleanRange (int source, int index, int prop, int value1, int value2); +void ConnectorReturnBooleanRange (int source, int index, int prop, int value1, int value2); +#endif + +#endif +