Read registers from VB
This commit is contained in:
		
							parent
							
								
									bf969e72b4
								
							
						
					
					
						commit
						294324fe28
					
				
							
								
								
									
										15
									
								
								client.c
								
								
								
								
							
							
						
						
									
										15
									
								
								client.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
#include <client.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -193,6 +194,20 @@ bool rdb_client_write_str_hex(RdbClient *self, const char *str) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value) {
 | 
			
		||||
    char hi, lo;
 | 
			
		||||
    return char_to_hex_digits(value, &hi, &lo)
 | 
			
		||||
        && write_char(self, hi)
 | 
			
		||||
        && write_char(self, lo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value) {
 | 
			
		||||
    return rdb_client_write_i8_hex(self, (uint8_t) value)
 | 
			
		||||
        && rdb_client_write_i8_hex(self, (uint8_t) (value >> 8))
 | 
			
		||||
        && rdb_client_write_i8_hex(self, (uint8_t) (value >> 16))
 | 
			
		||||
        && rdb_client_write_i8_hex(self, (uint8_t) (value >> 24));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rdb_client_send_packet(RdbClient *self) {
 | 
			
		||||
    if (self->len + 3 > RDB_CLIENT_BUFLEN) {
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#define RDBSERVER_CLIENT_H_
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +21,8 @@ ssize_t rdb_client_read(RdbClient *self, char *buf, size_t len);
 | 
			
		|||
void rdb_client_begin_packet(RdbClient *self);
 | 
			
		||||
bool rdb_client_write_str(RdbClient *self, const char *str);
 | 
			
		||||
bool rdb_client_write_str_hex(RdbClient *self, const char *str);
 | 
			
		||||
bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value);
 | 
			
		||||
bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value);
 | 
			
		||||
int rdb_client_send_packet(RdbClient *self);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										163
									
								
								main.c
								
								
								
								
							
							
						
						
									
										163
									
								
								main.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,9 +1,11 @@
 | 
			
		|||
#include <client.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <vb.h>
 | 
			
		||||
 | 
			
		||||
const size_t BUFLEN = 8096;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -40,9 +42,40 @@ const char* REGISTERS[] = {
 | 
			
		|||
    "name:r29;bitsize:32;offset:116;encoding:uint;format:hex;set:General Purpose Registers;dwarf:0",
 | 
			
		||||
    "name:r30;bitsize:32;offset:120;encoding:uint;format:hex;set:General Purpose Registers;dwarf:0",
 | 
			
		||||
    "name:lp;alt-name:r31;bitsize:32;offset:124;encoding:uint;format:hex;set:General Purpose Registers;dwarf:0;generic:ra",
 | 
			
		||||
    "name:pc;bitsize:32;offset:128;encoding:uint;format:hex;set:Special Registers;dwarf:0;generic:pc",
 | 
			
		||||
    "name:eipc;alt-name:sr0;bitsize:32;offset:128;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:eipsw;alt-name:sr1;bitsize:32;offset:132;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:fepc;alt-name:sr2;bitsize:32;offset:136;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:fepsw;alt-name:sr3;bitsize:32;offset:140;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:ecr;alt-name:sr4;bitsize:32;offset:144;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:psw;alt-name:sr5;bitsize:32;offset:148;encoding:uint;format:hex;set:Special Registers;dwarf:0;generic:flags",
 | 
			
		||||
    "name:pir;alt-name:sr6;bitsize:32;offset:152;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:tkcw;alt-name:sr7;bitsize:32;offset:156;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:chcw;alt-name:sr24;bitsize:32;offset:160;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:adtre;alt-name:sr25;bitsize:32;offset:164;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:sr29;bitsize:32;offset:168;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:sr30;bitsize:32;offset:172;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:sr31;bitsize:32;offset:176;encoding:uint;format:hex;set:Special Registers;dwarf:0",
 | 
			
		||||
    "name:pc;bitsize:32;offset:180;encoding:uint;format:hex;set:Special Registers;dwarf:0;generic:pc",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint32_t SYSTEM_REGISTERS[] = {
 | 
			
		||||
    VB_EIPC,
 | 
			
		||||
    VB_EIPSW,
 | 
			
		||||
    VB_FEPC,
 | 
			
		||||
    VB_FEPSW,
 | 
			
		||||
    VB_ECR,
 | 
			
		||||
    VB_PSW,
 | 
			
		||||
    VB_PIR,
 | 
			
		||||
    VB_TKCW,
 | 
			
		||||
    VB_CHCW,
 | 
			
		||||
    VB_ADTRE,
 | 
			
		||||
    29,
 | 
			
		||||
    30,
 | 
			
		||||
    31,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char PC_INDEX = 32 + 13;
 | 
			
		||||
 | 
			
		||||
bool read_hex_digit(char digit, char *out) {
 | 
			
		||||
    if (digit >= '0' && digit <= '9') {
 | 
			
		||||
        *out = digit - '0';
 | 
			
		||||
| 
						 | 
				
			
			@ -78,11 +111,23 @@ bool read_hex_byte(char *buf, char *val) {
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
 | 
			
		||||
bool read_hex_i32(char *buf, int32_t *val) {
 | 
			
		||||
    char byte;
 | 
			
		||||
    *val = 0;
 | 
			
		||||
    for (int i = 0; i < 8; i += 2) {
 | 
			
		||||
        if (!read_hex_byte(buf + i, &byte)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        *val |= ((int32_t) (uint8_t) byte) << i;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int handle_command(RdbClient *client, char *cmd, size_t cmdlen, VB *sim) {
 | 
			
		||||
    rdb_client_begin_packet(client);
 | 
			
		||||
 | 
			
		||||
    if (!strncmp(cmd, "\x03", cmdlen)) {
 | 
			
		||||
        rdb_client_write_str(client, "T05thread:p1.t1;threads:p1.t1;thread-pcs:07000000;00:00000000;01:00000001;20;07000000");
 | 
			
		||||
        rdb_client_write_str(client, "T05thread:p1.t1;threads:p1.t1");
 | 
			
		||||
        return rdb_client_send_packet(client);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +167,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
 | 
			
		|||
        } else {
 | 
			
		||||
            if (!read_hex_byte(cmd + 13, ®)) return 1;
 | 
			
		||||
        }
 | 
			
		||||
        if (reg < 33) {
 | 
			
		||||
        if (reg <= PC_INDEX) {
 | 
			
		||||
            rdb_client_write_str(client, REGISTERS[(size_t) reg]);
 | 
			
		||||
        }
 | 
			
		||||
        return rdb_client_send_packet(client);
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +192,53 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
 | 
			
		|||
        return rdb_client_send_packet(client);
 | 
			
		||||
    }
 | 
			
		||||
    if (!strncmp(cmd, "p", 1)) {
 | 
			
		||||
        rdb_client_write_str(client, "00000000");
 | 
			
		||||
        char reg_no;
 | 
			
		||||
        if (cmd[2] == ';') {
 | 
			
		||||
            if (!read_hex_digit(cmd[1], ®_no)) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (!read_hex_byte(cmd + 1, ®_no)) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        int32_t reg_value;
 | 
			
		||||
        if (reg_no == PC_INDEX) {
 | 
			
		||||
            reg_value = vbGetProgramCounter(sim);
 | 
			
		||||
        } else if (reg_no > 31) {
 | 
			
		||||
            reg_value = vbGetSystemRegister(sim, SYSTEM_REGISTERS[reg_no - 32]);
 | 
			
		||||
        } else {
 | 
			
		||||
            reg_value = vbGetProgramRegister(sim, reg_no);
 | 
			
		||||
        }
 | 
			
		||||
        rdb_client_write_i32_hex(client, reg_value);
 | 
			
		||||
        return rdb_client_send_packet(client);
 | 
			
		||||
    }
 | 
			
		||||
    if (!strncmp(cmd, "P", 1)) {
 | 
			
		||||
        char reg_no;
 | 
			
		||||
        int32_t reg_value;
 | 
			
		||||
        if (cmd[2] == '=') {
 | 
			
		||||
            if (!read_hex_digit(cmd[1], ®_no)) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
            if (!read_hex_i32(cmd + 3, ®_value)) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (!read_hex_byte(cmd + 1, ®_no)) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
            if (!read_hex_i32(cmd + 4, ®_value)) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (reg_no == PC_INDEX) {
 | 
			
		||||
            vbSetProgramCounter(sim, reg_value);
 | 
			
		||||
        } else if (reg_no > 31) {
 | 
			
		||||
            vbSetSystemRegister(sim, SYSTEM_REGISTERS[reg_no - 32], reg_value);
 | 
			
		||||
        } else {
 | 
			
		||||
            vbSetProgramRegister(sim, reg_no, reg_value);
 | 
			
		||||
        }
 | 
			
		||||
        rdb_client_write_str(client, "OK");
 | 
			
		||||
        return rdb_client_send_packet(client);
 | 
			
		||||
    }
 | 
			
		||||
    if (!strncmp(cmd, "Hc-1", 1)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +250,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
 | 
			
		|||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (!strncmp(cmd, "?", cmdlen)) {
 | 
			
		||||
        rdb_client_write_str(client, "T00thread:p1.t1;threads:p1.t1;thread-pcs:00000007;");
 | 
			
		||||
        rdb_client_write_str(client, "T00thread:p1.t1;threads:p1.t1;");
 | 
			
		||||
        return rdb_client_send_packet(client);
 | 
			
		||||
    }
 | 
			
		||||
    if (!strncmp(cmd, "qMemoryRegionInfo:", 18)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +299,7 @@ int handle_command(RdbClient *client, char *cmd, size_t cmdlen) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int server(int connfd) {
 | 
			
		||||
int server(int connfd, VB *sim) {
 | 
			
		||||
    RdbClient client;
 | 
			
		||||
    rdb_client_init(&client, connfd);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +315,7 @@ int server(int connfd) {
 | 
			
		|||
        } else {
 | 
			
		||||
            printf("received command \"%.*s\"\n", (int) len, buf);
 | 
			
		||||
            fflush(stdout);
 | 
			
		||||
            int res = handle_command(&client, buf, len);
 | 
			
		||||
            int res = handle_command(&client, buf, len, sim);
 | 
			
		||||
            if (res != 0) {
 | 
			
		||||
                return res;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -232,15 +323,63 @@ int server(int connfd) {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int readROM(VB *sim, char *filename) {
 | 
			
		||||
    FILE *file = fopen(filename, "rb");
 | 
			
		||||
    long size;
 | 
			
		||||
 | 
			
		||||
    if (!file) {
 | 
			
		||||
        perror("could not open file");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fseek(file, 0, SEEK_END)) {
 | 
			
		||||
        perror("could not seek file end");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    size = ftell(file);
 | 
			
		||||
    if (size == -1) {
 | 
			
		||||
        perror("could not read file size");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (fseek(file, 0, SEEK_SET)) {
 | 
			
		||||
        perror("could not seek file start");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sim->cart.rom     = malloc(size);
 | 
			
		||||
    sim->cart.romMask = size - 1;
 | 
			
		||||
 | 
			
		||||
    fread(sim->cart.rom, 1, size, file);
 | 
			
		||||
    if (ferror(file)) {
 | 
			
		||||
        perror("could not read file");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (fclose(file)) {
 | 
			
		||||
        perror("could not close file");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv) {
 | 
			
		||||
    if (argc < 2) {
 | 
			
		||||
        fprintf(stderr, "Please pass a ROM file\n");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    VB sim;
 | 
			
		||||
    if (readROM(&sim, argv[1])) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    vbSetProgramCounter(&sim, 0x07000000);
 | 
			
		||||
 | 
			
		||||
    short port;
 | 
			
		||||
    if (argc > 1) {
 | 
			
		||||
    if (argc > 2) {
 | 
			
		||||
        char *end;
 | 
			
		||||
        port = (short) strtol(argv[1], &end, 10);
 | 
			
		||||
        if (argv[1] == end) {
 | 
			
		||||
        port = (short) strtol(argv[2], &end, 10);
 | 
			
		||||
        if (argv[2] == end) {
 | 
			
		||||
            perror("could not parse port");
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +418,7 @@ int main(int argc, char** argv) {
 | 
			
		|||
    }
 | 
			
		||||
    printf("connected\n");
 | 
			
		||||
 | 
			
		||||
    int response = server(connfd);
 | 
			
		||||
    int response = server(connfd, &sim);
 | 
			
		||||
    return close(connfd)
 | 
			
		||||
        || close(fd)
 | 
			
		||||
        || response;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue