更新HCppBox

This commit is contained in:
HEYAHONG 2025-02-20 15:39:23 +08:00
parent ac99ca064e
commit 760e10b76b
No known key found for this signature in database
GPG Key ID: 97E3E469FE2C920B
47 changed files with 9301 additions and 195 deletions

View File

@ -102,6 +102,7 @@ static bool hgui_scene1_app_event_input_helper(uint8_t type,void *eventparam,siz
static bool hgui_scene1_app_init_callback(const hgui_scene1_app_t *app,void *usr)
{
(void)usr;
if(hgui_scene1_app_was_init(app))
{
return true;

View File

@ -10,6 +10,8 @@
#include "hcompiler.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdbool.h"
#include "string.h"
long hcompiler_get_stdc_version(void)
{
@ -20,6 +22,70 @@ long hcompiler_get_stdc_version(void)
#endif // __STDC_VERSION__
}
static bool is_number(const char c)
{
return c >= '0' && c <= '9';
}
static size_t get_number(const char *str,size_t index)
{
if(str==NULL)
{
return 0;
}
size_t str_len=strlen(str);
const char *number_str=NULL;
size_t number_len=0;
for(size_t i=0; i<str_len; i++)
{
if(is_number(str[i]))
{
if(number_str==NULL)
{
number_len=1;
number_str=&str[i];
}
else
{
number_len++;
}
}
else
{
if(number_str!=NULL)
{
if(index!=0)
{
number_str=NULL;
index--;
}
else
{
break;
}
}
}
}
if(index!=0)
{
number_str=NULL;
number_len=0;
}
if(number_str!=NULL && number_len > 0)
{
size_t ret=0;
for(size_t i=0; i<number_len; i++)
{
ret*=10;
ret+=(number_str[i]-'0');
}
return ret;
}
return 0;
}
const char * hcompiler_get_date(void)
{
@ -75,7 +141,7 @@ static int month_strcmp(const char *str1,const char *str2)
int hcompiler_get_date_year(void)
{
const char *date=hcompiler_get_date();
return (date[7]-'0')*1000+(date[8]-'0')*100+(date[9]-'0')*10+(date[10]-'0');
return get_number(date,1);
}
@ -95,25 +161,25 @@ int hcompiler_get_date_month(void)
int hcompiler_get_date_day(void)
{
const char *date=hcompiler_get_date();
return (date[4]-'0')*10+(date[5]-'0');
return get_number(date,0);
}
int hcompiler_get_time_hour(void)
{
const char *timestr=hcompiler_get_time();
return (timestr[0]-'0')*10+(timestr[1]-'0');
return get_number(timestr,0);
}
int hcompiler_get_time_minute(void)
{
const char *timestr=hcompiler_get_time();
return (timestr[3]-'0')*10+(timestr[4]-'0');
return get_number(timestr,1);
}
int hcompiler_get_time_second(void)
{
const char *timestr=hcompiler_get_time();
return (timestr[6]-'0')*10+(timestr[7]-'0');
return get_number(timestr,2);
}

View File

@ -8,11 +8,24 @@
**************************************************************/
#include "hsimulator.h"
#include "simulator/rp_pio_sm/rp_pio_sm.h"
#include "simulator/common/hs_common.h"
#include "simulator/common/hs_common.c"
#include "simulator/rp_pio_sm/rp_pio.h"
#include "simulator/rp_pio_sm/rp_pio_sm.c"
#include "simulator/rp_pio_sm/rp_pio_rom.c"
#include "simulator/mcs_51/mcs_51_core.h"
#include "simulator/mcs_51/mcs_51.h"
#include "simulator/mcs_51/mcs_51_common.c"
#include "simulator/mcs_51/mcs_51_disassembly.c"
#include "simulator/mcs_51/mcs_51_rom.c"
#include "simulator/mcs_51/mcs_51_ram.c"
#include "simulator/mcs_51/mcs_51_core.c"
#include "simulator/mcs_51/mcs_51_serial.c"
#include "simulator/risc-v/risc-v.h"
#include "simulator/risc-v/risc-v_opcodes.c"
#include "simulator/risc-v/risc-v_common.c"

View File

@ -14,8 +14,10 @@ extern "C"
{
#endif // __cplusplus
#include "simulator/rp_pio_sm/rp_pio_sm.h"
#include "simulator/common/hs_common.h"
#include "simulator/rp_pio_sm/rp_pio.h"
#include "simulator/mcs_51/mcs_51.h"
#include "simulator/risc-v/risc-v.h"
#ifdef __cplusplus
}

View File

@ -0,0 +1,14 @@
/***************************************************************
* Name: hs_common.c
* Purpose: hs_common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-06
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "hs_common.h"
#include "serial/8250/8250.h"
#include "serial/8250/8250.c"

View File

@ -0,0 +1,26 @@
/***************************************************************
* Name: hs_common.h
* Purpose: hs_common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-06
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_COMMON_H__
#define __HS_COMMON_H__
#include "stdint.h"
#include "stdlib.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#include "serial/8250/8250.h"
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_COMMON_H__

View File

@ -0,0 +1,646 @@
/***************************************************************
* Name: hs_common.c
* Purpose: hs_common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-06
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "8250.h"
void hs_common_serial_8250_init(hs_common_serial_8250_t *dev,hs_common_serial_8250_io_callback_t io,void *usr,size_t clk_freq)
{
hs_common_serial_8250_t temp=HS_COMMON_SERIAL_8250_INITIALIZER;
temp.io=io;
temp.usr=usr;
if(clk_freq!=0)
{
temp.clk_freq=clk_freq;
}
if(dev!=NULL)
{
(*dev)=temp;
}
}
void hs_common_serial_8250_bus_write(hs_common_serial_8250_t *dev,uint8_t address,uint8_t reg_data)
{
if(dev==NULL)
{
return;
}
//地址只允许07
address%=8;
bool DLAB=((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR] &0x80)!=0);
switch(address)
{
case 0:
{
if(DLAB)
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLL]=reg_data;
}
else
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_THR]=reg_data;
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MCR]&0x10)!=0)
{
//Loop Back
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&0x01)==0)
{
//当前未接收到数据
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_RBR]=reg_data;
//当前数据就绪
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]|=0x01;
}
}
if(dev->io!=NULL)
{
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_TRANSMIT_BYTE,&dev->registers[HS_COMMON_SERIAL_8250_REGISTER_THR]);
}
}
}
break;
case 1:
{
if(DLAB)
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLM]=reg_data;
}
else
{
//高4位为保留
reg_data&=0x0F;
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IER]=reg_data;
}
}
break;
case 2:
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_FCR]=reg_data;
}
break;
case 3:
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR]=reg_data;
}
break;
case 4:
{
if(dev->io!=NULL)
{
{
uint8_t out2=(((reg_data&0x08)!=0)?1:0);
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_OUT2,&out2);
}
{
uint8_t out1=(((reg_data&0x04)!=0)?1:0);
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_OUT1,&out1);
}
{
uint8_t rts=(((reg_data&0x02)!=0)?1:0);
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_RTS,&rts);
}
{
uint8_t dtr=(((reg_data&0x01)!=0)?1:0);
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_DTR,&dtr);
}
}
//高3位为保留位始终为0
reg_data&=0x1F;
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MCR]=reg_data;
}
break;
case 5:
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]=reg_data;
}
break;
case 6:
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MSR]=reg_data;
}
break;
case 7:
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_SCR]=reg_data;
}
break;
default:
{
}
break;
}
}
void hs_common_serial_8250_bus_read(hs_common_serial_8250_t *dev,uint8_t address,uint8_t *reg_data)
{
if(dev==NULL)
{
return;
}
//地址只允许07
address%=8;
bool DLAB=((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR] &0x80)!=0);
switch(address)
{
case 0:
{
if(DLAB)
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLL];
}
}
else
{
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MCR]&0x10)!=0)
{
//Loop Back
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&0x01)!=0)
{
//有数据
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_RBR];
}
//自动清除,数据准备好标志
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&=0xFE;
break;
}
}
//非Loopback模式或者Loopback模式下无数据
if(dev->io!=NULL)
{
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_RECEIVE_BYTE,&dev->registers[HS_COMMON_SERIAL_8250_REGISTER_RBR]);
}
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_RBR];
}
//自动清除,数据准备好标志
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&=0xFE;
}
}
break;
case 1:
{
if(DLAB)
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLM];
}
}
else
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IER];
}
}
}
break;
case 2:
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR];
}
}
break;
case 3:
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
}
}
break;
case 4:
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MCR];
}
}
break;
case 5:
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR];
}
}
break;
case 6:
{
if(reg_data!=NULL)
{
if(dev->io!=NULL)
{
uint8_t new_msr=0;
uint8_t value=0;
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_DCD,&value);
if(value!=0)
{
new_msr|=0x80;
}
value=0;
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_RI,&value);
if(value!=0)
{
new_msr|=0x40;
}
value=0;
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_DSR,&value);
if(value!=0)
{
new_msr|=0x20;
}
value=0;
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_CTS,&value);
if(value!=0)
{
new_msr|=0x10;
}
new_msr |= ((new_msr^dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MSR])>>4);
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MSR]=new_msr;
}
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MSR];
}
}
break;
case 7:
{
if(reg_data!=NULL)
{
(*reg_data)=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_SCR];
}
}
break;
default:
{
}
break;
}
}
void hs_common_serial_8250_bus_write32(hs_common_serial_8250_t *dev,uint8_t address,uint32_t reg_data)
{
if(address%4!=0)
{
return;
}
hs_common_serial_8250_bus_write(dev,address/4,(uint8_t)reg_data);
}
void hs_common_serial_8250_bus_read32(hs_common_serial_8250_t *dev,uint8_t address,uint32_t *reg_data)
{
if(address%4!=0)
{
return;
}
uint8_t data=0;
hs_common_serial_8250_bus_read(dev,address/4,&data);
if(reg_data!=NULL)
{
(*reg_data)=data;
}
}
void hs_common_serial_8250_bus_tick(hs_common_serial_8250_t *dev)
{
if(dev==NULL)
{
return;
}
if(dev->io!=NULL)
{
uint8_t data=0;
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_TICK,&data);
}
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IER]&0x0F)==0)
{
//无中断使能,直接清除现有中断等待标志
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]|=0x01;
}
else
{
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&0x01)!=0)
{
//当前无中断,按照优先级顺序进行中断扫描
for(size_t i=0; i<8; i++)
{
switch(i)
{
case 0:
{
//接收器线中断INTID=0x3
}
break;
case 1:
{
//接收数据有效中断INTID=0x2
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IER]&0x01)!=0)
{
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&0x01)!=0)
{
//指示等待接收数据中断
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&=0xF0;
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]|=((0x2)<<1);
}
}
}
break;
case 2:
{
//字符超时中断INTID=0x6
}
break;
case 3:
{
//THR空中断INTID=0x1
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IER]&0x02)!=0)
{
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&0x20)!=0)
{
//THR空中断
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&=0xF0;
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]|=((0x1)<<1);
}
}
}
break;
case 4:
{
//Modem状态INTID=0x0
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IER]&0x08)!=0)
{
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_MSR]&0x0F)!=0)
{
//Modem状态中断(注意中断过程中应当读取MSR寄存器以清空相应标志)
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&=0xF0;
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]|=((0x0)<<1);
}
}
}
break;
case 5:
{
}
break;
case 6:
{
}
break;
case 7:
{
}
break;
default:
{
}
break;
}
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&0x01)==0)
{
//已有中断等待处理,退出中断扫描。
break;
}
}
}
}
if((dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&0x01)==0)
{
//有中断正在等待
if(dev->io!=NULL)
{
//调用中断,在中断中应该清除中断标志,否则会再次中断。
dev->io(dev,HS_COMMON_SERIAL_8250_IO_OPERATE_IRQ,&dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]);
//清除保留位
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_IIR]&=(~0x30);
}
}
//TODO:进行8250内部处理
}
size_t hs_common_serial_8250_config_baud_get(hs_common_serial_8250_t *dev)
{
if(dev==NULL)
{
return 0;
}
size_t divisor_latch=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLM]*256UL+dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLL];
if(divisor_latch==0)
{
divisor_latch=1;
}
return dev->clk_freq/(16*divisor_latch);
}
void hs_common_serial_8250_config_baud_set(hs_common_serial_8250_t *dev,size_t baud)
{
if(dev==NULL)
{
return ;
}
if(baud==0)
{
//默认波特率115200
baud=115200;
}
size_t divisor_latch=dev->clk_freq/(16*baud);
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLM]=((divisor_latch>>8)&0xFF);
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_DLL]=(divisor_latch&0xFF);
}
hs_common_serial_8250_config_parity_t hs_common_serial_8250_config_parity_get(hs_common_serial_8250_t *dev)
{
if(dev==NULL)
{
return HS_COMMON_SERIAL_8250_CONFIG_PARITY_NONE;
}
uint8_t LCR=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
if((LCR&0x08)==0) //PEN
{
return HS_COMMON_SERIAL_8250_CONFIG_PARITY_NONE;
}
else
{
if((LCR&0x20)!=0) //Stick Parity
{
if((LCR&0x10)!=0) //EPS
{
return HS_COMMON_SERIAL_8250_CONFIG_PARITY_SPACE;
}
else
{
return HS_COMMON_SERIAL_8250_CONFIG_PARITY_MARK;
}
}
else
{
if((LCR&0x10)!=0) //EPS
{
return HS_COMMON_SERIAL_8250_CONFIG_PARITY_EVEN;
}
else
{
return HS_COMMON_SERIAL_8250_CONFIG_PARITY_ODD;
}
}
}
}
void hs_common_serial_8250_config_parity_set(hs_common_serial_8250_t *dev,hs_common_serial_8250_config_parity_t parity)
{
if(dev==NULL)
{
return;
}
uint8_t LCR=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
switch(parity)
{
case HS_COMMON_SERIAL_8250_CONFIG_PARITY_NONE:
{
LCR&=(~0x08);//PEN
}
break;
case HS_COMMON_SERIAL_8250_CONFIG_PARITY_EVEN:
{
LCR|=(0x08); //PEN
LCR|=(0x10); //EPS
LCR&=(~0x20); //Stick Parity
}
break;
case HS_COMMON_SERIAL_8250_CONFIG_PARITY_ODD:
{
LCR|=(0x08); //PEN
LCR&=(~0x10); //EPS
LCR&=(~0x20); //Stick Parity
}
break;
case HS_COMMON_SERIAL_8250_CONFIG_PARITY_SPACE:
{
LCR|=(0x08); //PEN
LCR|=(0x10); //EPS
LCR|=(0x20); //Stick Parity
}
break;
case HS_COMMON_SERIAL_8250_CONFIG_PARITY_MARK:
{
LCR|=(0x08); //PEN
LCR&=(~0x10); //EPS
LCR|=(0x20); //Stick Parity
}
break;
default:
{
}
break;
}
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR]=LCR;
}
size_t hs_common_serial_8250_config_stopbits_get(hs_common_serial_8250_t *dev)
{
if(dev==NULL)
{
return 1;
}
uint8_t LCR=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
if((LCR&0x04)!=0)
{
return 2;
}
return 1;
}
void hs_common_serial_8250_config_stopbits_set(hs_common_serial_8250_t *dev,size_t stopbits)
{
if(dev==NULL)
{
return;
}
uint8_t LCR=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
if(stopbits >= 2)
{
LCR|=(0x04);
}
else
{
LCR&=(~0x04);
}
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR]=LCR;
}
size_t hs_common_serial_8250_config_databits_get(hs_common_serial_8250_t *dev)
{
if(dev==NULL)
{
return 8;
}
uint8_t LCR=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
return 5+(LCR&0x03);
}
void hs_common_serial_8250_config_databits_set(hs_common_serial_8250_t *dev,size_t databits)
{
if(dev==NULL)
{
return ;
}
if(databits<5)
{
databits=5;
}
if(databits>8)
{
databits=8;
}
uint8_t LCR=dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR];
LCR&=(~0x03);
LCR|=(databits-5);
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LCR]=LCR;
}
bool hs_common_serial_8250_status_dataready_get(hs_common_serial_8250_t *dev)
{
if(dev==NULL)
{
return false;
}
return (dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]&0x01)!=0;
}
bool hs_common_serial_8250_status_dataready_set(hs_common_serial_8250_t *dev,uint8_t data)
{
if(dev==NULL)
{
return false;
}
if(!hs_common_serial_8250_status_dataready_get(dev))
{
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_RBR]=data;
dev->registers[HS_COMMON_SERIAL_8250_REGISTER_LSR]|=0x01;
return true;
}
return false;
}

View File

@ -0,0 +1,290 @@
/***************************************************************
* Name: 8250.h
* Purpose: 8250
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-06
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_COMMON_SERIAL_8250_H__
#define __HS_COMMON_SERIAL_8250_H__
#include "stdint.h"
#include "stdlib.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*
* 8250,8250便
* =/(16*)
* =/(16*)
*/
#ifndef HS_COMMON_SERIAL_8250_CLK_FREQ
#define HS_COMMON_SERIAL_8250_CLK_FREQ (1843200)
#endif // HS_COMMON_SERIAL_8250_CLK_FREQ
typedef enum
{
HS_COMMON_SERIAL_8250_REGISTER_RBR=0, /**< 接收缓冲寄存器只可读取DLAB=0访问此寄存器*/
HS_COMMON_SERIAL_8250_REGISTER_THR, /**< 发送保持寄存器,只可写入 DLAB=0访问此寄存器*/
HS_COMMON_SERIAL_8250_REGISTER_IER, /**< 中断使能寄存器, 可读写DLAB=0访问此寄存器*/
HS_COMMON_SERIAL_8250_REGISTER_IIR, /**< 中断指示寄存器,只可读取*/
HS_COMMON_SERIAL_8250_REGISTER_FCR, /**< FIFO控制寄存器只可写入*/
HS_COMMON_SERIAL_8250_REGISTER_LCR, /**< 线路控制寄存器,可读写*/
HS_COMMON_SERIAL_8250_REGISTER_MCR, /**< Modem控制寄存器可读写*/
HS_COMMON_SERIAL_8250_REGISTER_LSR, /**< 线路状态寄存器,可读写**/
HS_COMMON_SERIAL_8250_REGISTER_MSR, /**< Modem状态寄存器可读写**/
HS_COMMON_SERIAL_8250_REGISTER_SCR, /**< Scratch寄存器可读写**/
HS_COMMON_SERIAL_8250_REGISTER_DLL, /**< 除数低字节寄存器DLAB=1访问此寄存器 */
HS_COMMON_SERIAL_8250_REGISTER_DLM, /**< 除数高字节寄存器DLAB=1访问此寄存器 */
HS_COMMON_SERIAL_8250_REGISTER_MAX //用于确定寄存器的数量
} hs_common_serial_8250_register_t; /**< 寄存器 */
typedef enum
{
HS_COMMON_SERIAL_8250_IO_OPERATE_TRANSMIT_BYTE=0, /**< 发送数据,写THR时触发*/
HS_COMMON_SERIAL_8250_IO_OPERATE_RECEIVE_BYTE, /**< 接收数据,读RBR时触发 */
HS_COMMON_SERIAL_8250_IO_OPERATE_IRQ, /**< 中断请求当中断使能且发生相应中断时触发数据为IIR寄存器 */
HS_COMMON_SERIAL_8250_IO_OPERATE_TICK, /**< 时钟节拍一般用于8250内部寄存器更新 */
HS_COMMON_SERIAL_8250_IO_OPERATE_DCD, /**< DCD信号数据返回1表示有效并非指高电平 */
HS_COMMON_SERIAL_8250_IO_OPERATE_RI, /**< RI信号 数据返回1表示有效并非指高电平*/
HS_COMMON_SERIAL_8250_IO_OPERATE_DSR, /**< DSR信号 数据返回1表示有效并非指高电平*/
HS_COMMON_SERIAL_8250_IO_OPERATE_CTS, /**< CTS信号 数据返回1表示有效并非指高电平*/
HS_COMMON_SERIAL_8250_IO_OPERATE_OUT2, /**< 输出OUT2信号 数据为1表示有效并非指高电平通常低电平有效*/
HS_COMMON_SERIAL_8250_IO_OPERATE_OUT1, /**< 输出OUT1信号 数据为1表示有效并非指高电平通常低电平有效*/
HS_COMMON_SERIAL_8250_IO_OPERATE_RTS, /**< 输出RTS信号 数据为1表示有效并非指高电平通常低电平有效*/
HS_COMMON_SERIAL_8250_IO_OPERATE_DTR, /**< 输出DTR信号 数据为1表示有效并非指高电平通常低电平有效*/
} hs_common_serial_8250_io_operate_t; /**< IO操作 */
/** \brief 8250设备前向声明
*/
struct hs_common_serial_8250;
/** \brief 8250 IO操作(用户需要实现相应IO操作)
*
* \param dev struct hs_common_serial_8250* 8250
* \param io_operate hs_common_serial_8250_io_operate_t
* \param data uint8_t*
* \return bool
*
*/
typedef bool (*hs_common_serial_8250_io_callback_t)(struct hs_common_serial_8250 *dev,hs_common_serial_8250_io_operate_t io_operate,uint8_t *data);
typedef struct hs_common_serial_8250
{
hs_common_serial_8250_io_callback_t io; /**< IO操作 */
void * usr; /**< 用户参数 */
size_t clk_freq; /**< 时钟频率,用于计算波特率 */
uint8_t registers[HS_COMMON_SERIAL_8250_REGISTER_MAX]; /**< 内部寄存器可使用hs_common_serial_8250_register_t作为下标访问相应寄存器 */
} hs_common_serial_8250_t;
/** \brief hs_common_serial_8250_t初始化参数
*
*
*/
#define HS_COMMON_SERIAL_8250_INITIALIZER \
{\
NULL,\
NULL,\
HS_COMMON_SERIAL_8250_CLK_FREQ,\
{\
0x00,\
0xff,\
0x00,\
0x01,\
0x00,\
0x03,\
0x00,\
0x60,\
0x00,\
0x00,\
0x01,\
0x00\
}\
}
/** \brief 8250 初始化
*
* \param dev struct hs_common_serial_8250* 8250
* \param io hs_common_serial_8250_io_callback_t IO操作
* \param usr void *
* \param clk_freq size_t
*
*/
void hs_common_serial_8250_init(hs_common_serial_8250_t *dev,hs_common_serial_8250_io_callback_t io,void *usr,size_t clk_freq);
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_RBR 0 /**< 接收缓冲寄存器只可读取DLAB=0访问此寄存器*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_THR 0 /**< 发送保持寄存器,只可写入 DLAB=0访问此寄存器*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_IER 1 /**< 中断使能寄存器, 可读写DLAB=0访问此寄存器*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_IIR 2 /**< 中断指示寄存器,只可读取*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_FCR 2 /**< FIFO控制寄存器只可写入*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_LCR 3 /**< 线路控制寄存器,可读写*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_MCR 4 /**< Modem控制寄存器可读写*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_LSR 5 /**< 线路状态寄存器,可读写*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_MSR 6 /**< Modem状态寄存器可读写*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_SCR 7 /**< Scratch寄存器可读写*/
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_DLL 0 /**< 除数低字节寄存器DLAB=1访问此寄存器 */
#define HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_DLM 1 /**< 除数高字节寄存器DLAB=1访问此寄存器 */
/** \brief 8250 总线写(一般由总线上的主设备(如CPU)调用)
*
* \param dev hs_common_serial_8250_t* 8250
* \param address uint8_t 线07,HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_*
* \param reg_data uint8_t
*
*/
void hs_common_serial_8250_bus_write(hs_common_serial_8250_t *dev,uint8_t address,uint8_t reg_data);
/** \brief 8250 总线读(一般由总线上的主设备(如CPU)调用)
*
* \param dev hs_common_serial_8250_t* 8250
* \param address uint8_t 线07,HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_*
* \param reg_data uint8_t*
*
*/
void hs_common_serial_8250_bus_read(hs_common_serial_8250_t *dev,uint8_t address,uint8_t *reg_data);
/** \brief 8250 总线32位对齐写(一般由总线上的主设备(如CPU)调用)
*
* \param dev hs_common_serial_8250_t* 8250
* \param address uint8_t 线00x1C,使32[2 7]HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_*
* \param reg_data uint32_t
*
*/
void hs_common_serial_8250_bus_write32(hs_common_serial_8250_t *dev,uint8_t address,uint32_t reg_data);
/** \brief 8250 总线32位对齐读(一般由总线上的主设备(如CPU)调用)
*
* \param dev hs_common_serial_8250_t* 8250
* \param address uint8_t 线00x1C使32[2 7]HS_COMMON_SERIAL_8250_REGISTER_ADDRESS_*
* \param reg_data uint32_t*
*
*/
void hs_common_serial_8250_bus_read32(hs_common_serial_8250_t *dev,uint8_t address,uint32_t *reg_data);
/** \brief 8250总线节拍(一般由总线上的主设备(如CPU)调用),在进行读写前调用,可用于更新寄存器状态或者调用中断
*
* \param dev hs_common_serial_8250_t* 8250
*
*/
void hs_common_serial_8250_bus_tick(hs_common_serial_8250_t *dev);
/** \brief 8250获取波特率。
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \return size_t
*
*/
size_t hs_common_serial_8250_config_baud_get(hs_common_serial_8250_t *dev);
/** \brief 8250设置波特率
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \param baud size_t
*
*/
void hs_common_serial_8250_config_baud_set(hs_common_serial_8250_t *dev,size_t baud);
typedef enum
{
HS_COMMON_SERIAL_8250_CONFIG_PARITY_NONE=0, /**< 无校验 */
HS_COMMON_SERIAL_8250_CONFIG_PARITY_EVEN, /**< 偶校验*/
HS_COMMON_SERIAL_8250_CONFIG_PARITY_ODD, /**< 奇校验 */
HS_COMMON_SERIAL_8250_CONFIG_PARITY_MARK, /**< 校验值固定为1 */
HS_COMMON_SERIAL_8250_CONFIG_PARITY_SPACE /**< 校验值固定为0 */
} hs_common_serial_8250_config_parity_t; /**< 校验类型定义 */
/** \brief 8250获取校验位
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \return hs_common_serial_8250_config_parity_t
*
*/
hs_common_serial_8250_config_parity_t hs_common_serial_8250_config_parity_get(hs_common_serial_8250_t *dev);
/** \brief 8250设置校验位
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \param parity hs_common_serial_8250_config_parity_t
*
*/
void hs_common_serial_8250_config_parity_set(hs_common_serial_8250_t *dev,hs_common_serial_8250_config_parity_t parity);
/** \brief 8250获取停止位
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \return size_t 1=12=251.5
*
*/
size_t hs_common_serial_8250_config_stopbits_get(hs_common_serial_8250_t *dev);
/** \brief 8250设置停止位
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \param stopbits size_t 1=12=251.5
*
*/
void hs_common_serial_8250_config_stopbits_set(hs_common_serial_8250_t *dev,size_t stopbits);
/** \brief 8250获取数据位
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \return size_t
*
*/
size_t hs_common_serial_8250_config_databits_get(hs_common_serial_8250_t *dev);
/** \brief 8250设置数据位
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \param databits size_t
*
*/
void hs_common_serial_8250_config_databits_set(hs_common_serial_8250_t *dev,size_t databits);
/** \brief 8250获取是否有数据
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \return bool true时8250,
*
*/
bool hs_common_serial_8250_status_dataready_get(hs_common_serial_8250_t *dev);
/** \brief 8250设置数据
* 线
*
* \param dev hs_common_serial_8250_t* 8250
* \param data uint8_t 使RBR线io操作回调io操作回调中接收数据使
* \return bool
*
*/
bool hs_common_serial_8250_status_dataready_set(hs_common_serial_8250_t *dev,uint8_t data);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_COMMON_SERIAL_8250_H__

View File

@ -14,7 +14,12 @@ extern "C"
{
#endif // __cplusplus
#include "mcs_51_common.h"
#include "mcs_51_disassembly.h"
#include "mcs_51_rom.h"
#include "mcs_51_ram.h"
#include "mcs_51_core.h"
#include "mcs_51_serial.h"
#ifdef __cplusplus
}

View File

@ -0,0 +1,10 @@
/***************************************************************
* Name: mcs_51_common.c
* Purpose: mcs_51_common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-13
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/

View File

@ -0,0 +1,32 @@
/***************************************************************
* Name: mcs_51_common.h
* Purpose: mcs_51_common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-13
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_MCS_51_COMMON_H__
#define __HS_MCS_51_COMMON_H__
#include "stdint.h"
#include "stdlib.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*
* MCS-51,MCS-51便
*
*
*/
#ifndef HS_MCS_51_COMMON_CLK_FREQ
#define HS_MCS_51_COMMON_CLK_FREQ (11059200)
#endif // HS_MCS_51_COMMON_CLK_FREQ
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_MCS_51_COMMON_H__

View File

@ -6,6 +6,8 @@
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "mcs_51_core.h"
#include "mcs_51_disassembly.h"
struct hs_mcs_51_core
{
@ -14,7 +16,7 @@ struct hs_mcs_51_core
struct
{
uint16_t delay_tick:2;//MCS-51具有多周期指令。为保证执行效果对于多周期指令需要延时,最多延时3周期。
uint16_t interrupt_nested:2;//中断嵌套层数0=正常运行
uint16_t interrupt_nested:2;//中断嵌套层数0=正常运行,3=直接进入高优先级中断
uint16_t pc;//PC
uint32_t interrupt_low_priority_scan_table;//中断(低优先级)扫描表位0表示中断0最高支持32个中断
uint32_t interrupt_high_priority_scan_table;//中断(高优先级)扫描表位0表示中断0最高支持32个中断
@ -53,7 +55,14 @@ static void hs_mcs_51_core_scan_interrupt(hs_mcs_51_core_t * core)
{
core->interrupt_high_priority_scan_table &= (~(1ULL<<i));
uint16_t address=3+8*i;
core->interrupt_nested++;//增加中断嵌套RETI指令时自减1
if(core->interrupt_nested==0)
{
core->interrupt_nested=3;
}
else
{
core->interrupt_nested++;//增加中断嵌套RETI指令时自减1
}
{
uint8_t sp=0;
@ -151,139 +160,7 @@ static void hs_mcs_51_core_scan_interrupt(hs_mcs_51_core_t * core)
static size_t hs_mcs_51_core_instruction_length(uint8_t instruction)
{
size_t ret=1;
switch(instruction)
{
case 0x02:
case 0x10:
case 0x12:
case 0x20:
case 0x30:
case 0x43:
case 0x53:
case 0x63:
case 0x75:
case 0x85:
case 0x90:
case 0xB4:
case 0xB5:
case 0xB6:
case 0xB7:
case 0xB8:
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF:
case 0xD5:
{
ret=3;
}
break;
case 0x01:
case 0x05:
case 0x11:
case 0x15:
case 0x21:
case 0x24:
case 0x25:
case 0x31:
case 0x34:
case 0x35:
case 0x40:
case 0x41:
case 0x42:
case 0x44:
case 0x45:
case 0x50:
case 0x51:
case 0x52:
case 0x54:
case 0x55:
case 0x60:
case 0x61:
case 0x62:
case 0x64:
case 0x65:
case 0x70:
case 0x71:
case 0x72:
case 0x74:
case 0x76:
case 0x77:
case 0x78:
case 0x79:
case 0x7A:
case 0x7B:
case 0x7C:
case 0x7D:
case 0x7E:
case 0x7F:
case 0x80:
case 0x81:
case 0x82:
case 0x86:
case 0x87:
case 0x88:
case 0x89:
case 0x8A:
case 0x8B:
case 0x8C:
case 0x8D:
case 0x8E:
case 0x8F:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0xA0:
case 0xA1:
case 0xA2:
case 0xA6:
case 0xA7:
case 0xA8:
case 0xA9:
case 0xAA:
case 0xAB:
case 0xAC:
case 0xAD:
case 0xAE:
case 0xAF:
case 0xB0:
case 0xB1:
case 0xB2:
case 0xC0:
case 0xC1:
case 0xC2:
case 0xC5:
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD8:
case 0xD9:
case 0xDA:
case 0xDB:
case 0xDC:
case 0xDD:
case 0xDE:
case 0xDF:
case 0xE1:
case 0xE5:
case 0xF1:
case 0xF5:
{
ret=2;
}
break;
default:
{
ret=1;
}
break;
}
return ret;
return hs_mcs_51_disassembly_instruction_length(&instruction);
}
static uint8_t hs_mcs_51_sfr_acc_read(hs_mcs_51_core_t * core)
@ -438,7 +315,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
{
uint8_t instruction[HS_MCS_51_INSTRUCTION_MAX_LENGTH]= {0};
core->io(core,HS_MCS_51_IO_READ_ROM,core->pc,instruction,sizeof(instruction),core->usr);
//TODO:执行指令
core->io(core,HS_MCS_51_IO_INSTRUCTION_ENTER,core->pc,instruction,sizeof(instruction),core->usr);
switch(instruction[0])
{
case 0x01://AJMP addr
@ -869,7 +746,14 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
//调整中断嵌套级别
if(core->interrupt_nested!=0)
{
core->interrupt_nested--;
if(core->interrupt_nested==3)
{
core->interrupt_nested=0;
}
else
{
core->interrupt_nested--;
}
}
}
break;
@ -1423,8 +1307,8 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
break;
case 0x85://MOV addr,addr
{
uint8_t addr_dst=instruction[1];
uint8_t addr_src=instruction[2];
uint8_t addr_src=instruction[1];
uint8_t addr_dst=instruction[2];
uint8_t val=0;
core->io(core,HS_MCS_51_IO_READ_RAM_SFR,addr_src,&val,sizeof(val),core->usr);
core->io(core,HS_MCS_51_IO_WRITE_RAM_SFR,addr_dst,&val,sizeof(val),core->usr);
@ -1465,6 +1349,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
core->pc+=2;
core->delay_tick=1;
};
break;
case 0x90://MOV DPTR,#data
{
uint8_t dph=instruction[1];
@ -1512,7 +1397,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
uint8_t Ov= (((acc<0x80 && data>0x7f && result>0x7f) || (acc>0x7f && data<0x80 && result<0x80))?1:0);
psw|=((Cy<<7)|(Ac<<6)|(Ov<<2));
hs_mcs_51_sfr_psw_write(core,psw);
hs_mcs_51_sfr_psw_write(core,result);
hs_mcs_51_sfr_acc_write(core,result);
}
core->pc+=2;
}
@ -1538,7 +1423,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
uint8_t Ov= (((acc<0x80 && data>0x7f && result>0x7f) || (acc>0x7f && data<0x80 && result<0x80))?1:0);
psw|=((Cy<<7)|(Ac<<6)|(Ov<<2));
hs_mcs_51_sfr_psw_write(core,psw);
hs_mcs_51_sfr_psw_write(core,result);
hs_mcs_51_sfr_acc_write(core,result);
}
core->pc+=2;
}
@ -1568,7 +1453,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
uint8_t Ov= (((acc<0x80 && data>0x7f && result>0x7f) || (acc>0x7f && data<0x80 && result<0x80))?1:0);
psw|=((Cy<<7)|(Ac<<6)|(Ov<<2));
hs_mcs_51_sfr_psw_write(core,psw);
hs_mcs_51_sfr_psw_write(core,result);
hs_mcs_51_sfr_acc_write(core,result);
}
core->pc+=1;
}
@ -1602,7 +1487,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
uint8_t Ov= (((acc<0x80 && data>0x7f && result>0x7f) || (acc>0x7f && data<0x80 && result<0x80))?1:0);
psw|=((Cy<<7)|(Ac<<6)|(Ov<<2));
hs_mcs_51_sfr_psw_write(core,psw);
hs_mcs_51_sfr_psw_write(core,result);
hs_mcs_51_sfr_acc_write(core,result);
}
core->pc+=1;
}
@ -2180,6 +2065,7 @@ static void hs_mcs_51_core_exec(hs_mcs_51_core_t * core)
}
break;
}
core->io(core,HS_MCS_51_IO_INSTRUCTION_EXIT,core->pc,instruction,sizeof(instruction),core->usr);
}
}
@ -2189,9 +2075,17 @@ void hs_mcs_51_core_tick(hs_mcs_51_core_t * core,size_t cycles)
{
while((cycles--)!=0)
{
if(core->io==NULL)
{
//io无效不工作
continue;
}
core->io(core,HS_MCS_51_IO_TICK_ENTER,core->pc,(uint8_t *)&cycles,sizeof(cycles),core->usr);
if(core->delay_tick!=0)
{
core->delay_tick--;
core->io(core,HS_MCS_51_IO_TICK_EXIT,core->pc,(uint8_t *)&cycles,sizeof(cycles),core->usr);
continue;
}
@ -2199,6 +2093,7 @@ void hs_mcs_51_core_tick(hs_mcs_51_core_t * core,size_t cycles)
hs_mcs_51_core_exec(core);
core->io(core,HS_MCS_51_IO_TICK_EXIT,core->pc,(uint8_t *)&cycles,sizeof(cycles),core->usr);
}
}
}

View File

@ -27,6 +27,14 @@ typedef struct hs_mcs_51_core hs_mcs_51_core_t;
*/
size_t hs_mcs_51_core_size(void);
#ifndef HS_MCS_51_CORE_SIZE
/** \brief hs_mcs_51_core_t结构体大小,一般用于静态分配,注意:可能大于hs_mcs_51_core_size()返回的值。
*
*
*/
#define HS_MCS_51_CORE_SIZE() (sizeof(uintptr_t)*2+sizeof(uint32_t)*4)
#endif // HS_MCS_51_CORE_SIZE
#ifndef HS_MCS_51_INSTRUCTION_MAX_LENGTH
#define HS_MCS_51_INSTRUCTION_MAX_LENGTH 3 /**< 指令最长字节数,默认每次读取此长度的指令 */
#endif // HS_MCS_51_INSTRUCTION_MAX_SIZE
@ -43,7 +51,11 @@ typedef enum
HS_MCS_51_IO_WRITE_EXTERNAL_RAM, //写入外部RAM(最高64KB)
HS_MCS_51_IO_BREAKPOINT, //由MCS-51的保留指令0xA5触发可用于自定义的指令(默认这是一条单周期单字节指令)通过地址传入PC的值下一条指令地址通过数据传出相对跳转的地址(有符号数)。
HS_MCS_51_IO_INTERRUPT_ENTER, //中断进入,地址为中断号,数据为运行级别
HS_MCS_51_IO_INTERRUPT_EXIT //中断退出,数据为运行级别,通常用于自动清除某些标志
HS_MCS_51_IO_INTERRUPT_EXIT, //中断退出,地址为中断号,数据为运行级别,通常用于自动清除某些标志
HS_MCS_51_IO_INSTRUCTION_ENTER, //指令进入,开始执行指令时调用。通常用于调试或者用户处理指令。地址为当前PC值,数据为已经执行的指令。
HS_MCS_51_IO_INSTRUCTION_EXIT, //指令退出,结束执行指令时调用。通常用于调试或者用户处理指令。地址为当前PC值(可能已被指令修改),数据为已经执行的指令。
HS_MCS_51_IO_TICK_ENTER, //节拍进入,时钟节拍开始时调用。地址为当前PC值,数据为剩余节拍数(类型为size_t)。
HS_MCS_51_IO_TICK_EXIT //节拍退出,时钟节拍结束时调用。地址为当前PC值,数据为剩余节拍数(类型为size_t)。
} hs_mcs_51_io_opt_t;
/** \brief MCS-51 IO操作
@ -131,7 +143,7 @@ typedef enum
/** \brief MCS-51内核设置中断到中断扫描表将在下一个周期执行中断执行后自动清除一般由外设调用注意此函数不是线程安全的必要时需要加锁。
*
* \param core hs_mcs_51_core_t* MCS-51
* \param number hs_mcs_51_interrupt_number_t
* \param number hs_mcs_51_interrupt_number_t ,使
* \param is_high_priority bool
*
*/
@ -140,7 +152,7 @@ void hs_mcs_51_core_interrupt_set(hs_mcs_51_core_t * core,hs_mcs_51_interrupt_nu
/** \brief MCS-51内核获取中断嵌套层数
*
* \param core hs_mcs_51_core_t*
* \return int ,-1
* \return int ,-1,0123
*
*/
int hs_mcs_51_core_interrupt_nested_get(hs_mcs_51_core_t * core);

View File

@ -0,0 +1,329 @@
/***************************************************************
* Name: mcs_51_disassembly.c
* Purpose: mcs_51_disassembly接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-14
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "mcs_51_disassembly.h"
const hs_mcs_51_disassembly_instruction_t hs_mcs_51_disassembly_instruction_table[]=
{
{ 0x00, 0xff, ' ', 1, "NOP",false},
{ 0x01, 0xff, 'A', 2, "AJMP %A",false},
{ 0x02, 0xff, 'L', 3, "LJMP %l",false},
{ 0x03, 0xff, ' ', 1, "RR A",false},
{ 0x04, 0xff, ' ', 1, "INC A",false},
{ 0x05, 0xff, ' ', 2, "INC %a",false},
{ 0x06, 0xff, ' ', 1, "INC @R0",false},
{ 0x07, 0xff, ' ', 1, "INC @R1",false},
{ 0x08, 0xff, ' ', 1, "INC R0",false},
{ 0x09, 0xff, ' ', 1, "INC R1",false},
{ 0x0a, 0xff, ' ', 1, "INC R2",false},
{ 0x0b, 0xff, ' ', 1, "INC R3",false},
{ 0x0c, 0xff, ' ', 1, "INC R4",false},
{ 0x0d, 0xff, ' ', 1, "INC R5",false},
{ 0x0e, 0xff, ' ', 1, "INC R6",false},
{ 0x0f, 0xff, ' ', 1, "INC R7",false},
{ 0x10, 0xff, 'R', 3, "JBC %b,%R",false},
{ 0x11, 0xff, 'a', 2, "ACALL %A",false},
{ 0x12, 0xff, 'l', 3, "LCALL %l", true},
{ 0x13, 0xff, ' ', 1, "RRC A",false},
{ 0x14, 0xff, ' ', 1, "DEC A",false},
{ 0x15, 0xff, ' ', 2, "DEC %a",false},
{ 0x16, 0xff, ' ', 1, "DEC @R0",false},
{ 0x17, 0xff, ' ', 1, "DEC @R1",false},
{ 0x18, 0xff, ' ', 1, "DEC R0",false},
{ 0x19, 0xff, ' ', 1, "DEC R1",false},
{ 0x1a, 0xff, ' ', 1, "DEC R2",false},
{ 0x1b, 0xff, ' ', 1, "DEC R3",false},
{ 0x1c, 0xff, ' ', 1, "DEC R4",false},
{ 0x1d, 0xff, ' ', 1, "DEC R5",false},
{ 0x1e, 0xff, ' ', 1, "DEC R6",false},
{ 0x1f, 0xff, ' ', 1, "DEC R7",false},
{ 0x20, 0xff, 'R', 3, "JB %b,%R",false},
{ 0x21, 0xff, 'A', 2, "AJMP %A",false},
{ 0x22, 0xff, '_', 1, "RET",false},
{ 0x23, 0xff, ' ', 1, "RL A",false},
{ 0x24, 0xff, ' ', 2, "ADD A,#%d",false},
{ 0x25, 0xff, ' ', 2, "ADD A,%a",false},
{ 0x26, 0xff, ' ', 1, "ADD A,@R0",false},
{ 0x27, 0xff, ' ', 1, "ADD A,@R1",false},
{ 0x28, 0xff, ' ', 1, "ADD A,R0",false},
{ 0x29, 0xff, ' ', 1, "ADD A,R1",false},
{ 0x2a, 0xff, ' ', 1, "ADD A,R2",false},
{ 0x2b, 0xff, ' ', 1, "ADD A,R3",false},
{ 0x2c, 0xff, ' ', 1, "ADD A,R4",false},
{ 0x2d, 0xff, ' ', 1, "ADD A,R5",false},
{ 0x2e, 0xff, ' ', 1, "ADD A,R6",false},
{ 0x2f, 0xff, ' ', 1, "ADD A,R7",false},
{ 0x30, 0xff, 'R', 3, "JNB %b,%R",false},
{ 0x31, 0xff, 'a', 2, "ACALL %A", true},
{ 0x32, 0xff, '_', 1, "RETI",false},
{ 0x33, 0xff, ' ', 1, "RLC A",false},
{ 0x34, 0xff, ' ', 2, "ADDC A,#%d",false},
{ 0x35, 0xff, ' ', 2, "ADDC A,%a",false},
{ 0x36, 0xff, ' ', 1, "ADDC A,@R0",false},
{ 0x37, 0xff, ' ', 1, "ADDC A,@R1",false},
{ 0x38, 0xff, ' ', 1, "ADDC A,R0",false},
{ 0x39, 0xff, ' ', 1, "ADDC A,R1",false},
{ 0x3a, 0xff, ' ', 1, "ADDC A,R2",false},
{ 0x3b, 0xff, ' ', 1, "ADDC A,R3",false},
{ 0x3c, 0xff, ' ', 1, "ADDC A,R4",false},
{ 0x3d, 0xff, ' ', 1, "ADDC A,R5",false},
{ 0x3e, 0xff, ' ', 1, "ADDC A,R6",false},
{ 0x3f, 0xff, ' ', 1, "ADDC A,R7",false},
{ 0x40, 0xff, 'r', 2, "JC %r",false},
{ 0x41, 0xff, 'A', 2, "AJMP %A",false},
{ 0x42, 0xff, ' ', 2, "ORL %a,A",false},
{ 0x43, 0xff, ' ', 3, "ORL %a,#%D",false},
{ 0x44, 0xff, ' ', 2, "ORL A,#%d",false},
{ 0x45, 0xff, ' ', 2, "ORL A,%a",false},
{ 0x46, 0xff, ' ', 1, "ORL A,@R0",false},
{ 0x47, 0xff, ' ', 1, "ORL A,@R1",false},
{ 0x48, 0xff, ' ', 1, "ORL A,R0",false},
{ 0x49, 0xff, ' ', 1, "ORL A,R1",false},
{ 0x4a, 0xff, ' ', 1, "ORL A,R2",false},
{ 0x4b, 0xff, ' ', 1, "ORL A,R3",false},
{ 0x4c, 0xff, ' ', 1, "ORL A,R4",false},
{ 0x4d, 0xff, ' ', 1, "ORL A,R5",false},
{ 0x4e, 0xff, ' ', 1, "ORL A,R6",false},
{ 0x4f, 0xff, ' ', 1, "ORL A,R7",false},
{ 0x50, 0xff, 'r', 2, "JNC %r",false},
{ 0x51, 0xff, 'a', 2, "ACALL %A", true},
{ 0x52, 0xff, ' ', 2, "ANL %a,A",false},
{ 0x53, 0xff, ' ', 3, "ANL %a,#%D",false},
{ 0x54, 0xff, ' ', 2, "ANL A,#%d",false},
{ 0x55, 0xff, ' ', 2, "ANL A,%a",false},
{ 0x56, 0xff, ' ', 1, "ANL A,@R0",false},
{ 0x57, 0xff, ' ', 1, "ANL A,@R1",false},
{ 0x58, 0xff, ' ', 1, "ANL A,R0",false},
{ 0x59, 0xff, ' ', 1, "ANL A,R1",false},
{ 0x5a, 0xff, ' ', 1, "ANL A,R2",false},
{ 0x5b, 0xff, ' ', 1, "ANL A,R3",false},
{ 0x5c, 0xff, ' ', 1, "ANL A,R4",false},
{ 0x5d, 0xff, ' ', 1, "ANL A,R5",false},
{ 0x5e, 0xff, ' ', 1, "ANL A,R6",false},
{ 0x5f, 0xff, ' ', 1, "ANL A,R7",false},
{ 0x60, 0xff, 'r', 2, "JZ %r",false},
{ 0x61, 0xff, 'A', 2, "AJMP %A",false},
{ 0x62, 0xff, ' ', 2, "XRL %a,A",false},
{ 0x63, 0xff, ' ', 3, "XRL %a,#%D",false},
{ 0x64, 0xff, ' ', 2, "XRL A,#%d",false},
{ 0x65, 0xff, ' ', 2, "XRL A,%a",false},
{ 0x66, 0xff, ' ', 1, "XRL A,@R0",false},
{ 0x67, 0xff, ' ', 1, "XRL A,@R1",false},
{ 0x68, 0xff, ' ', 1, "XRL A,R0",false},
{ 0x69, 0xff, ' ', 1, "XRL A,R1",false},
{ 0x6a, 0xff, ' ', 1, "XRL A,R2",false},
{ 0x6b, 0xff, ' ', 1, "XRL A,R3",false},
{ 0x6c, 0xff, ' ', 1, "XRL A,R4",false},
{ 0x6d, 0xff, ' ', 1, "XRL A,R5",false},
{ 0x6e, 0xff, ' ', 1, "XRL A,R6",false},
{ 0x6f, 0xff, ' ', 1, "XRL A,R7",false},
{ 0x70, 0xff, 'r', 2, "JNZ %r",false},
{ 0x71, 0xff, 'a', 2, "ACALL %A", true},
{ 0x72, 0xff, ' ', 2, "ORL C,%b",false},
{ 0x73, 0xff, '_', 1, "JMP @A+DPTR",false},
{ 0x74, 0xff, ' ', 2, "MOV A,#%d",false},
{ 0x75, 0xff, ' ', 3, "MOV %a,#%D",false},
{ 0x76, 0xff, ' ', 2, "MOV @R0,#%d",false},
{ 0x77, 0xff, ' ', 2, "MOV @R1,#%d",false},
{ 0x78, 0xff, ' ', 2, "MOV R0,#%d",false},
{ 0x79, 0xff, ' ', 2, "MOV R1,#%d",false},
{ 0x7a, 0xff, ' ', 2, "MOV R2,#%d",false},
{ 0x7b, 0xff, ' ', 2, "MOV R3,#%d",false},
{ 0x7c, 0xff, ' ', 2, "MOV R4,#%d",false},
{ 0x7d, 0xff, ' ', 2, "MOV R5,#%d",false},
{ 0x7e, 0xff, ' ', 2, "MOV R6,#%d",false},
{ 0x7f, 0xff, ' ', 2, "MOV R7,#%d",false},
{ 0x80, 0xff, 's', 2, "SJMP %r",false},
{ 0x81, 0xff, 'A', 2, "AJMP %A",false},
{ 0x82, 0xff, ' ', 2, "ANL C,%b",false},
{ 0x83, 0xff, ' ', 1, "MOVC A,@A+PC",false},
{ 0x84, 0xff, ' ', 1, "DIV AB",false},
{ 0x85, 0xff, ' ', 3, "MOV %8,%a",false},
{ 0x86, 0xff, ' ', 2, "MOV %a,@R0",false},
{ 0x87, 0xff, ' ', 2, "MOV %a,@R1",false},
{ 0x88, 0xff, ' ', 2, "MOV %a,R0",false},
{ 0x89, 0xff, ' ', 2, "MOV %a,R1",false},
{ 0x8a, 0xff, ' ', 2, "MOV %a,R2",false},
{ 0x8b, 0xff, ' ', 2, "MOV %a,R3",false},
{ 0x8c, 0xff, ' ', 2, "MOV %a,R4",false},
{ 0x8d, 0xff, ' ', 2, "MOV %a,R5",false},
{ 0x8e, 0xff, ' ', 2, "MOV %a,R6",false},
{ 0x8f, 0xff, ' ', 2, "MOV %a,R7",false},
{ 0x90, 0xff, ' ', 3, "MOV DPTR,#%6",false},
{ 0x91, 0xff, 'a', 2, "ACALL %A", true},
{ 0x92, 0xff, ' ', 2, "MOV %b,C",false},
{ 0x93, 0xff, ' ', 1, "MOVC A,@A+DPTR",false},
{ 0x94, 0xff, ' ', 2, "SUBB A,#%d",false},
{ 0x95, 0xff, ' ', 2, "SUBB A,%a",false},
{ 0x96, 0xff, ' ', 1, "SUBB A,@R0",false},
{ 0x97, 0xff, ' ', 1, "SUBB A,@R1",false},
{ 0x98, 0xff, ' ', 1, "SUBB A,R0",false},
{ 0x99, 0xff, ' ', 1, "SUBB A,R1",false},
{ 0x9a, 0xff, ' ', 1, "SUBB A,R2",false},
{ 0x9b, 0xff, ' ', 1, "SUBB A,R3",false},
{ 0x9c, 0xff, ' ', 1, "SUBB A,R4",false},
{ 0x9d, 0xff, ' ', 1, "SUBB A,R5",false},
{ 0x9e, 0xff, ' ', 1, "SUBB A,R6",false},
{ 0x9f, 0xff, ' ', 1, "SUBB A,R7",false},
{ 0xa0, 0xff, ' ', 2, "ORL C,/%b",false},
{ 0xa1, 0xff, 'A', 2, "AJMP %A",false},
{ 0xa2, 0xff, ' ', 2, "MOV C,%b",false},
{ 0xa3, 0xff, ' ', 1, "INC DPTR",false},
{ 0xa4, 0xff, ' ', 1, "MUL AB",false},
{ 0xa5, 0xff, '_', 1, "-",false},
{ 0xa6, 0xff, ' ', 2, "MOV @R0,%a",false},
{ 0xa7, 0xff, ' ', 2, "MOV @R1,%a",false},
{ 0xa8, 0xff, ' ', 2, "MOV R0,%a",false},
{ 0xa9, 0xff, ' ', 2, "MOV R1,%a",false},
{ 0xaa, 0xff, ' ', 2, "MOV R2,%a",false},
{ 0xab, 0xff, ' ', 2, "MOV R3,%a",false},
{ 0xac, 0xff, ' ', 2, "MOV R4,%a",false},
{ 0xad, 0xff, ' ', 2, "MOV R5,%a",false},
{ 0xae, 0xff, ' ', 2, "MOV R6,%a",false},
{ 0xaf, 0xff, ' ', 2, "MOV R7,%a",false},
{ 0xb0, 0xff, ' ', 2, "ANL C,/%b",false},
{ 0xb1, 0xff, 'a', 2, "ACALL %A", true},
{ 0xb2, 0xff, ' ', 2, "CPL %b",false},
{ 0xb3, 0xff, ' ', 1, "CPL C",false},
{ 0xb4, 0xff, 'R', 3, "CJNE A,#%d,%R",false},
{ 0xb5, 0xff, 'R', 3, "CJNE A,%a,%R",false},
{ 0xb6, 0xff, 'R', 3, "CJNE @R0,#%d,%R",false},
{ 0xb7, 0xff, 'R', 3, "CJNE @R1,#%d,%R",false},
{ 0xb8, 0xff, 'R', 3, "CJNE R0,#%d,%R",false},
{ 0xb9, 0xff, 'R', 3, "CJNE R1,#%d,%R",false},
{ 0xba, 0xff, 'R', 3, "CJNE R2,#%d,%R",false},
{ 0xbb, 0xff, 'R', 3, "CJNE R3,#%d,%R",false},
{ 0xbc, 0xff, 'R', 3, "CJNE R4,#%d,%R",false},
{ 0xbd, 0xff, 'R', 3, "CJNE R5,#%d,%R",false},
{ 0xbe, 0xff, 'R', 3, "CJNE R6,#%d,%R",false},
{ 0xbf, 0xff, 'R', 3, "CJNE R7,#%d,%R",false},
{ 0xc0, 0xff, ' ', 2, "PUSH %a",false},
{ 0xc1, 0xff, 'A', 2, "AJMP %A",false},
{ 0xc2, 0xff, ' ', 2, "CLR %b",false},
{ 0xc3, 0xff, ' ', 1, "CLR C",false},
{ 0xc4, 0xff, ' ', 1, "SWAP A",false},
{ 0xc5, 0xff, ' ', 2, "XCH A,%a",false},
{ 0xc6, 0xff, ' ', 1, "XCH A,@R0",false},
{ 0xc7, 0xff, ' ', 1, "XCH A,@R1",false},
{ 0xc8, 0xff, ' ', 1, "XCH A,R0",false},
{ 0xc9, 0xff, ' ', 1, "XCH A,R1",false},
{ 0xca, 0xff, ' ', 1, "XCH A,R2",false},
{ 0xcb, 0xff, ' ', 1, "XCH A,R3",false},
{ 0xcc, 0xff, ' ', 1, "XCH A,R4",false},
{ 0xcd, 0xff, ' ', 1, "XCH A,R5",false},
{ 0xce, 0xff, ' ', 1, "XCH A,R6",false},
{ 0xcf, 0xff, ' ', 1, "XCH A,R7",false},
{ 0xd0, 0xff, ' ', 2, "POP %a",false},
{ 0xd1, 0xff, 'a', 2, "ACALL %A", true},
{ 0xd2, 0xff, ' ', 2, "SETB %b",false},
{ 0xd3, 0xff, ' ', 1, "SETB C",false},
{ 0xd4, 0xff, ' ', 1, "DA A",false},
{ 0xd5, 0xff, 'R', 3, "DJNZ %a,%R",false},
{ 0xd6, 0xff, ' ', 1, "XCHD A,@R0",false},
{ 0xd7, 0xff, ' ', 1, "XCHD A,@R1",false},
{ 0xd8, 0xff, 'r', 2, "DJNZ R0,%r",false},
{ 0xd9, 0xff, 'r', 2, "DJNZ R1,%r",false},
{ 0xda, 0xff, 'r', 2, "DJNZ R2,%r",false},
{ 0xdb, 0xff, 'r', 2, "DJNZ R3,%r",false},
{ 0xdc, 0xff, 'r', 2, "DJNZ R4,%r",false},
{ 0xdd, 0xff, 'r', 2, "DJNZ R5,%r",false},
{ 0xde, 0xff, 'r', 2, "DJNZ R6,%r",false},
{ 0xdf, 0xff, 'r', 2, "DJNZ R7,%r",false},
{ 0xe0, 0xff, ' ', 1, "MOVX A,@DPTR",false},
{ 0xe1, 0xff, 'A', 2, "AJMP %A",false},
{ 0xe2, 0xff, ' ', 1, "MOVX A,@R0",false},
{ 0xe3, 0xff, ' ', 1, "MOVX A,@R1",false},
{ 0xe4, 0xff, ' ', 1, "CLR A",false},
{ 0xe5, 0xff, ' ', 2, "MOV A,%a",false},
{ 0xe6, 0xff, ' ', 1, "MOV A,@R0",false},
{ 0xe7, 0xff, ' ', 1, "MOV A,@R1",false},
{ 0xe8, 0xff, ' ', 1, "MOV A,R0",false},
{ 0xe9, 0xff, ' ', 1, "MOV A,R1",false},
{ 0xea, 0xff, ' ', 1, "MOV A,R2",false},
{ 0xeb, 0xff, ' ', 1, "MOV A,R3",false},
{ 0xec, 0xff, ' ', 1, "MOV A,R4",false},
{ 0xed, 0xff, ' ', 1, "MOV A,R5",false},
{ 0xee, 0xff, ' ', 1, "MOV A,R6",false},
{ 0xef, 0xff, ' ', 1, "MOV A,R7",false},
{ 0xf0, 0xff, ' ', 1, "MOVX @DPTR,A",false},
{ 0xf1, 0xff, 'a', 2, "ACALL %A", true},
{ 0xf2, 0xff, ' ', 1, "MOVX @R0,A",false},
{ 0xf3, 0xff, ' ', 1, "MOVX @R1,A",false},
{ 0xf4, 0xff, ' ', 1, "CPL A",false},
{ 0xf5, 0xff, ' ', 2, "MOV %a,A",false},
{ 0xf6, 0xff, ' ', 1, "MOV @R0,A",false},
{ 0xf7, 0xff, ' ', 1, "MOV @R1,A",false},
{ 0xf8, 0xff, ' ', 1, "MOV R0,A",false},
{ 0xf9, 0xff, ' ', 1, "MOV R1,A",false},
{ 0xfa, 0xff, ' ', 1, "MOV R2,A",false},
{ 0xfb, 0xff, ' ', 1, "MOV R3,A",false},
{ 0xfc, 0xff, ' ', 1, "MOV R4,A",false},
{ 0xfd, 0xff, ' ', 1, "MOV R5,A",false},
{ 0xfe, 0xff, ' ', 1, "MOV R6,A",false},
{ 0xff, 0xff, ' ', 1, "MOV R7,A",false},
{ 0, 0, 0, 0, NULL,false }
};
const hs_mcs_51_disassembly_instruction_t *hs_mcs_51_disassembly_instruction_table_get(const uint8_t *instruction)
{
if(instruction!=NULL)
{
return &hs_mcs_51_disassembly_instruction_table[(*instruction)];
}
return NULL;
}
size_t hs_mcs_51_disassembly_instruction_length(const uint8_t *instruction)
{
if(instruction!=NULL)
{
return hs_mcs_51_disassembly_instruction_table[(*instruction)].length;
}
return 0;
}
size_t hs_mcs_51_disassembly_code_instruction_count(const uint8_t *code,size_t length)
{
size_t ret=0;
if(code!=NULL && length > 0)
{
size_t pc=0;
while(pc<length)
{
ret++;
pc+=hs_mcs_51_disassembly_instruction_length(&code[pc]);
}
}
return ret;
}
size_t hs_mcs_51_disassembly_code_instruction_type_count(const uint8_t *code,size_t length)
{
size_t ret=0;
if(code!=NULL && length > 0)
{
size_t pc=0;
uint8_t mask[32]= {0};
while(pc<length)
{
{
mask[code[pc]/8]|=(1ULL<<(code[pc]%8));
}
pc+=hs_mcs_51_disassembly_instruction_length(&code[pc]);
}
for(size_t i=0; i<256; i++)
{
if((mask[i/8] & (1ULL<<(i%8)))!=0)
{
ret++;
}
}
}
return ret;
}

View File

@ -0,0 +1,78 @@
/***************************************************************
* Name: mcs_51_disassembly.h
* Purpose: mcs_51_disassembly接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-14
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_MCS_51_DISASSEMBLY_H__
#define __HS_MCS_51_DISASSEMBLY_H__
#include "stdint.h"
#include "stdlib.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C"
{
#endif
struct hs_mcs_51_disassembly_instruction;
typedef struct hs_mcs_51_disassembly_instruction hs_mcs_51_disassembly_instruction_t;
struct hs_mcs_51_disassembly_instruction
{
uint8_t code; /**<指令代码通常为指令第1字节 */
uint8_t mask; /**<掩码通常使用mask=0表示反汇编表结束 */
int8_t branch; /**<分支类型 */
uint8_t length; /**<指令长度 */
const char *mnemonic; /**<汇编助记符 */
bool is_call; /**<是否为调用 */
};
/** \brief 反汇编表共257项前256项可使用MCS-51指令第一字节引索
*
*
*/
extern const hs_mcs_51_disassembly_instruction_t hs_mcs_51_disassembly_instruction_table[];
/** \brief 从反汇编表中读取指令
*
* \param instruction const uint8_t*
* \return const hs_mcs_51_disassembly_instruction_t*
*
*/
const hs_mcs_51_disassembly_instruction_t *hs_mcs_51_disassembly_instruction_table_get(const uint8_t *instruction);
/** \brief 从反汇编表中读取指令长度
*
* \param instruction uint8_t*
* \return size_t 0
*
*/
size_t hs_mcs_51_disassembly_instruction_length(const uint8_t *instruction);
/** \brief 获取程序代码中的指令条数
*
* \param code uint8_t*
* \param length size_t
* \return size_t
*
*/
size_t hs_mcs_51_disassembly_code_instruction_count(const uint8_t *code,size_t length);
/** \brief 获取程序代码中的指令类型数量
*
* \param code uint8_t*
* \param length size_t
* \return size_t
*
*/
size_t hs_mcs_51_disassembly_code_instruction_type_count(const uint8_t *code,size_t length);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_MCS_51_DISASSEMBLY_H__

View File

@ -0,0 +1,180 @@
/***************************************************************
* Name: mcs_51_ram.c
* Purpose: mcs_51_ram接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-15
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "mcs_51_ram.h"
void hs_mcs_51_ram_model_tiny_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_tiny_t* ram)
{
if(ram!=NULL)
{
switch(opt)
{
case HS_MCS_51_IO_RESET: //IO复位
{
//清空内存内容
memset(ram->ram,0,sizeof(ram->ram));
};
break;
case HS_MCS_51_IO_READ_RAM_SFR: //读取内部低128字节RAM与SFR
{
memcpy(data,&ram->ram[address],length);
}
break;
case HS_MCS_51_IO_WRITE_RAM_SFR: //写入内部低128字节RAM与SFR
{
memcpy(&ram->ram[address],data,length);
}
break;
case HS_MCS_51_IO_READ_HIGH_RAM:
{
if(address < 128)
{
memcpy(data,&ram->ram[address],length);
}
}
break;
case HS_MCS_51_IO_WRITE_HIGH_RAM:
{
if(address < 128)
{
memcpy(&ram->ram[address],data,length);
}
}
break;
default:
{
}
break;
}
}
}
void hs_mcs_51_ram_model_small_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_small_t* ram)
{
if(ram!=NULL)
{
hs_mcs_51_ram_model_tiny_bus_io(core,opt,address,data,length,usr,&ram->base);
switch(opt)
{
case HS_MCS_51_IO_RESET: //IO复位
{
//清空内存内容
memset(ram->ram,0,sizeof(ram->ram));
};
break;
case HS_MCS_51_IO_READ_HIGH_RAM:
{
if(address >= 128)
{
memcpy(data,&ram->ram[address-128],length);
}
}
break;
case HS_MCS_51_IO_WRITE_HIGH_RAM:
{
if(address >= 128)
{
memcpy(&ram->ram[address-128],data,length);
}
}
break;
default:
{
}
break;
}
}
}
void hs_mcs_51_ram_model_medium_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_medium_t* ram)
{
if(ram!=NULL)
{
hs_mcs_51_ram_model_small_bus_io(core,opt,address,data,length,usr,&ram->base);
switch(opt)
{
case HS_MCS_51_IO_RESET: //IO复位
{
//清空内存内容
memset(ram->xram,0,sizeof(ram->xram));
};
break;
case HS_MCS_51_IO_READ_EXTERNAL_RAM:
{
if(address < 256)
{
memcpy(data,&ram->xram[address],length);
}
}
break;
case HS_MCS_51_IO_WRITE_EXTERNAL_RAM:
{
if(address < 256)
{
memcpy(&ram->xram[address],data,length);
}
}
break;
default:
{
}
break;
}
}
}
void hs_mcs_51_ram_model_large_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_large_t* ram)
{
if(ram!=NULL)
{
hs_mcs_51_ram_model_medium_bus_io(core,opt,address,data,length,usr,&ram->base);
switch(opt)
{
case HS_MCS_51_IO_RESET: //IO复位
{
//清空内存内容
memset(ram->xram,0,sizeof(ram->xram));
};
break;
case HS_MCS_51_IO_READ_EXTERNAL_RAM:
{
if(address >= 256)
{
memcpy(data,&ram->xram[address-256],length);
}
}
break;
case HS_MCS_51_IO_WRITE_EXTERNAL_RAM:
{
if(address >= 256)
{
memcpy(&ram->xram[address-256],data,length);
}
}
break;
default:
{
}
break;
}
}
}
void hs_mcs_51_ram_model_huge_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_huge_t* ram)
{
if(ram!=NULL)
{
hs_mcs_51_ram_model_large_bus_io(core,opt,address,data,length,usr,&ram->base);
}
}

View File

@ -0,0 +1,153 @@
/***************************************************************
* Name: mcs_51_ram.h
* Purpose: mcs_51_ram接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-15
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_MCS_51_RAM_H__
#define __HS_MCS_51_RAM_H__
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "mcs_51_core.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** \brief 极简模型,注意:只能选取一种作为最终使用的模型
*
*
*/
struct hs_mcs_51_ram_model_tiny;
typedef struct hs_mcs_51_ram_model_tiny hs_mcs_51_ram_model_tiny_t;
struct hs_mcs_51_ram_model_tiny
{
uint8_t ram[256]; //内部128字节+SFR
};
/** \brief MCS-51 RAM总线IO操作(一般由总线上的主设备(如CPU)调用),注意:需要在外设操作前调用
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param ram hs_mcs_51_ram_model_tiny_t* MCS-51 RAM指针
*
*/
void hs_mcs_51_ram_model_tiny_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_tiny_t* ram);
/** \brief small模型注意只能选取一种作为最终使用的模型
*
*
*/
struct hs_mcs_51_ram_model_small;
typedef struct hs_mcs_51_ram_model_small hs_mcs_51_ram_model_small_t;
struct hs_mcs_51_ram_model_small
{
hs_mcs_51_ram_model_tiny_t base;
uint8_t ram[128]; //内部RAM高128字节
};
/** \brief MCS-51 RAM总线IO操作(一般由总线上的主设备(如CPU)调用),注意:需要在外设操作前调用
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param ram hs_mcs_51_ram_model_small_t* MCS-51 RAM指针
*
*/
void hs_mcs_51_ram_model_small_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_small_t* ram);
/** \brief medium模型注意只能选取一种作为最终使用的模型
*
*
*/
struct hs_mcs_51_ram_model_medium;
typedef struct hs_mcs_51_ram_model_medium hs_mcs_51_ram_model_medium_t;
struct hs_mcs_51_ram_model_medium
{
hs_mcs_51_ram_model_small_t base;
uint8_t xram[256]; //外部低256字节
};
/** \brief MCS-51 RAM总线IO操作(一般由总线上的主设备(如CPU)调用),注意:需要在外设操作前调用
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param ram hs_mcs_51_ram_model_medium_t* MCS-51 RAM指针
*
*/
void hs_mcs_51_ram_model_medium_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_medium_t* ram);
/** \brief large模型注意只能选取一种作为最终使用的模型
*
*
*/
struct hs_mcs_51_ram_model_large;
typedef struct hs_mcs_51_ram_model_large hs_mcs_51_ram_model_large_t;
struct hs_mcs_51_ram_model_large
{
hs_mcs_51_ram_model_medium_t base;
uint8_t xram[64*1024-256]; //外部64K字节(除开低256字节)
};
/** \brief MCS-51 RAM总线IO操作(一般由总线上的主设备(如CPU)调用),注意:需要在外设操作前调用
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param ram hs_mcs_51_ram_model_large_t* MCS-51 RAM指针
*
*/
void hs_mcs_51_ram_model_large_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_large_t* ram);
/** \brief huge模型注意只能选取一种作为最终使用的模型
*
*
*/
struct hs_mcs_51_ram_model_huge;
typedef struct hs_mcs_51_ram_model_huge hs_mcs_51_ram_model_huge_t;
struct hs_mcs_51_ram_model_huge
{
hs_mcs_51_ram_model_large_t base;
};
/** \brief MCS-51 RAM总线IO操作(一般由总线上的主设备(如CPU)调用),注意:需要在外设操作前调用
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param ram hs_mcs_51_ram_model_huge_t* MCS-51 RAM指针
*
*/
void hs_mcs_51_ram_model_huge_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_ram_model_huge_t* ram);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_MCS_51_RAM_H__

View File

@ -0,0 +1,189 @@
/***************************************************************
* Name: mcs_51_rom.c
* Purpose: mcs_51_rom接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-13
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "mcs_51_rom.h"
void hs_mcs_51_rom_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_rom_t *rom)
{
if(opt==HS_MCS_51_IO_RESET)
{
if(rom!=NULL)
{
if((rom->code!=NULL)&& (rom->len > (64*1024)))
{
//超过2个Bank
uint8_t psbank_addr=HS_MCS_51_ROM_PSBANK_C8051F120_SFR_ADDRESS;
if(rom->psbank_addr >= 0x80)
{
psbank_addr=rom->psbank_addr;
}
uint8_t psbank_val=0x11;
if(psbank_addr==HS_MCS_51_ROM_PSBANK_CC2530_SFR_ADDRESS)
{
//对于CC2530而言PSBANK为FMAP寄存器不区分常数与指令因此常数访问同指令访问
psbank_val=0x01;
}
//常数Bank与指令Bank选择1
hs_mcs_51_sfr_write(core,(hs_mcs_51_sfr_addr_t)psbank_addr, psbank_val);
}
}
}
if(opt==HS_MCS_51_IO_READ_ROM)
{
if(rom!=NULL)
{
//使用size_t用作临时地址
size_t address_size_t=address;
if((rom->code!=NULL))
{
//使用size_t用作地址,16位地址在地址映射后可能溢出
size_t address=address_size_t;
//进行地址映射
if((rom->code!=NULL)&& (rom->len > (64*1024)))
{
//超过2个Bank(未超过64KB不启用PSBANK)
uint8_t psbank_addr=HS_MCS_51_ROM_PSBANK_C8051F120_SFR_ADDRESS;
if(rom->psbank_addr >= 0x80)
{
psbank_addr=rom->psbank_addr;
}
uint8_t psbank_val=0x11;
hs_mcs_51_sfr_read(core,(hs_mcs_51_sfr_addr_t)psbank_addr,&psbank_val);
if(address >= 0x8000)
{
//访问高地址需要进行Bank选择,低地址永远访问Bank0
address-=0x8000;
if(psbank_addr==HS_MCS_51_ROM_PSBANK_CC2530_SFR_ADDRESS)
{
//对于CC2530而言PSBANK为FMAP寄存器不区分常数与指令因此常数访问同指令访问
psbank_val&=0x0F;
psbank_val+=(psbank_val<<4);
}
if(length == 1)
{
//常数访问
address+=(((psbank_val&0xF0)>>4)*0x8000);
}
else
{
//指令访问
address+=((psbank_val&0xF)*0x8000);
}
}
}
//读取数据
if((rom->len >= (address+length)) )
{
memcpy(data,&rom->code[address],length);
//成功读取指令
return;
}
else if((rom->len > (address)))
{
memcpy(data,&rom->code[address],rom->len-address);
//成功读取指令
return;
}
}
}
{
//失败跳转至0地址
uint8_t ljmp_zero[]= {0x02,0x00,0x00};
memcpy(data,ljmp_zero,(length>sizeof(ljmp_zero))?(sizeof(ljmp_zero)):(length));
}
}
}
/*
* helloworld程序(rom/helloworld目录)
*/
static const unsigned char hs_mcs_51_rom_helloworld_bin[] = {
0x02, 0x00, 0x29, 0x02, 0x00, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
0x00, 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x87, 0xff, 0xff,
0xff, 0xff, 0xff, 0x02, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
0x00, 0x89, 0x02, 0x00, 0xd0, 0x75, 0x81, 0x09, 0x12, 0x02, 0xe3, 0xe5,
0x82, 0x60, 0x03, 0x02, 0x00, 0x26, 0x79, 0x00, 0xe9, 0x44, 0x00, 0x60,
0x1b, 0x7a, 0x00, 0x90, 0x03, 0x10, 0x78, 0x01, 0x75, 0xa0, 0x00, 0xe4,
0x93, 0xf2, 0xa3, 0x08, 0xb8, 0x00, 0x02, 0x05, 0xa0, 0xd9, 0xf4, 0xda,
0xf2, 0x75, 0xa0, 0xff, 0xe4, 0x78, 0x7f, 0xf6, 0xd8, 0xfd, 0x78, 0x00,
0xe8, 0x44, 0x00, 0x60, 0x0a, 0x79, 0x01, 0x75, 0xa0, 0x00, 0xe4, 0xf3,
0x09, 0xd8, 0xfc, 0x78, 0x00, 0xe8, 0x44, 0x00, 0x60, 0x0c, 0x79, 0x00,
0x90, 0x00, 0x01, 0xe4, 0xf0, 0xa3, 0xd8, 0xfc, 0xd9, 0xfa, 0x02, 0x00,
0x26, 0x32, 0x32, 0x32, 0x32, 0x32, 0x75, 0x98, 0x90, 0x22, 0xae, 0x82,
0x8e, 0x99, 0x10, 0x99, 0x02, 0x80, 0xfb, 0x22, 0x30, 0x98, 0xfd, 0x85,
0x99, 0x82, 0xc2, 0x98, 0x22, 0xad, 0x82, 0xae, 0x83, 0xaf, 0xf0, 0x8d,
0x82, 0x8e, 0x83, 0x8f, 0xf0, 0x12, 0x02, 0x59, 0xfc, 0x60, 0x1c, 0x0d,
0xbd, 0x00, 0x01, 0x0e, 0x7b, 0x00, 0x8c, 0x82, 0x8b, 0x83, 0xc0, 0x07,
0xc0, 0x06, 0xc0, 0x05, 0x12, 0x00, 0x8e, 0xd0, 0x05, 0xd0, 0x06, 0xd0,
0x07, 0x80, 0xd8, 0x22, 0x12, 0x00, 0x8a, 0x90, 0x02, 0xe7, 0x75, 0xf0,
0x80, 0x12, 0x00, 0xa1, 0x90, 0x02, 0xf5, 0x75, 0xf0, 0x80, 0x12, 0x00,
0xa1, 0x7f, 0x01, 0xef, 0x24, 0xf6, 0x50, 0x03, 0x02, 0x01, 0xd7, 0x7e,
0x01, 0xc3, 0xef, 0x9e, 0x50, 0x03, 0x02, 0x01, 0xc9, 0x8f, 0x04, 0x7d,
0x00, 0x74, 0x30, 0x2c, 0xf5, 0x82, 0xe4, 0x3d, 0xf5, 0x83, 0xc0, 0x07,
0xc0, 0x06, 0x12, 0x00, 0x8e, 0x90, 0x00, 0x2a, 0x12, 0x00, 0x8e, 0xd0,
0x06, 0x8e, 0x04, 0x7d, 0x00, 0x74, 0x30, 0x2c, 0xf5, 0x82, 0xe4, 0x3d,
0xf5, 0x83, 0xc0, 0x06, 0x12, 0x00, 0x8e, 0x90, 0x00, 0x3d, 0x12, 0x00,
0x8e, 0xd0, 0x06, 0xd0, 0x07, 0x8f, 0xf0, 0xee, 0xa4, 0xfc, 0xad, 0xf0,
0xc3, 0xec, 0x94, 0x0a, 0xed, 0x64, 0x80, 0x94, 0x80, 0x40, 0x26, 0x75,
0x08, 0x0a, 0x75, 0x09, 0x00, 0x8c, 0x82, 0x8d, 0x83, 0xc0, 0x07, 0xc0,
0x06, 0x12, 0x02, 0xab, 0xe5, 0x82, 0x85, 0x83, 0xf0, 0x24, 0x30, 0xf5,
0x82, 0xe4, 0x35, 0xf0, 0xf5, 0x83, 0x12, 0x00, 0x8e, 0xd0, 0x06, 0xd0,
0x07, 0x8f, 0xf0, 0xee, 0xa4, 0xfc, 0xad, 0xf0, 0x75, 0x08, 0x0a, 0x75,
0x09, 0x00, 0x8c, 0x82, 0x8d, 0x83, 0xc0, 0x07, 0xc0, 0x06, 0xc0, 0x05,
0xc0, 0x04, 0x12, 0x02, 0x75, 0xe5, 0x82, 0x85, 0x83, 0xf0, 0x24, 0x30,
0xf5, 0x82, 0xe4, 0x35, 0xf0, 0xf5, 0x83, 0x12, 0x00, 0x8e, 0xd0, 0x04,
0xd0, 0x05, 0xd0, 0x06, 0xd0, 0x07, 0xc3, 0xec, 0x94, 0x0a, 0xed, 0x64,
0x80, 0x94, 0x80, 0x50, 0x0e, 0x90, 0x00, 0x20, 0xc0, 0x07, 0xc0, 0x06,
0x12, 0x00, 0x8e, 0xd0, 0x06, 0xd0, 0x07, 0x90, 0x00, 0x20, 0xc0, 0x07,
0xc0, 0x06, 0x12, 0x00, 0x8e, 0xd0, 0x06, 0xd0, 0x07, 0x0e, 0x02, 0x00,
0xf1, 0x90, 0x00, 0x0a, 0xc0, 0x07, 0x12, 0x00, 0x8e, 0xd0, 0x07, 0x0f,
0x02, 0x00, 0xe7, 0x12, 0x00, 0x98, 0x7e, 0x00, 0x8e, 0x83, 0x12, 0x00,
0x8e, 0x80, 0xf4, 0xe5, 0x08, 0x45, 0x09, 0x60, 0x46, 0x7a, 0x01, 0xe5,
0x08, 0x25, 0xe0, 0xf5, 0x08, 0xe5, 0x09, 0x33, 0x40, 0x12, 0xf5, 0x09,
0xe5, 0x82, 0x95, 0x08, 0xe5, 0x83, 0x95, 0x09, 0x40, 0x03, 0x0a, 0x80,
0xe6, 0xc3, 0xe5, 0x09, 0x13, 0xf5, 0x09, 0xe5, 0x08, 0x13, 0xf5, 0x08,
0xc3, 0xe5, 0x82, 0x95, 0x08, 0xf5, 0xf0, 0xe5, 0x83, 0x95, 0x09, 0x40,
0x05, 0xf5, 0x83, 0x85, 0xf0, 0x82, 0xc3, 0xe5, 0x09, 0x13, 0xf5, 0x09,
0xe5, 0x08, 0x13, 0xf5, 0x08, 0xda, 0xe1, 0x22, 0x7a, 0x10, 0xe4, 0xfb,
0xfc, 0xe5, 0x82, 0x25, 0xe0, 0xf5, 0x82, 0xe5, 0x83, 0x33, 0xf5, 0x83,
0xeb, 0x33, 0xfb, 0xec, 0x33, 0xfc, 0xeb, 0x95, 0x08, 0xf5, 0xf0, 0xec,
0x95, 0x09, 0x40, 0x06, 0xfc, 0xab, 0xf0, 0x43, 0x82, 0x01, 0xda, 0xdd,
0x22, 0x20, 0xf7, 0x14, 0x30, 0xf6, 0x14, 0x88, 0x83, 0xa8, 0x82, 0x20,
0xf5, 0x07, 0xe6, 0xa8, 0x83, 0x75, 0x83, 0x00, 0x22, 0xe2, 0x80, 0xf7,
0xe4, 0x93, 0x22, 0xe0, 0x22, 0xc2, 0xd5, 0xe5, 0x83, 0x30, 0xe7, 0x0d,
0xd2, 0xd5, 0xe4, 0xc3, 0x95, 0x82, 0xf5, 0x82, 0xe4, 0x95, 0x83, 0xf5,
0x83, 0xe5, 0x09, 0x30, 0xe7, 0x0b, 0xe4, 0xc3, 0x95, 0x08, 0xf5, 0x08,
0xe4, 0x95, 0x09, 0xf5, 0x09, 0x12, 0x01, 0xe3, 0x30, 0xd5, 0x0b, 0xe4,
0xc3, 0x95, 0x82, 0xf5, 0x82, 0xe4, 0x95, 0x83, 0xf5, 0x83, 0x22, 0xc2,
0xd5, 0xe5, 0x83, 0x30, 0xe7, 0x0d, 0xd2, 0xd5, 0xe4, 0xc3, 0x95, 0x82,
0xf5, 0x82, 0xe4, 0x95, 0x83, 0xf5, 0x83, 0xe5, 0x09, 0x30, 0xe7, 0x0d,
0xb2, 0xd5, 0xe4, 0xc3, 0x95, 0x08, 0xf5, 0x08, 0xe4, 0x95, 0x09, 0xf5,
0x09, 0x12, 0x02, 0x30, 0x30, 0xd5, 0x0b, 0xe4, 0xc3, 0x95, 0x82, 0xf5,
0x82, 0xe4, 0x95, 0x83, 0xf5, 0x83, 0x22, 0x75, 0x82, 0x00, 0x22, 0x48,
0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0a,
0x00, 0x39, 0x78, 0x39, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c,
0x65, 0x3a, 0x0a, 0x00
};
#define hs_mcs_51_rom_helloworld_len 784
const hs_mcs_51_rom_t hs_mcs_51_rom_helloworld=
{
hs_mcs_51_rom_helloworld_bin,
hs_mcs_51_rom_helloworld_len,
HS_MCS_51_ROM_PSBANK_C8051F120_SFR_ADDRESS
};

View File

@ -0,0 +1,67 @@
/***************************************************************
* Name: mcs_51_rom.h
* Purpose: mcs_51_rom接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-13
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_MCS_51_ROM_H__
#define __HS_MCS_51_ROM_H__
#include "stdio.h"
#include "string.h"
#include "mcs_51_core.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*
* PSBANK通常用于MCS-5164KB大小huge64KB地址空间分为2个32KB的Bank32KB的Bank
* PSBANK通常为一个8位SFR寄存器4Bank4Bank
* 使PSBANK功能PSBANK寄存器__sfr __at (0xB1) PSBANK;huge模型
*/
#define HS_MCS_51_ROM_PSBANK_C8051F120_SFR_ADDRESS (0xB1)
#define HS_MCS_51_ROM_PSBANK_CC2530_SFR_ADDRESS (0x9F)
struct hs_mcs_51_rom;
typedef struct hs_mcs_51_rom hs_mcs_51_rom_t;
struct hs_mcs_51_rom
{
const unsigned char *code; /**< 程序指针 */
unsigned int len; /**< 程序长度 */
unsigned char psbank_addr; /**< 程序PSBANK寄存器地址默认为C8051F120的PSBANK地址*/
};
/** \brief MCS-51 ROM初始化参数
*
*
*/
#define HS_MCS_51_ROM_INITIALIZER {NULL,0,HS_MCS_51_ROM_PSBANK_C8051F120_SFR_ADDRESS}
/** \brief MCS-51 ROM总线IO操作(一般由总线上的主设备(如CPU)调用)注意此操作不能在RAM操作之前调用
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param rom hs_mcs_51_rom_t* MCS-51 ROM指针,
*
*/
void hs_mcs_51_rom_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_rom_t *rom);
/*
* helloworld程序(rom/helloworld目录)
*/
extern const hs_mcs_51_rom_t hs_mcs_51_rom_helloworld;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_MCS_51_ROM_H__

View File

@ -0,0 +1,244 @@
/***************************************************************
* Name: mcs_51_serial.c
* Purpose: mcs_51_serial接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-13
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "mcs_51_serial.h"
void hs_mcs_51_serial_init(hs_mcs_51_serial_t *serial,hs_mcs_51_serial_io_callback_t io,void *usr)
{
hs_mcs_51_serial_t new_serial= {io,usr,0,0};
if(serial!=NULL)
{
(*serial)=new_serial;
}
}
void hs_mcs_51_serial_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_serial_t *serial)
{
if(serial==NULL || core == NULL)
{
//无效无io操作
return;
}
switch(opt)
{
case HS_MCS_51_IO_TICK_ENTER:
{
if(serial->io!=NULL)
{
uint16_t core_pc= hs_mcs_51_pc_get(core);
serial->io(serial,HS_MCS_51_SERIAL_IO_TICK,&core_pc);
}
if((serial->RB&((1ULL<<8)))!=0)
{
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_RB8,true);
}
else
{
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_RB8,false);
}
if(hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_EA) && hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_ES))
{
//中断已使能
if(hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_RI) || hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_TI))
{
//需要中断
if(hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_PS))
{
//高优先级
if(hs_mcs_51_core_interrupt_nested_get(core) < 2)
{
hs_mcs_51_core_interrupt_set(core,HS_MCS_51_INTERRUPT_8051_SI0,true);
}
}
else
{
//低优先级
if(hs_mcs_51_core_interrupt_nested_get(core) < 1)
{
hs_mcs_51_core_interrupt_set(core,HS_MCS_51_INTERRUPT_8051_SI0,false);
}
}
}
}
}
break;
case HS_MCS_51_IO_TICK_EXIT:
{
}
break;
case HS_MCS_51_IO_READ_RAM_SFR: //读取内部低128字节RAM与SFR
{
switch(address)
{
case HS_MCS_51_SFR_SBUF:
{
if(serial->io!=NULL)
{
serial->io(serial,HS_MCS_51_SERIAL_IO_RECEIVE,&serial->RB);
}
if(data!=NULL)
{
(*data)=(serial->RB&0xFF);
}
}
break;
default:
{
}
break;
}
}
break;
case HS_MCS_51_IO_WRITE_RAM_SFR: //写入内部低128字节RAM与SFR
{
switch(address)
{
case HS_MCS_51_SFR_SBUF:
{
if(serial->io==NULL)
{
//当io函数为空时默认成功
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_TI,true);
}
else
{
if(data!=NULL)
{
serial->TH=(*data);
}
serial->TH&=(~((1ULL<<8)));
if(hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_TB8))
{
serial->TH|=((1ULL<<8));
}
if(serial->io(serial,HS_MCS_51_SERIAL_IO_TRANSMIT,&serial->TH))
{
//当io函数成功时,默认成功。当IO函数失败时默认由用户设置TI标志
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_TI,true);
}
}
}
break;
default:
{
}
break;
}
}
break;
default:
{
}
break;
}
}
size_t hs_mcs_51_serial_config_mode_get(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial)
{
(void)serial;
uint8_t scon=0;
hs_mcs_51_sfr_read(core,HS_MCS_51_SFR_SCON,&scon);
return scon>>6;//高2位表示模式
}
size_t hs_mcs_51_serial_config_baud_get(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial)
{
size_t baud=0;
switch(hs_mcs_51_serial_config_mode_get(core,serial))
{
case 0:
{
baud=HS_MCS_51_COMMON_CLK_FREQ/12;
}
break;
case 1:
case 3:
{
uint8_t pcon=0;
hs_mcs_51_sfr_read(core,HS_MCS_51_SFR_PCON,&pcon);
bool smod=pcon&0x80;
uint8_t th1=0;
hs_mcs_51_sfr_read(core,HS_MCS_51_SFR_TH1,&th1);
baud=HS_MCS_51_COMMON_CLK_FREQ*(smod?2:1)/32/((256-th1)*12);
}
break;
case 2:
{
uint8_t pcon=0;
hs_mcs_51_sfr_read(core,HS_MCS_51_SFR_PCON,&pcon);
bool smod=pcon&0x80;
baud=HS_MCS_51_COMMON_CLK_FREQ*(smod?2:1)/64;
}
break;
default:
{
}
break;
}
return baud;
}
void hs_mcs_51_serial_config_ti_set(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial)
{
(void)serial;
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_TI,true);
}
bool hs_mcs_51_serial_config_ri_get(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial)
{
(void)serial;
return hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_RI);
}
bool hs_mcs_51_serial_status_dataready_set(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial,uint16_t data)
{
if(core==0 || serial==0)
{
//参数错误
return false;
}
if(!hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_REN))
{
//程序未启用串口
return false;
}
if(hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_RI))
{
//程序未清除RI标志
return false;
}
bool RB8=((data&(1ULL<<8))!=0);
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_RB8,RB8);
serial->RB=data;
if(hs_mcs_51_bit_read(core,HS_MCS_51_BIT_ADDRESS_SM2)&&!RB8)
{
//启用SM2不接收RB8为0的数据
return false;
}
//设置RI标志
hs_mcs_51_bit_write(core,HS_MCS_51_BIT_ADDRESS_RI,true);
return true;
}

View File

@ -0,0 +1,122 @@
/***************************************************************
* Name: mcs_51_serial.h
* Purpose: mcs_51_serial接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-13
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_MCS_51_SERIAL_H__
#define __HS_MCS_51_SERIAL_H__
#include "mcs_51_common.h"
#include "mcs_51_core.h"
#ifdef __cplusplus
extern "C"
{
#endif
struct hs_mcs_51_serial;
typedef struct hs_mcs_51_serial hs_mcs_51_serial_t;
typedef enum
{
HS_MCS_51_SERIAL_IO_TRANSMIT=0, /**< 发送数据,写SBUF时触发*/
HS_MCS_51_SERIAL_IO_RECEIVE, /**< 接收数据,读SBUF时触发 */
HS_MCS_51_SERIAL_IO_TICK, /**< 节拍总线节拍时触发数据为内核PC值*/
} hs_mcs_51_serial_io_t;
/** \brief
*
* \param serial hs_mcs_51_serial_t* MCS-51
* \param io_type hs_mcs_51_serial_io_t io类型
* \param data uint16_t* /
* \return bool
*
*/
typedef bool (*hs_mcs_51_serial_io_callback_t)(hs_mcs_51_serial_t *serial,hs_mcs_51_serial_io_t io_type,uint16_t *data);
struct hs_mcs_51_serial
{
hs_mcs_51_serial_io_callback_t io; /**< IO回调 */
void* usr; /**< 用户指针,用于串口的用户指针 */
uint16_t RB; /**< 接收缓冲 */
uint16_t TH; /**< 发送保持 */
};
/** \brief MCS-51串口初始化
*
* \param serial hs_mcs_51_serial_t* MCS-51
* \param io hs_mcs_51_serial_io_callback_t IO回调
* \param usr void*
*
*/
void hs_mcs_51_serial_init(hs_mcs_51_serial_t *serial,hs_mcs_51_serial_io_callback_t io,void *usr);
/** \brief MCS-51串口总线IO操作(一般由总线上的主设备(如CPU)调用)
*
* \param core hs_mcs_51_core_t* MCS-51hs_mcs_51_io_t
* \param address uint16_t hs_mcs_51_io_t
* \param opt hs_mcs_51_io_opt_t IO操作选项hs_mcs_51_io_t
* \param data uint8_t* hs_mcs_51_io_t
* \param length uint16_t hs_mcs_51_io_t
* \param usr void* hs_mcs_51_io_t
* \param serial hs_mcs_51_serial_t* MCS-51NULL时此函数内部不操作
*
*/
void hs_mcs_51_serial_bus_io(hs_mcs_51_core_t *core,hs_mcs_51_io_opt_t opt,uint16_t address,uint8_t *data,uint16_t length,void *usr,hs_mcs_51_serial_t *serial);
/** \brief MCS-51串口获取串口模式
*
* \param core hs_mcs_51_core_t* MCS-51
* \param serial hs_mcs_51_serial_t* MCS-51
* \return size_t
*
*/
size_t hs_mcs_51_serial_config_mode_get(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial);
/** \brief MCS-51串口获取串口波特率
*
* \param core hs_mcs_51_core_t* MCS-51
* \param serial hs_mcs_51_serial_t* MCS-51
* \return size_t
*
*/
size_t hs_mcs_51_serial_config_baud_get(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial);
/** \brief MCS-51串口设置TI
*
* \param core hs_mcs_51_core_t* MCS-51
* \param serial hs_mcs_51_serial_t* MCS-51
*
*/
void hs_mcs_51_serial_config_ti_set(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial);
/** \brief MCS-51串口获取RI
*
* \param core hs_mcs_51_core_t* MCS-51
* \param serial hs_mcs_51_serial_t* MCS-51
* \return bool RI标志
*
*/
bool hs_mcs_51_serial_config_ri_get(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial);
/** \brief MCS-51串口设置数据用于设置接收到的数据
*
* \param core hs_mcs_51_core_t* MCS-51
* \param serial hs_mcs_51_serial_t* MCS-51
* \param data uint16_t SM2使(io回调中设置)
* \return bool
*
*/
bool hs_mcs_51_serial_status_dataready_set(hs_mcs_51_core_t *core,hs_mcs_51_serial_t *serial,uint16_t data);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_MCS_51_SERIAL_H__

View File

@ -0,0 +1,116 @@
#include "stdio.h"
#include "stdint.h"
#include "8051.h"
/*
* PSBANK的SFRmodel-huge,SDCC的C运行库crtbank.asm
*/
__sfr __at (0xB1) PSBANK;
//外部中断0
void ie0_isr(void) __interrupt(IE0_VECTOR)
{
}
//定时器0
void tf0_isr(void) __interrupt(TF0_VECTOR)
{
}
//外部中断1
void ie1_isr(void) __interrupt(IE1_VECTOR)
{
}
//定时器1
void tf1_isr(void) __interrupt(TF1_VECTOR)
{
}
//串口0
void si0_isr(void) __interrupt(SI0_VECTOR)
{
}
void uart_init(void)
{
SCON=0x90;
}
void uart_send_char(int ch)
{
SBUF=(uint8_t)ch;
/*
* TI需要被硬件1
*/
while(TI==0);
TI=0;
}
uint8_t uart_receive_char(void)
{
/*
* RI需要被硬件1
*/
while(RI==0);
uint8_t data=SBUF;
RI=0;
return data;
}
void uart_send_str(char *str)
{
while(*str!='\0')
{
uart_send_char(*(str++));
}
}
void main(void)
{
uart_init();
uart_send_str("Hello World!\n");
{
//打印9x9乘法表
uart_send_str("9x9 multiplication table:\n");
for(uint8_t i=1; i<=9; i++)
{
for(uint8_t j=1; j<=i; j++)
{
uart_send_char(i+'0');
uart_send_char('*');
uart_send_char(j+'0');
uart_send_char('=');
if(i*j >= 10)
{
uart_send_char('0'+i*j/10);
}
uart_send_char('0'+i*j%10);
if(i*j < 10)
{
uart_send_char(' ');
}
uart_send_char(' ');
}
uart_send_char('\n');
}
}
while(1)
{
int data=uart_receive_char();
uart_send_char(data);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
/***************************************************************
* Name: risc-v.h
* Purpose: risc-v接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-01-29
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_RISC_V_H__
#define __HS_RISC_V_H__
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#include "risc-v_common.h"
#include "risc-v_opcodes.h"
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_RISC_V_H__

View File

@ -0,0 +1,192 @@
/***************************************************************
* Name: risc-v_common.h
* Purpose: risc-v common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-01-29
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "risc-v_common.h"
size_t hs_risc_v_common_instruction_length(uint32_t instruction)
{
if((instruction&0x707F)==0x707F)
{
//192位及更高位数
return 192/8;
}
else if((instruction&0x7F)==0x7F)
{
//80位指令及更高位数
return (80+16*((instruction>>12)&0x7))/8;
}
else if((instruction&0x7F)==0x3F)
{
//64位指令
return 64/8;
}
else if((instruction&0x3F)==0x1F)
{
//48位指令
return 48/8;
}
else if((instruction&0x3)==0x3)
{
//32位指令
return 32/8;
}
else
{
//16位指令
return 16/8;
}
}
int32_t hs_risc_v_common_sign_extend_uint12(uint16_t data)
{
union
{
struct
{
uint16_t val:12;
} unsigned_data;
struct
{
int16_t val:12;
} signed_data;
} cvt;
cvt.unsigned_data.val=data;
return cvt.signed_data.val;
}
int64_t hs_risc_v_common_sign_extend_uint32(uint32_t data)
{
union
{
struct
{
uint64_t val:32;
} unsigned_data;
struct
{
int64_t val:32;
} signed_data;
} cvt;
cvt.unsigned_data.val=data;
return cvt.signed_data.val;
}
bool hs_risc_v_common_instruction_set_sets_has_rv32g(uint32_t sets)
{
uint32_t rv32g=HS_RISC_V_COMMON_INSTRUCTION_SET_RV32G;
if((sets&0xF)==(rv32g&0xF))
{
//基本指令集相同,比较指令集扩展
if(((sets&rv32g)&0xFFFFFFF0)==(rv32g&0xFFFFFFF0))
{
return true;
}
}
return false;
}
bool hs_risc_v_common_instruction_set_sets_has_rv64g(uint32_t sets)
{
uint32_t rv64g=HS_RISC_V_COMMON_INSTRUCTION_SET_RV64G;
if((sets&0xF)==(rv64g&0xF))
{
//基本指令集相同,比较指令集扩展
if(((sets&rv64g)&0xFFFFFFF0)==(rv64g&0xFFFFFFF0))
{
return true;
}
}
return false;
}
bool hs_risc_v_common_instruction_set_sets_has_set(uint32_t sets,hs_risc_v_common_instruction_set_t instruction_set)
{
if(instruction_set >= (1ULL<<(4)))
{
//扩展指令集通过位来判断
return (instruction_set&sets)!=0;
}
else
{
//基本指令集需要通过等于来判断
uint32_t instruction_base_set=(sets&0x0000000F);
return instruction_base_set==(uint32_t)instruction_set;
}
}
uint32_t hs_risc_v_common_instruction_set_sets_format(uint32_t sets)
{
{
//基本指令集
uint32_t instruction_base_set=(sets&0x0000000F);
sets&=(~0x0000000F);
switch(instruction_base_set)
{
case HS_RISC_V_COMMON_INSTRUCTION_SET_RV32I:
case HS_RISC_V_COMMON_INSTRUCTION_SET_RV32E:
case HS_RISC_V_COMMON_INSTRUCTION_SET_RV64I:
case HS_RISC_V_COMMON_INSTRUCTION_SET_RV64E:
case HS_RISC_V_COMMON_INSTRUCTION_SET_RV128I:
{
}
break;
default:
{
//默认基本指令集为RV32I
instruction_base_set=HS_RISC_V_COMMON_INSTRUCTION_SET_RV32I;
}
break;
}
sets|=instruction_base_set;
}
{
//扩展指令集依赖添加(默认使用32位的枚举值64位及更高位通常枚举值相同)
//指令扩展"D"依赖指令扩展"F"
if(hs_risc_v_common_instruction_set_sets_has_set(sets,HS_RISC_V_COMMON_INSTRUCTION_SET_RV32D))
{
sets|=HS_RISC_V_COMMON_INSTRUCTION_SET_RV32F;
}
//指令扩展"F"依赖指令扩展"Zicsr"
if(hs_risc_v_common_instruction_set_sets_has_set(sets,HS_RISC_V_COMMON_INSTRUCTION_SET_RV32F))
{
sets|=HS_RISC_V_COMMON_INSTRUCTION_SET_RV32ZICSR;
}
}
return sets;
}
uint32_t hs_risc_v_common_instruction_set_sets_set_set(uint32_t sets,hs_risc_v_common_instruction_set_t instruction_set)
{
if(instruction_set >= (1ULL<<(4)))
{
sets|=instruction_set;
}
else
{
sets &=0xFFFFFFF0;
sets |=instruction_set;
}
return hs_risc_v_common_instruction_set_sets_format(sets);
}
uint32_t hs_risc_v_common_instruction_set_sets_clear_set(uint32_t sets,hs_risc_v_common_instruction_set_t instruction_set)
{
if(instruction_set >= (1ULL<<(4)))
{
sets&=((~instruction_set)&0xFFFFFFF0);
}
return hs_risc_v_common_instruction_set_sets_format(sets);
}

View File

@ -0,0 +1,281 @@
/***************************************************************
* Name: risc-v_common.h
* Purpose: risc-v common接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-01-29
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_RISC_V_COMMON_H__
#define __HS_RISC_V_COMMON_H__
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#include "stdlib.h"
#include "stdint.h"
#include "stdbool.h"
#include "string.h"
/** \brief 获取指令长度,通常情况下risc-v的指令长度为32位/16位但risc-v也规定了指令长度一般是16位的整倍数的编码。
*
*
* \param instruction uint32_t 3232
* \return size_t
*
*/
size_t hs_risc_v_common_instruction_length(uint32_t instruction);
/** \brief 32位指令基础操作码。基础操作码主要指指令低7位。
* 231616
*
*/
typedef enum
{
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_LOAD = 0b0000011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_STORE = 0b0100011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_MADD = 0b1000011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_BRANCH = 0b1100011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_LOAD_FP = 0b0000111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_STORE_FP = 0b0100111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_MSUB = 0b1000111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_JALR = 0b1100111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_CUSTOM_0 = 0b0001011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_CUSTOM_1 = 0b0101011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_NMSUB = 0b1001011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_RESERVED = 0b1101011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_MISC_MEM = 0b0001111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_AMO = 0b0101111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_NMADD = 0b1001111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_JAL = 0b1101111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP_IMM = 0b0010011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP = 0b0110011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP_FP = 0b1010011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_SYSTEM = 0b1110011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_AUIPC = 0b0010111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_LUI = 0b0110111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP_V = 0b1010111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP_VE = 0b1110111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP_IMM_32 = 0b0011011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_OP_32 = 0b0111011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_CUSTOM_3 = 0b1011011,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_CUSTOM_4 = 0b1111011,
/*
*
*/
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_TO_48BIT_0 = 0b0011111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_TO_64BIT = 0b0111111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_TO_48BIT_1 = 0b1011111,
HS_RISC_V_COMMON_INSTRUCTION_32BIT_BASE_OPCODE_TO_80BIT_OR_HIGHER = 0b1111111,
} hs_risc_v_common_instruction_32bit_base_opcode;
/** \brief 将12位数扩展为32位有符号数
*
* \param data uint16_t 12()
* \return int32_t 32(64,C语言支持的类型可直接符号扩展)
*
*/
int32_t hs_risc_v_common_sign_extend_uint12(uint16_t data);
/** \brief 将32位数扩展为64位有符号数
*
* \param data uint16_t 32()
* \return int32_t 64
*
*/
int64_t hs_risc_v_common_sign_extend_uint32(uint32_t data);
typedef union
{
uint8_t bytes[1];
uint8_t value;
int8_t s_value;
} hs_risc_v_common_memory_byte_t; /**< 字节类型 */
typedef union
{
uint8_t bytes[2];
uint16_t value;
int16_t s_value;
} hs_risc_v_common_memory_halfword_t; /**< 半字类型 */
typedef union
{
uint8_t bytes[4];
uint32_t value;
int32_t s_value;
} hs_risc_v_common_memory_word_t; /**< 字类型 */
typedef union
{
uint8_t bytes[8];
uint64_t value;
int64_t s_value;
} hs_risc_v_common_memory_doubleword_t; /**< 双字类型 */
typedef union
{
uint8_t bytes[16];
} hs_risc_v_common_memory_quadword_t; /**< 四字类型 */
#ifndef HS_RISC_V_COMMOM_MEMORY_BYTEORDER_FIX
/*
* value成员可用bytes成员可用
* Data为变量名称
*/
#define HS_RISC_V_COMMOM_MEMORY_BYTEORDER_FIX(Data) \
{ \
hs_risc_v_common_memory_halfword_t m_hs_byteorder; \
m_hs_byteorder.value=0x01; \
if(m_hs_byteorder.bytes[0]==0) \
{ \
for(size_t i=0;i<sizeof(Data)/2;i++) \
{ \
uint8_t temp=(Data).bytes[i]; \
(Data).bytes[i]=(Data).bytes[sizeof(Data)-1-i]; \
(Data).bytes[sizeof(Data)-1-i]=temp; \
} \
}; \
}
#endif // HS_RISC_V_COMMOM_MEMORY_BYTEORDER_FIX
typedef enum
{
/*
* 4,1
*/
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32I= (0ULL << (0)), /**< RV32I基本指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32E= (1ULL << (0)), /**< RV32E基本指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64I= (2ULL << (0)), /**< RV64I基本指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64E= (3ULL << (0)), /**< RV64E基本指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV128I=(4ULL << (0)), /**< RV128I基本指令集 */
/*
*
*/
//"C"扩展:压缩指令
HS_RISC_V_COMMON_INSTRUCTION_SET_RVC= (1ULL << (4)), /**< RVC扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32C= (1ULL << (4)), /**< RV32C扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64C= (1ULL << (4)), /**< RV64C扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV128C=(1ULL << (4)), /**< RV128C扩展指令集 */
//"A"扩展:原子操作指令
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32A= (1ULL << (5)), /**< RV32A扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64A= (1ULL << (5)), /**< RV64A扩展指令集 */
//"M"扩展:整数乘除
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32M= (1ULL << (6)), /**< RV32M扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64M= (1ULL << (6)), /**< RV64M扩展指令集 */
//"F"扩展:单精度浮点,依赖"Zicsr"扩展
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32F= (1ULL << (7)), /**< RV32F扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64F= (1ULL << (7)), /**< RV64F扩展指令集 */
//"D"扩展:双精度浮点,依赖"F"扩展
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32D= (1ULL << (8)), /**< RV32D扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64D= (1ULL << (8)), /**< RV64D扩展指令集 */
//"Zicsr"扩展:控制状态寄存器
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32ZICSR= (1ULL << (26+1)), /**< RV32Zicsr扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64ZICSR= (1ULL << (26+1)), /**< RV64Zicsr扩展指令集 */
//"Zifencei"扩展:控制状态寄存器
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32ZIFENCEI= (1ULL << (26+2)), /**< RV32Zicsr扩展指令集 */
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64ZIFENCEI= (1ULL << (26+2)), /**< RV64Zicsr扩展指令集 */
} hs_risc_v_common_instruction_set_t; /**< 指令集类型 */
/** \brief RISC-V 32位通用指令集RV32G包括IMAFDZicsr_Zifencei
*
*
*/
#define HS_RISC_V_COMMON_INSTRUCTION_SET_RV32G (\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32I |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32M |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32A |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32F |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32D |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32ZICSR |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV32ZIFENCEI )
/** \brief 指令集集合中是否含有32位通用指令集
*
* \param sets uint32_t
* \return bool
*
*/
bool hs_risc_v_common_instruction_set_sets_has_rv32g(uint32_t sets);
/** \brief RISC-V 64位通用指令集RV64G包括IMAFDZicsr_Zifencei
*
*
*/
#define HS_RISC_V_COMMON_INSTRUCTION_SET_RV64G (\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64I |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64M |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64A |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64F |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64D |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64ZICSR |\
HS_RISC_V_COMMON_INSTRUCTION_SET_RV64ZIFENCEI )
/** \brief 指令集集合中是否含有64位通用指令集
*
* \param sets uint32_t
* \return bool
*
*/
bool hs_risc_v_common_instruction_set_sets_has_rv64g(uint32_t sets);
/** \brief 指令集集合中是否有某个指令集
*
* \param sets uint32_t
* \param instruction_set hs_risc_v_common_instruction_set_t
* \return bool
*
*/
bool hs_risc_v_common_instruction_set_sets_has_set(uint32_t sets,hs_risc_v_common_instruction_set_t instruction_set);
/** \brief 指令集集合格式化(去除其中不合理的值如不存在的基本指令集、添加某些指令集依赖(指一个指令集依赖另一个指令集))
*
* \param sets uint32_t
* \return uint32_t
*
*/
uint32_t hs_risc_v_common_instruction_set_sets_format(uint32_t sets);
/** \brief 指令集集合添加指令集类型
*
* \param sets uint32_t
* \param instruction_set hs_risc_v_common_instruction_set_t
* \return uint32_t
*
*/
uint32_t hs_risc_v_common_instruction_set_sets_set_set(uint32_t sets,hs_risc_v_common_instruction_set_t instruction_set);
/** \brief 指令集集合删除指令集类型。注意:只可以删除扩展指令且仅当没有指令依赖待删除的指令时可成功删除
*
* \param sets uint32_t
* \param instruction_set hs_risc_v_common_instruction_set_t
* \return uint32_t
*
*/
uint32_t hs_risc_v_common_instruction_set_sets_clear_set(uint32_t sets,hs_risc_v_common_instruction_set_t instruction_set);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_RISC_V_COMMON_H__

View File

@ -0,0 +1,33 @@
/***************************************************************
* Name: risc-v_opcodes.h
* Purpose: risc-v opcodes接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-17
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "risc-v_opcodes.h"
/*
* INSN
*/
#ifndef DECLARE_INSN
#define DECLARE_INSN(NAME,MATCH,MASK) \
extern const hs_risc_v_opcodes_insn_t hs_risc_v_opcodes_insn_##NAME;\
const hs_risc_v_opcodes_insn_t hs_risc_v_opcodes_insn_##NAME={#NAME,MATCH,MASK};
#endif // DECLARE_INSN
/*
* CSR
*/
#ifndef DECLARE_CSR
#define DECLARE_CSR(NAME,ADDR) \
extern const hs_risc_v_opcodes_csr_t hs_risc_v_opcodes_csr_##NAME;\
const hs_risc_v_opcodes_csr_t hs_risc_v_opcodes_csr_##NAME={#NAME,ADDR};
#endif // DECLARE_INSN
/*
* riscv-opcodeshttps://github.com/riscv/riscv-opcodes.git生成的C语言头文件。
*
*/
#include "encoding.out.h"

View File

@ -0,0 +1,351 @@
/***************************************************************
* Name: risc-v_opcodes.h
* Purpose: risc-v_opcodes接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-17
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HS_RISC_V_OPCODES_H__
#define __HS_RISC_V_OPCODES_H__
#include "stdint.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
struct hs_risc_v_opcodes_insn;
typedef struct hs_risc_v_opcodes_insn hs_risc_v_opcodes_insn_t;
struct hs_risc_v_opcodes_insn
{
const char *name; /**< 指令名称 */
uint32_t match; /**< 指令匹配值 */
uint32_t mask; /**< 指令匹配掩码 */
};
/** \brief 声明要使用的INSN
*
*
*/
#ifdef __cplusplus
#define HS_RISC_V_OPCODES_INSN_DECLARE(NAME) \
extern "C" const hs_risc_v_opcodes_insn_t hs_risc_v_opcodes_insn_##NAME
#else
#define HS_RISC_V_OPCODES_INSN_DECLARE(NAME) \
extern const hs_risc_v_opcodes_insn_t hs_risc_v_opcodes_insn_##NAME
#endif
/** \brief 获取INSN的名称
*
*
*/
#define HS_RISC_V_OPCODES_INSN_NAME(NAME) (hs_risc_v_opcodes_insn_##NAME)
/*
* RV32I
*/
HS_RISC_V_OPCODES_INSN_DECLARE(lui);
HS_RISC_V_OPCODES_INSN_DECLARE(auipc);
HS_RISC_V_OPCODES_INSN_DECLARE(jal);
HS_RISC_V_OPCODES_INSN_DECLARE(jalr);
HS_RISC_V_OPCODES_INSN_DECLARE(beq);
HS_RISC_V_OPCODES_INSN_DECLARE(bne);
HS_RISC_V_OPCODES_INSN_DECLARE(blt);
HS_RISC_V_OPCODES_INSN_DECLARE(bge);
HS_RISC_V_OPCODES_INSN_DECLARE(bltu);
HS_RISC_V_OPCODES_INSN_DECLARE(bgeu);
HS_RISC_V_OPCODES_INSN_DECLARE(lb);
HS_RISC_V_OPCODES_INSN_DECLARE(lh);
HS_RISC_V_OPCODES_INSN_DECLARE(lw);
HS_RISC_V_OPCODES_INSN_DECLARE(lbu);
HS_RISC_V_OPCODES_INSN_DECLARE(lhu);
HS_RISC_V_OPCODES_INSN_DECLARE(sb);
HS_RISC_V_OPCODES_INSN_DECLARE(sh);
HS_RISC_V_OPCODES_INSN_DECLARE(sw);
HS_RISC_V_OPCODES_INSN_DECLARE(addi);
HS_RISC_V_OPCODES_INSN_DECLARE(slti);
HS_RISC_V_OPCODES_INSN_DECLARE(xori);
HS_RISC_V_OPCODES_INSN_DECLARE(ori);
HS_RISC_V_OPCODES_INSN_DECLARE(andi);
HS_RISC_V_OPCODES_INSN_DECLARE(add);
HS_RISC_V_OPCODES_INSN_DECLARE(sub);
HS_RISC_V_OPCODES_INSN_DECLARE(sll);
HS_RISC_V_OPCODES_INSN_DECLARE(slt);
HS_RISC_V_OPCODES_INSN_DECLARE(sltu);
HS_RISC_V_OPCODES_INSN_DECLARE(xor);
HS_RISC_V_OPCODES_INSN_DECLARE(srl);
HS_RISC_V_OPCODES_INSN_DECLARE(sra);
HS_RISC_V_OPCODES_INSN_DECLARE(or);
HS_RISC_V_OPCODES_INSN_DECLARE(and);
HS_RISC_V_OPCODES_INSN_DECLARE(fence);
HS_RISC_V_OPCODES_INSN_DECLARE(ecall);
HS_RISC_V_OPCODES_INSN_DECLARE(ebreak);
HS_RISC_V_OPCODES_INSN_DECLARE(slli);
HS_RISC_V_OPCODES_INSN_DECLARE(srli);
HS_RISC_V_OPCODES_INSN_DECLARE(srai);
HS_RISC_V_OPCODES_INSN_DECLARE(pause);
/*
* RV64IRV32I新增
*/
HS_RISC_V_OPCODES_INSN_DECLARE(lwu);
HS_RISC_V_OPCODES_INSN_DECLARE(ld);
HS_RISC_V_OPCODES_INSN_DECLARE(sd);
HS_RISC_V_OPCODES_INSN_DECLARE(slli);
HS_RISC_V_OPCODES_INSN_DECLARE(srli);
HS_RISC_V_OPCODES_INSN_DECLARE(srai);
HS_RISC_V_OPCODES_INSN_DECLARE(addw);
HS_RISC_V_OPCODES_INSN_DECLARE(subw);
HS_RISC_V_OPCODES_INSN_DECLARE(sllw);
HS_RISC_V_OPCODES_INSN_DECLARE(srlw);
HS_RISC_V_OPCODES_INSN_DECLARE(sraw);
/*
* RV32/RV64 Zifencei
*/
HS_RISC_V_OPCODES_INSN_DECLARE(fence_i);
/*
* RV32/RV64 Zicsr
*/
HS_RISC_V_OPCODES_INSN_DECLARE(csrrw);
HS_RISC_V_OPCODES_INSN_DECLARE(csrrs);
HS_RISC_V_OPCODES_INSN_DECLARE(csrrc);
HS_RISC_V_OPCODES_INSN_DECLARE(csrrwi);
HS_RISC_V_OPCODES_INSN_DECLARE(csrrsi);
HS_RISC_V_OPCODES_INSN_DECLARE(csrrci);
/*
* RV32M
*/
HS_RISC_V_OPCODES_INSN_DECLARE(mul);
HS_RISC_V_OPCODES_INSN_DECLARE(mulh);
HS_RISC_V_OPCODES_INSN_DECLARE(mulhsu);
HS_RISC_V_OPCODES_INSN_DECLARE(mulhu);
HS_RISC_V_OPCODES_INSN_DECLARE(div);
HS_RISC_V_OPCODES_INSN_DECLARE(divu);
HS_RISC_V_OPCODES_INSN_DECLARE(rem);
HS_RISC_V_OPCODES_INSN_DECLARE(remu);
/*
* RV64M (RV32M新增)
*/
HS_RISC_V_OPCODES_INSN_DECLARE(mulw);
HS_RISC_V_OPCODES_INSN_DECLARE(divw);
HS_RISC_V_OPCODES_INSN_DECLARE(divuw);
HS_RISC_V_OPCODES_INSN_DECLARE(remw);
HS_RISC_V_OPCODES_INSN_DECLARE(remuw);
/*
* RV32A
*/
HS_RISC_V_OPCODES_INSN_DECLARE(lr_w);
HS_RISC_V_OPCODES_INSN_DECLARE(sc_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amoswap_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amoadd_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amoxor_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amoand_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amoor_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amomin_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amomax_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amominu_w);
HS_RISC_V_OPCODES_INSN_DECLARE(amomaxu_w);
/*
* RV64A (RV32A新增)
*/
HS_RISC_V_OPCODES_INSN_DECLARE(lr_d);
HS_RISC_V_OPCODES_INSN_DECLARE(sc_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amoswap_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amoadd_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amoxor_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amoand_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amoor_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amomin_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amomax_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amominu_d);
HS_RISC_V_OPCODES_INSN_DECLARE(amomaxu_d);
/*
* RV32F
*/
HS_RISC_V_OPCODES_INSN_DECLARE(flw);
HS_RISC_V_OPCODES_INSN_DECLARE(fsw);
HS_RISC_V_OPCODES_INSN_DECLARE(fmadd_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fmsub_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fnmsub_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fnmadd_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fadd_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fsub_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fmul_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fdiv_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fsqrt_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fsgnj_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fsgnjn_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fsgnjx_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fmin_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fmax_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_w_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_wu_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fmv_x_w);
HS_RISC_V_OPCODES_INSN_DECLARE(feq_s);
HS_RISC_V_OPCODES_INSN_DECLARE(flt_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fle_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fclass_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_s_w);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_s_wu);
HS_RISC_V_OPCODES_INSN_DECLARE(fmv_w_x);
HS_RISC_V_OPCODES_INSN_DECLARE(frflags);
HS_RISC_V_OPCODES_INSN_DECLARE(fsflags);
HS_RISC_V_OPCODES_INSN_DECLARE(fsflagsi);
HS_RISC_V_OPCODES_INSN_DECLARE(frrm);
HS_RISC_V_OPCODES_INSN_DECLARE(fsrm);
HS_RISC_V_OPCODES_INSN_DECLARE(fsrmi);
HS_RISC_V_OPCODES_INSN_DECLARE(fscsr);
HS_RISC_V_OPCODES_INSN_DECLARE(frcsr);
/*
* RV64F (RV32F新增)
*/
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_l_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_lu_s);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_s_l);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_s_lu);
/*
* RV32D
*/
HS_RISC_V_OPCODES_INSN_DECLARE(fld);
HS_RISC_V_OPCODES_INSN_DECLARE(fsd);
HS_RISC_V_OPCODES_INSN_DECLARE(fmadd_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fmsub_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fnmsub_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fnmadd_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fadd_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fsub_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fmul_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fdiv_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fsqrt_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fsgnj_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fsgnjn_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fsgnjx_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fmin_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fmax_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_s_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_d_s);
HS_RISC_V_OPCODES_INSN_DECLARE(feq_d);
HS_RISC_V_OPCODES_INSN_DECLARE(flt_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fle_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fclass_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_w_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_wu_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_d_w);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_d_wu);
/*
* RV64D (RV32D新增)
*/
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_l_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_lu_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fmv_x_d);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_d_l);
HS_RISC_V_OPCODES_INSN_DECLARE(fcvt_d_lu);
HS_RISC_V_OPCODES_INSN_DECLARE(fmv_d_x);
/*
* RVC RVC指令集与其它指令集不同
* RVC中的指令会根据具体的基本指令集不同而不同
* RVC中的指令根据最低两位的值可分为012332
*/
//象限0
HS_RISC_V_OPCODES_INSN_DECLARE(c_addi4spn);
HS_RISC_V_OPCODES_INSN_DECLARE(c_fld);
HS_RISC_V_OPCODES_INSN_DECLARE(c_lq);
HS_RISC_V_OPCODES_INSN_DECLARE(c_lw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_flw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_ld);
HS_RISC_V_OPCODES_INSN_DECLARE(c_fsd);
HS_RISC_V_OPCODES_INSN_DECLARE(c_sq);
HS_RISC_V_OPCODES_INSN_DECLARE(c_sw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_fsw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_sd);
//象限1
HS_RISC_V_OPCODES_INSN_DECLARE(c_nop);
HS_RISC_V_OPCODES_INSN_DECLARE(c_addi);
HS_RISC_V_OPCODES_INSN_DECLARE(c_jal);
HS_RISC_V_OPCODES_INSN_DECLARE(c_addiw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_li);
HS_RISC_V_OPCODES_INSN_DECLARE(c_addi16sp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_lui);
HS_RISC_V_OPCODES_INSN_DECLARE(c_srli);
HS_RISC_V_OPCODES_INSN_DECLARE(c_srli64);
HS_RISC_V_OPCODES_INSN_DECLARE(c_srai);
HS_RISC_V_OPCODES_INSN_DECLARE(c_srai64);
HS_RISC_V_OPCODES_INSN_DECLARE(c_andi);
HS_RISC_V_OPCODES_INSN_DECLARE(c_sub);
HS_RISC_V_OPCODES_INSN_DECLARE(c_xor);
HS_RISC_V_OPCODES_INSN_DECLARE(c_or);
HS_RISC_V_OPCODES_INSN_DECLARE(c_and);
HS_RISC_V_OPCODES_INSN_DECLARE(c_subw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_addw);
HS_RISC_V_OPCODES_INSN_DECLARE(c_j);
HS_RISC_V_OPCODES_INSN_DECLARE(c_beqz);
HS_RISC_V_OPCODES_INSN_DECLARE(c_bnez);
//象限2
HS_RISC_V_OPCODES_INSN_DECLARE(c_slli);
HS_RISC_V_OPCODES_INSN_DECLARE(c_slli64);
HS_RISC_V_OPCODES_INSN_DECLARE(c_fldsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_lqsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_lwsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_flwsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_ldsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_jr);
HS_RISC_V_OPCODES_INSN_DECLARE(c_mv);
HS_RISC_V_OPCODES_INSN_DECLARE(c_ebreak);
HS_RISC_V_OPCODES_INSN_DECLARE(c_jalr);
HS_RISC_V_OPCODES_INSN_DECLARE(c_add);
HS_RISC_V_OPCODES_INSN_DECLARE(c_fsdsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_sqsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_swsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_fswsp);
HS_RISC_V_OPCODES_INSN_DECLARE(c_sdsp);
struct hs_risc_v_opcodes_csr;
typedef struct hs_risc_v_opcodes_csr hs_risc_v_opcodes_csr_t;
struct hs_risc_v_opcodes_csr
{
const char *name; /**< CSR名称 */
uint16_t addr; /**< CSR地址 */
};
/** \brief 声明要使用的CSR
*
*
*/
#ifdef __cplusplus
#define HS_RISC_V_OPCODES_CSR_DECLARE(NAME) \
extern "C" const hs_risc_v_opcodes_csr_t hs_risc_v_opcodes_csr_##NAME
#else
#define HS_RISC_V_OPCODES_CSR_DECLARE(NAME) \
extern const hs_risc_v_opcodes_csr_t hs_risc_v_opcodes_csr_##NAME
#endif
/** \brief 获取CSR的名称
*
*
*/
#define HS_RISC_V_OPCODES_CSR_NAME(NAME) (hs_risc_v_opcodes_csr_##NAME)
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HS_RISC_V_OPCODES_H__

View File

@ -0,0 +1,6 @@
____ ___ __ __
| _ \ / _ \| \/ |
| |_) | | | | |\/| |
| _ <| |_| | | | |
|_| \_\\___/|_| |_|

View File

@ -0,0 +1,31 @@
#include "hbox_config.h"
#include "hbox.h"
#ifdef HRC_ENABLED
#include "hrc.h"
#endif // HRC_ENABLED
hdefaults_tick_t hbox_tick_get(void)
{
return 0;
}
void hbox_enter_critical()
{
}
void hbox_exit_critical()
{
}
void * hbox_malloc(size_t bytes)
{
return malloc(bytes);
}
void hbox_free(void *ptr)
{
free(ptr);
}

View File

@ -0,0 +1,20 @@
#ifndef __HBOX_CONFIG_H__
#define __HBOX_CONFIG_H__
#define HDEFAULTS_TICK_GET hbox_tick_get
#define HDEFAULTS_MUTEX_LOCK hbox_enter_critical
#define HDEFAULTS_MUTEX_UNLOCK hbox_exit_critical
#define HDEFAULTS_MALLOC hbox_malloc
#define HDEFAULTS_FREE hbox_free
/*
* 使
*/
#define HCPPRT_NO_ATOMIC 1
/*
* C++
*/
#define HCPPRT_USE_CTORS 1
#endif // __HBOX_CONFIG_H__

View File

@ -0,0 +1,8 @@
#include "stdio.h"
#include "stdlib.h"
int main()
{
while(true);
}

View File

@ -0,0 +1,368 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright © 2019 Keith Packard
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
ENTRY(_start)
/*
* These values should be provided by the application. We'll include
* some phony values here to make things link for testing
*/
MEMORY
{
flash (rx!w) :
ORIGIN = DEFINED(__flash) ? __flash : 0xD0000000,
LENGTH = DEFINED(__flash_size) ? __flash_size : 0x00200000
ram (w!rx) :
ORIGIN = DEFINED(__ram) ? __ram : 0x20000000,
LENGTH = DEFINED(__ram_size) ? __ram_size : 0x00002000
}
PHDRS
{
text PT_LOAD;
ram PT_LOAD;
ram_init PT_LOAD;
tls PT_TLS;
}
SECTIONS
{
PROVIDE(__stack = ORIGIN(ram) + LENGTH(ram));
/*
* 向量表
*/
.vector : {
KEEP (*(.vector))
} >flash AT>flash :text
.init : {
. = ORIGIN(flash)+0x400;
KEEP (*(.text.init.enter))
KEEP (*(.data.init.enter))
KEEP (*(SORT_BY_NAME(.init) SORT_BY_NAME(.init.*)))
KEEP (*crt0.*(.text*))
/*
* 默认中断/库函数地址
*/
. = ORIGIN(flash)+0x500;
KEEP (*(.vector.default_handler))
. = ORIGIN(flash)+0x540;
KEEP (*(.vector.trap))
. = ORIGIN(flash)+0x580;
KEEP (*(.vector.reset_handler))
} >flash AT>flash :text
.text : {
/* code */
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.* .opd .opd.*)
*(.gnu.linkonce.t.*)
KEEP (*(.fini .fini.*))
__text_end = .;
PROVIDE (__etext = __text_end);
PROVIDE (_etext = __text_end);
PROVIDE (etext = __text_end);
/* Need to pre-align so that the symbols come after padding */
. = ALIGN(8);
/* lists of constructors and destructors */
PROVIDE_HIDDEN ( __preinit_array_start = . );
KEEP (*(.preinit_array))
PROVIDE_HIDDEN ( __preinit_array_end = . );
PROVIDE_HIDDEN ( __init_array_start = . );
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array .ctors))
PROVIDE_HIDDEN ( __init_array_end = . );
PROVIDE_HIDDEN ( __fini_array_start = . );
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array .dtors))
PROVIDE_HIDDEN ( __fini_array_end = . );
} >flash AT>flash :text
.rodata : {
/* read-only data */
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >flash AT>flash :text
.data.rel.ro : {
/* data that needs relocating */
*(.data.rel.ro .data.rel.ro.*)
} >flash AT>flash :text
/*
* Needs to be in its own segment with the PLT entries first
* so that the linker will compute the offsets to those
* entries correctly.
*/
.got : {
*(.got.plt)
*(.got)
} >flash AT>flash :text
.toc : {
*(.toc .toc.*)
} >flash AT>flash :text
/* additional sections when compiling with C++ exception support */
.except_ordered : {
*(.gcc_except_table *.gcc_except_table.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >flash AT>flash :text
.eh_frame_hdr : {
PROVIDE_HIDDEN ( __eh_frame_hdr_start = . );
*(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*)
PROVIDE_HIDDEN ( __eh_frame_hdr_end = . );
} >flash AT>flash :text
.eh_frame : {
PROVIDE_HIDDEN ( __eh_frame_start = . );
KEEP (*(.eh_frame .eh_frame.*))
PROVIDE_HIDDEN ( __eh_frame_end = . );
} >flash AT>flash :text
.except_unordered : {
. = ALIGN(8);
PROVIDE(__exidx_start = .);
*(.ARM.exidx*)
PROVIDE(__exidx_end = .);
} >flash AT>flash :text
/*
* Data values which are preserved across reset
*/
.preserve (NOLOAD) : {
PROVIDE(__preserve_start__ = .);
KEEP(*(SORT_BY_NAME(.preserve.*)))
KEEP(*(.preserve))
PROVIDE(__preserve_end__ = .);
} >ram AT>ram :ram
.data : ALIGN_WITH_INPUT {
*(.data .data.*)
*(.gnu.linkonce.d.*)
/* Need to pre-align so that the symbols come after padding */
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
PROVIDE( _gp = . + 0x8000);
*(.sdata .sdata.* .sdata2.*)
*(.gnu.linkonce.s.*)
} >ram AT>flash :ram_init
PROVIDE(__data_start = ADDR(.data));
PROVIDE(__data_source = LOADADDR(.data));
/* Thread local initialized data. This gets
* space allocated as it is expected to be placed
* in ram to be used as a template for TLS data blocks
* allocated at runtime. We're slightly abusing that
* by placing the data in flash where it will be copied
* into the allocate ram addresses by the existing
* data initialization code in crt0.
* BFD includes .tbss alignment when computing .tdata
* alignment, but for ld.lld we have to explicitly pad
* as it only guarantees usage as a TLS template works
* rather than supporting this use case.
*/
.tdata : /* For ld.lld: ALIGN(__tls_align) */ ALIGN_WITH_INPUT {
*(.tdata .tdata.* .gnu.linkonce.td.*)
PROVIDE(__data_end = .);
PROVIDE(__tdata_end = .);
} >ram AT>flash :tls :ram_init
PROVIDE( __tls_base = ADDR(.tdata));
PROVIDE( __tdata_start = ADDR(.tdata));
PROVIDE( __tdata_source = LOADADDR(.tdata) );
PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
PROVIDE( __data_source_end = __tdata_source_end );
PROVIDE( __tdata_size = SIZEOF(.tdata) );
PROVIDE( __edata = __data_end );
PROVIDE( _edata = __data_end );
PROVIDE( edata = __data_end );
PROVIDE( __data_size = __data_end - __data_start );
PROVIDE( __data_source_size = __data_source_end - __data_source );
.tbss (NOLOAD) : {
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
PROVIDE( __tbss_end = . );
} >ram AT>ram :tls :ram
PROVIDE( __bss_start = ADDR(.tbss));
PROVIDE( __tbss_start = ADDR(.tbss));
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tbss_size = SIZEOF(.tbss) );
PROVIDE( __tls_size = __tls_end - __tls_base );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
/*
* Unlike ld.lld, ld.bfd does not advance the location counter for
* .tbss, but we actually need memory allocated for .tbss as we use
* it for the initial TLS storage.
* Create special section here just to make room.
*/
.tbss_space (NOLOAD) : {
. = ADDR(.tbss);
. = . + SIZEOF(.tbss);
} >ram AT>ram :ram
.bss (NOLOAD) : {
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
/* Align the heap */
. = ALIGN(8);
__bss_end = .;
} >ram AT>ram :ram
PROVIDE( __non_tls_bss_start = ADDR(.bss) );
PROVIDE( __end = __bss_end );
_end = __bss_end;
PROVIDE( end = __bss_end );
PROVIDE( __bss_size = __bss_end - __bss_start );
/* Make the rest of memory available for heap storage */
PROVIDE (__heap_start = __end);
PROVIDE (__heap_end = __stack - (DEFINED(__stack_size) ? __stack_size : 0x00001000));
PROVIDE (__heap_size = __heap_end - __heap_start);
/* Allow a minimum heap size to be specified */
.heap (NOLOAD) : {
. += (DEFINED(__heap_size_min) ? __heap_size_min : 0);
} >ram :ram
/* Define a stack region to make sure it fits in memory */
.stack (NOLOAD) : {
. += (DEFINED(__stack_size) ? __stack_size : 0x00001000);
} >ram :ram
/* Throw away C++ exception handling information */
/*
/DISCARD/ : {
*(.note .note.*)
*(.eh_frame .eh_frame.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
*(.ARM.exidx*)
}
*/
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1. */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions. */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2. */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2. */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3. */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF 5. */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.debug_sup 0 : { *(.debug_sup) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
}
/*
* Check that sections that are copied from flash to RAM have matching
* padding, so that a single memcpy() of __data_size copies the correct bytes.
*/
ASSERT( __data_size == __data_source_size,
"ERROR: .data/.tdata flash size does not match RAM size");

View File

@ -0,0 +1,90 @@
cmake_minimum_required(VERSION 3.20)
include("${CMAKE_CURRENT_SOURCE_DIR}/../toolchain.cmake")
set(PROJECT_NAME rom)
project(${PROJECT_NAME} C CXX ASM)
file(GLOB C_CXX_FILES ../*.h ../*.c ../*.cpp *.h *.c *.cpp)
if(${PICOLIBC})
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} \
-march=rv32i\
-mabi=ilp32\
-std=gnu11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=picolibcpp.specs\
")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} \
-march=rv32i\
-mabi=ilp32\
-std=gnu++11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=picolibcpp.specs\
")
set(CMAKE_EXE_LINKER_FLAGS " ${CMAKE_EXE_LINKER_FLAGS}\
-march=rv32i\
-mabi=ilp32\
-nostdlib++\
-T${CMAKE_CURRENT_SOURCE_DIR}/../rom.ld\
-Wl,--gc-sections \
-Wl,-Map,${PROJECT_NAME}.map\
")
endif()
if(${NEWLIB})
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} \
-march=rv32i\
-mabi=ilp32\
-std=gnu11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=nano.specs\
")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} \
-march=rv32i\
-mabi=ilp32\
-std=gnu++11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=nano.specs\
")
set(CMAKE_EXE_LINKER_FLAGS " ${CMAKE_EXE_LINKER_FLAGS}\
-march=rv32i\
-mabi=ilp32\
-nostdlib++\
-T${CMAKE_CURRENT_SOURCE_DIR}/../rom.ld\
-Wl,--gc-sections \
-Wl,-Map,${PROJECT_NAME}.map\
")
endif()
add_definitions(
-DHBOX_CONFIG_HEADER=hbox_config.h
)
add_executable(${PROJECT_NAME} ${C_CXX_FILES})
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/
${CMAKE_CURRENT_SOURCE_DIR}/../
)
#HRCfs
set(HRC_FS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../fs/)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../hbox HBox EXCLUDE_FROM_ALL)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../hrc HRC EXCLUDE_FROM_ALL)
#HBoxHRC
hbox_enable(${PROJECT_NAME})
hrc_enable(${PROJECT_NAME})
add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${PROJECT_NAME}.elf
COMMAND ${CMAKE_OBJCOPY} --verbose -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

View File

@ -0,0 +1,120 @@
#include "hbox.h"
#include "stdint.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
__WEAK __SECTION(".vector.default_handler") void vector_table_default_handler();
__WEAK __SECTION(".vector.trap") void vector_table_trap();
__WEAK __SECTION(".vector.reset_handler") __attribute__((naked)) void vector_table_reset_handler();
extern const uint32_t vector_table[256] __SECTION(".vector");
#ifdef __cplusplus
}
#endif // __cplusplus
/*
* .
*/
const uint32_t vector_table[256] __SECTION(".vector") =
{
/*
* 64,16RISV-V标准保留
*/
(uint32_t)(uintptr_t)vector_table_trap, //陷入函数
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_reset_handler, //复位中断
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
(uint32_t)(uintptr_t)vector_table_default_handler,
/*
* ,
*/
};
/*
*
*/
__WEAK __SECTION(".vector.default_handler") void vector_table_default_handler()
{
while(true);
}
/*
*
*/
__WEAK __SECTION(".vector.trap") void vector_table_trap()
{
while(true);
}
/*
*
*/
extern "C" void _start();
__WEAK __SECTION(".vector.reset_handler") __attribute__((naked)) void vector_table_reset_handler()
{
_start();
while(true);
}

View File

@ -0,0 +1,90 @@
cmake_minimum_required(VERSION 3.20)
include("${CMAKE_CURRENT_SOURCE_DIR}/../toolchain.cmake")
set(PROJECT_NAME rom)
project(${PROJECT_NAME} C CXX ASM)
file(GLOB C_CXX_FILES ../*.h ../*.c ../*.cpp *.h *.c *.cpp)
if(${PICOLIBC})
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} \
-march=rv64i\
-mabi=lp64\
-std=gnu11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=picolibcpp.specs\
")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} \
-march=rv64i\
-mabi=lp64\
-std=gnu++11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=picolibcpp.specs\
")
set(CMAKE_EXE_LINKER_FLAGS " ${CMAKE_EXE_LINKER_FLAGS}\
-march=rv64i\
-mabi=lp64\
-nostdlib++\
-T${CMAKE_CURRENT_SOURCE_DIR}/../rom.ld\
-Wl,--gc-sections \
-Wl,-Map,${PROJECT_NAME}.map\
")
endif()
if(${NEWLIB})
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} \
-march=rv64i\
-mabi=lp64\
-std=gnu11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=nano.specs\
")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} \
-march=rv64i\
-mabi=lp64\
-std=gnu++11\
-fPIC\
-ffunction-sections\
-fdata-sections\
--specs=nano.specs\
")
set(CMAKE_EXE_LINKER_FLAGS " ${CMAKE_EXE_LINKER_FLAGS}\
-march=rv64i\
-mabi=lp64\
-nostdlib++\
-T${CMAKE_CURRENT_SOURCE_DIR}/../rom.ld\
-Wl,--gc-sections \
-Wl,-Map,${PROJECT_NAME}.map\
")
endif()
add_definitions(
-DHBOX_CONFIG_HEADER=hbox_config.h
)
add_executable(${PROJECT_NAME} ${C_CXX_FILES})
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/
${CMAKE_CURRENT_SOURCE_DIR}/../
)
#HRCfs
set(HRC_FS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../fs/)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../hbox HBox EXCLUDE_FROM_ALL)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../hrc HRC EXCLUDE_FROM_ALL)
#HBoxHRC
hbox_enable(${PROJECT_NAME})
hrc_enable(${PROJECT_NAME})
add_custom_command(TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${PROJECT_NAME}.elf
COMMAND ${CMAKE_OBJCOPY} --verbose -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

View File

@ -0,0 +1,125 @@
#include "hbox.h"
#include "stdint.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
__WEAK __SECTION(".vector.default_handler") void vector_table_default_handler();
__WEAK __SECTION(".vector.trap") void vector_table_trap();
__WEAK __SECTION(".vector.reset_handler") __attribute__((naked)) void vector_table_reset_handler();
extern const uint32_t vector_table[256] __SECTION(".vector");
#ifdef __cplusplus
}
#endif // __cplusplus
const uint32_t vector_table_default_handler_address = 0xD0000500; /*此值在链接脚本中定义*/
const uint32_t vector_table_trap_address = 0xD0000540; /*此值在链接脚本中定义*/
const uint32_t vector_table_reset_handler_address = 0xD0000580; /*此值在链接脚本中定义*/
/*
* ..64RISC-V使
*/
const uint32_t vector_table[256] __SECTION(".vector") =
{
/*
* 64,16RISV-V标准保留
*/
(uint32_t)(uintptr_t)vector_table_trap_address, //陷入函数
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_reset_handler_address, //复位中断
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
(uint32_t)(uintptr_t)vector_table_default_handler_address,
/*
* ,
*/
};
/*
*
*/
__WEAK __SECTION(".vector.default_handler") void vector_table_default_handler()
{
while(true);
}
/*
*
*/
__WEAK __SECTION(".vector.trap") void vector_table_trap()
{
while(true);
}
/*
*
*/
extern "C" void _start();
__WEAK __SECTION(".vector.reset_handler") __attribute__((naked)) void vector_table_reset_handler()
{
_start();
while(true);
}

View File

@ -0,0 +1,127 @@
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
char *__env[1] = { 0 };
char **environ = __env;
int _getpid(void)
{
return 1;
}
int _kill(int pid, int sig)
{
errno = EINVAL;
return -1;
}
void _exit (int status)
{
while (1) {} /* Make sure we hang here */
}
__attribute__((weak)) int _read(int file, char *ptr, int len)
{
if(ptr==NULL)
{
return 0;
}
if(file==0)
{
return 0;
}
return 0;
}
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
if(ptr==NULL)
{
return 0;
}
if(file==1 || file == 2)
{
return 0;
}
return 0;
}
int _close(int file)
{
return -1;
}
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int _isatty(int file)
{
return 1;
}
int _lseek(int file, int ptr, int dir)
{
return 0;
}
int _open(char *path, int flags, ...)
{
/* Pretend like we always fail */
return -1;
}
int _wait(int *status)
{
errno = ECHILD;
return -1;
}
int _unlink(char *name)
{
errno = ENOENT;
return -1;
}
int _stat(char *file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int _link(char *old, char *new)
{
errno = EMLINK;
return -1;
}
int _fork(void)
{
errno = EAGAIN;
return -1;
}
int _execve(char *name, char **argv, char **env)
{
errno = ENOMEM;
return -1;
}

View File

@ -0,0 +1,29 @@
#include <errno.h>
#include <stdint.h>
#include <stddef.h>
/**
* Pointer to the current high watermark of the heap usage
*/
static uint8_t __attribute__((unused)) *__sbrk_heap_end = NULL;
/**
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
* and others from the C library
*
* @verbatim
*
* This implementation starts allocating at the '_end' linker symbol
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
* The implementation considers '_estack' linker symbol to be RAM end
* NOTE: If the MSP stack, at any point during execution, grows larger than the
* reserved size, please increase the '_Min_Stack_Size'.
*
* @param incr Memory size
* @return Pointer to allocated memory
*/
void *_sbrk(ptrdiff_t incr)
{
errno = ENOMEM;
return (void *)-1;
}

View File

@ -0,0 +1,51 @@
cmake_minimum_required(VERSION 3.20)
#riscv64-unknown-elf-gcc
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv64-unknown-elf-gcc)
set(CMAKE_ASM_COMPILER riscv64-unknown-elf-gcc)
set(CMAKE_CXX_COMPILER riscv64-unknown-elf-g++)
set(CMAKE_ADDR2LINE riscv64-unknown-elf-addr2line)
set(CMAKE_AR riscv64-unknown-elf-ar)
set(CMAKE_RANLIB riscv64-unknown-elf-ranlib)
set(CMAKE_CXX_COMPILER_AR riscv64-unknown-elf-ar)
set(CMAKE_CXX_COMPILER_RANLIB riscv64-unknown-elf-ranlib)
set(CMAKE_C_COMPILER_AR riscv64-unknown-elf-ar)
set(CMAKE_C_COMPILER_RANLIB riscv64-unknown-elf-ranlib)
set(CMAKE_Fortran_COMPILER riscv64-unknown-elf-gfortan)
set(CMAKE_OBJCOPY riscv64-unknown-elf-objcopy)
set(CMAKE_OBJDUMP riscv64-unknown-elf-objdump)
set(CMAKE_RC_COMPILER riscv64-unknown-elf-windres)
set(CMAKE_READELF riscv64-unknown-elf-readelf)
set(CMAKE_SIZE riscv64-unknown-elf-size)
set(CMAKE_STRIP riscv64-unknown-elf-strip)
set(CMAKE_LINKER riscv64-unknown-elf-ld)
set(CMAKE_EXECUTABLE_SUFFIX_ASM .elf)
set(CMAKE_EXECUTABLE_SUFFIX_C .elf)
set(CMAKE_EXECUTABLE_SUFFIX_CXX .elf)
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
execute_process( COMMAND ${CMAKE_C_COMPILER} --version
OUTPUT_QUIET
COMMAND_ERROR_IS_FATAL ANY
)
execute_process( COMMAND ${CMAKE_C_COMPILER} -specs=picolibcpp.specs --version
RESULT_VARIABLE PICOLIBCPP_SPECS_TEST_CODE
OUTPUT_QUIET
ERROR_QUIET
)
if("${PICOLIBCPP_SPECS_TEST_CODE}" EQUAL "0")
message(STATUS "libc using picolibc!")
set(PICOLIBC TRUE)
else()
execute_process( COMMAND ${CMAKE_C_COMPILER} -specs=nano.specs --version
RESULT_VARIABLE NANO_SPECS_TEST_CODE
OUTPUT_QUIET
ERROR_QUIET
)
if("${NANO_SPECS_TEST_CODE}" EQUAL "0")
message(STATUS "libc using newlib!")
set(NEWLIB TRUE)
else()
message(FATAL_ERROR "libc not support!")
endif()
endif()

View File

@ -0,0 +1,28 @@
/***************************************************************
* Name: rp_pio.h
* Purpose: rp_pio接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-16
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HSIMLULATOR_RP_PIO_H__
#define __HSIMLULATOR_RP_PIO_H__
#include "stdbool.h"
#include "stdint.h"
#include "stdlib.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#include "rp_pio_sm.h"
#include "rp_pio_rom.h"
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HSIMLULATOR_RP_PIO_H__

View File

@ -0,0 +1,83 @@
/***************************************************************
* Name: rp_pio_rom.c
* Purpose: rp_pio_rom接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-16
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#include "rp_pio_rom.h"
/** \brief 程序主要将TX FIFO中的数据无数据则stall中的最低位通过PINS发送出去。。
*
* loop:
* pull
* out pins, 1
* jmp loop
*
*/
const hs_rp_pio_sm_memory_t hs_rp_pio_sm_rom_hello_pio=
{
{
0x80a0, // 0: pull block
0x6001, // 1: out pins, 1
0x0000 // 2: jmp 0
},
{
0,
0,
1,
1,
0,
0,
0,
0
}
};
static bool hs_rp_pio_hello_pio_io_process(hs_rp_pio_sm_t *sm,hs_rp_pio_sm_io_opt_t opt,uint32_t *val,void *usr)
{
hs_rp_pio_hello_pio_t *pio=(hs_rp_pio_hello_pio_t *)sm;
if(pio->io!=NULL)
{
pio->io(pio,(hs_rp_pio_sm_hello_pio_io_opt_t)(int)opt,val,usr);
}
return true;
}
void hs_rp_pio_hello_pio_init(hs_rp_pio_hello_pio_t *pio,hs_rp_pio_hello_pio_io_t hook,void *usr)
{
if(pio==NULL)
{
return;
}
pio->io=hook;
hs_rp_pio_init(&pio->pio,hs_rp_pio_hello_pio_io_process,usr);
pio->pio.memory=hs_rp_pio_sm_rom_hello_pio;
}
void hs_rp_pio_hello_pio_tick(hs_rp_pio_hello_pio_t* pio,size_t cycles)
{
if(pio!=NULL)
{
hs_rp_pio_tick(&pio->pio,cycles);
}
}
void hs_rp_pio_hello_pio_reset(hs_rp_pio_hello_pio_t *pio)
{
if(pio!=NULL)
{
hs_rp_pio_reset(&pio->pio);
}
}
bool hs_rp_pio_hello_pio_push(hs_rp_pio_hello_pio_t *pio,uint32_t data)
{
if(pio!=NULL)
{
return hs_rp_pio_push(&pio->pio,data);
}
return false;
}

View File

@ -0,0 +1,90 @@
/***************************************************************
* Name: rp_pio_rom.h
* Purpose: rp_pio_rom接口
* Author: HYH (hyhsystem.cn)
* Created: 2025-02-16
* Copyright: HYH (hyhsystem.cn)
* License: MIT
**************************************************************/
#ifndef __HSIMLULATOR_RP_PIO_ROM_H__
#define __HSIMLULATOR_RP_PIO_ROM_H__
#include "stdbool.h"
#include "stdint.h"
#include "stdlib.h"
#include "rp_pio_sm.h"
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/** \brief 程序主要将TX FIFO中的数据无数据则stall中的最低位通过PINS发送出去。
*
* loop:
* pull
* out pins, 1
* jmp loop
*
*/
extern const hs_rp_pio_sm_memory_t hs_rp_pio_sm_rom_hello_pio;
struct hs_rp_pio_hello_pio;
typedef struct hs_rp_pio_hello_pio hs_rp_pio_hello_pio_t;
typedef enum
{
HS_RP_PIO_SM_HELLO_PIO_IO_RESET = HS_RP_PIO_SM_IO_RESET,
HS_RP_PIO_SM_HELLO_PIO_IO_WRITE_PINS = HS_RP_PIO_SM_IO_WRITE_PINS,
} hs_rp_pio_sm_hello_pio_io_opt_t;
typedef bool (*hs_rp_pio_hello_pio_io_t)(hs_rp_pio_hello_pio_t *sm,hs_rp_pio_sm_hello_pio_io_opt_t opt,uint32_t *val,void *usr);
struct hs_rp_pio_hello_pio
{
hs_rp_pio_t pio;
hs_rp_pio_hello_pio_io_t io;
};
/** \brief hello_pio PIO初始化
*
* \param pio hs_rp_pio_hello_pio_t* hello_pio pio指针
* \param hook hs_rp_pio_hello_pio_io_t Hook函数
* \param usr void*
*
*/
void hs_rp_pio_hello_pio_init(hs_rp_pio_hello_pio_t *pio,hs_rp_pio_hello_pio_io_t hook,void *usr);
/** \brief hello_pio PIO节拍,由于pio对时序要求比较高推荐在定时器中调用此函数。注意此函数不是线程安全的必要时需要加锁。
*
* \param pio hs_rp_pio_hello_pio_t* hello_pio pio指针
* \param cycles size_t ,0,使1使
*
*/
void hs_rp_pio_hello_pio_tick(hs_rp_pio_hello_pio_t* pio,size_t cycles);
/** \brief hello_pio PIO复位(恢复默认状态与配置),注意:此函数不是线程安全的,必要时需要加锁。
*
* \param pio hs_rp_pio_hello_pio_t* hello_pio pio指针
*
*/
void hs_rp_pio_hello_pio_reset(hs_rp_pio_hello_pio_t *pio);
/** \brief hello_pio PIO PUSH数据注意此函数不是线程安全的必要时需要加锁。
*
* \param pio hs_rp_pio_hello_pio_t* hello_pio pio指针
* \param data uint32_t
* \return bool
*
*/
bool hs_rp_pio_hello_pio_push(hs_rp_pio_hello_pio_t *pio,uint32_t data);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __HSIMLULATOR_RP_PIO_ROM_H__

View File

@ -1795,29 +1795,4 @@ bool hs_rp_pio_rxfifo_get(hs_rp_pio_t *pio,uint32_t addr,uint32_t* data)
return false;
}
/** \brief 程序主要将TX FIFO中的数据无数据则stall中的最低位通过PINS发送出去。。
*
* loop:
* pull
* out pins, 1
* jmp loop
*
*/
const hs_rp_pio_sm_memory_t hs_rp_pio_sm_program_simple_pins_out=
{
{
0x80a0, // 0: pull block
0x6001, // 1: out pins, 1
0x0000 // 2: jmp 0
},
{
0,
0,
1,
1,
0,
0,
0,
0
}
};

View File

@ -26,6 +26,15 @@ typedef struct hs_rp_pio_sm hs_rp_pio_sm_t;
*/
size_t hs_rp_pio_sm_size(void);
#ifndef HS_RP_PIO_SM_SIZE
/** \brief hs_rp_pio_sm_t结构体大小,一般用于静态分配,注意:可能大于hs_rp_pio_sm_size()返回的值。
*
*
*/
#define HS_RP_PIO_SM_SIZE() ((((sizeof(uintptr_t)*2+sizeof(uint32_t)*6)/sizeof(uint32_t))+(((sizeof(uintptr_t)*2+sizeof(uint32_t)*6)%sizeof(uint32_t))?1:0))*sizeof(uint32_t))
#endif // HS_RP_PIO_SM_SIZE
typedef enum
{
HS_RP_PIO_SM_IO_RESET,//IO复位无参数
@ -327,7 +336,7 @@ void hs_rp_pio_sm_load_memory_cfg(hs_rp_pio_sm_t *sm,hs_rp_pio_sm_fifo_t *sm_rxf
typedef struct
{
uint32_t sm[((sizeof(uintptr_t)*2+sizeof(uint32_t)*6)/sizeof(uint32_t))+(((sizeof(uintptr_t)*2+sizeof(uint32_t)*6)%sizeof(uint32_t))?1:0)];
uint32_t sm[HS_RP_PIO_SM_SIZE()/sizeof(uint32_t)];
hs_rp_pio_sm_memory_t memory; //程序内存
hs_rp_pio_sm_fifo_t txfifo; //用户可使用hs_rp_pio_sm_fifo_push向状态机写入数据。
hs_rp_pio_sm_fifo_t rxfifo; //用户可使用hs_rp_pio_sm_fifo_pull读取状态机的数据。对于某些程序而言,可直接访问fifo内的字。
@ -406,20 +415,11 @@ bool hs_rp_pio_rxfifo_set(hs_rp_pio_t *pio,uint32_t addr,uint32_t data);
bool hs_rp_pio_rxfifo_get(hs_rp_pio_t *pio,uint32_t addr,uint32_t* data);
/** \brief 程序主要将TX FIFO中的数据无数据则stall中的最低位通过PINS发送出去。
*
* loop:
* pull
* out pins, 1
* jmp loop
*
*/
extern const hs_rp_pio_sm_memory_t hs_rp_pio_sm_program_simple_pins_out;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __RP_PIO_SM_H__
#endif // __HSIMLULATOR_RP_PIO_SM_H__

View File

@ -630,6 +630,7 @@ static class HCPPGuiDriver
public:
bool fill_rectangle(hgui_driver_t *driver,size_t x,size_t y,size_t w,size_t h,hgui_pixel_t pixel)
{
(void)driver;
std::lock_guard<std::recursive_mutex> lock(m_lock);
if(screen!=NULL)
{
@ -659,6 +660,7 @@ public:
}
bool reset(hgui_driver_t *driver)
{
(void)driver;
std::lock_guard<std::recursive_mutex> lock(m_lock);
if((SDL_WasInit(SDL_INIT_EVERYTHING)&SDL_INIT_VIDEO)==0)
{
@ -685,6 +687,7 @@ public:
}
bool is_ok(hgui_driver_t *driver)
{
(void)driver;
std::lock_guard<std::recursive_mutex> lock(m_lock);
return screen!=NULL;
}
@ -696,6 +699,7 @@ public:
}
bool resize(hgui_driver_t *driver,ssize_t *w,ssize_t *h)
{
(void)driver;
std::lock_guard<std::recursive_mutex> lock(m_lock);
if(w==NULL || h == NULL)
{

View File

@ -21,10 +21,10 @@ src += Glob('*.cpp')
CPPPATH = [
cwd,
]
LIBS=[]
if sys.platform.startswith("win32"):
LIBS += ["ws2_32"]
LIBS=[]
if sys.platform.startswith("win32") or sys.platform.startswith("cygwin"):
LIBS += ["ws2_32"]
group = DefineGroup('HCPPBox', src, depend = [''], CPPPATH = CPPPATH,LIBS=LIBS)