feature: a lot of stuff and got to a working command line ish
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -112,3 +112,4 @@ modules.xml
|
|||||||
# End of https://www.toptal.com/developers/gitignore/api/cmake,jetbrains+all
|
# End of https://www.toptal.com/developers/gitignore/api/cmake,jetbrains+all
|
||||||
|
|
||||||
*.old
|
*.old
|
||||||
|
**/__pycache__
|
||||||
@@ -7,31 +7,142 @@
|
|||||||
#include <drivers/ports.h>
|
#include <drivers/ports.h>
|
||||||
#include <cpu/isr.h>
|
#include <cpu/isr.h>
|
||||||
#include <libc/libc.h>
|
#include <libc/libc.h>
|
||||||
|
#include <libc/stdbool.h>
|
||||||
|
#include <libc/ringqueue.h>
|
||||||
|
#include <mem/mem.h>
|
||||||
|
|
||||||
char scancodes_ascii[] = {
|
|
||||||
0, 0,
|
const char scancode_map_lowercase[] = {
|
||||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
|
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||||
0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
'o', 'p', '[', ']', 0, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c',
|
||||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
|
'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
'*',
|
|
||||||
0, ' ',
|
|
||||||
0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F1-F10
|
|
||||||
0, 0,
|
|
||||||
'7', '8', '9', '-',
|
|
||||||
'4', '5', '6', '+',
|
|
||||||
'1', '2', '3',
|
|
||||||
'0', 0,
|
|
||||||
0, // sysrq
|
|
||||||
0, 0, // weird
|
|
||||||
0, 0, // F11 F12
|
|
||||||
// weid
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char scancode_map_uppercase[] = {
|
||||||
|
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
||||||
|
'O', 'P', '{', '}', 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C',
|
||||||
|
'V', 'B', 'N', 'M', '<', '>', '?', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
//char scancodes_ascii[] = {
|
||||||
|
// 0, 0,
|
||||||
|
// '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
|
||||||
|
// 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||||
|
// 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
|
||||||
|
// 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
|
||||||
|
// '*',
|
||||||
|
// 0, ' ',
|
||||||
|
// 0,
|
||||||
|
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F1-F10
|
||||||
|
// 0, 0,
|
||||||
|
// '7', '8', '9', '-',
|
||||||
|
// '4', '5', '6', '+',
|
||||||
|
// '1', '2', '3',
|
||||||
|
// '0', 0,
|
||||||
|
// 0, // sysrq
|
||||||
|
// 0, 0, // weird
|
||||||
|
// 0, 0, // F11 F12
|
||||||
|
// // weid
|
||||||
|
//};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 shift: 1;
|
||||||
|
u8 ctrl: 1;
|
||||||
|
u8 alt: 1;
|
||||||
|
u8 extended: 1;
|
||||||
|
} keyboard_state;
|
||||||
|
|
||||||
|
void *keyboard_event_buffer = NULL;
|
||||||
|
|
||||||
char *MSG_KEY = "Clicked on key 'x'\n";
|
char *MSG_KEY = "Clicked on key 'x'\n";
|
||||||
|
|
||||||
void print_scancode(unsigned char scancode);
|
char getc() {
|
||||||
|
while (true) {
|
||||||
|
KeyEvent* event = get_next_event();
|
||||||
|
char retval = 0;
|
||||||
|
if (event == NULL) {
|
||||||
|
goto _getc_end;
|
||||||
|
}
|
||||||
|
if (event->is_release) {
|
||||||
|
goto _getc_end;
|
||||||
|
}
|
||||||
|
if (event->scancode == 0x1C) {
|
||||||
|
retval = '\n';
|
||||||
|
goto _getc_end;
|
||||||
|
}
|
||||||
|
if (event->ascii_code != 0) {
|
||||||
|
retval = event->ascii_code;
|
||||||
|
goto _getc_end;
|
||||||
|
}
|
||||||
|
_getc_end:
|
||||||
|
free_event(event);
|
||||||
|
if (retval != 0) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyEvent *get_next_event() {
|
||||||
|
KeyEvent *target = malloc(sizeof(KeyEvent));
|
||||||
|
if (!ring_buffer_get(keyboard_event_buffer, target)) {
|
||||||
|
free(target);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
||||||
|
void free_event(KeyEvent *event) {
|
||||||
|
free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void print_scancode(unsigned char scancode);
|
||||||
|
|
||||||
|
void handle_modifier_keys(unsigned char scancode, bool is_release) {
|
||||||
|
switch (scancode) {
|
||||||
|
case 42:
|
||||||
|
case 54:
|
||||||
|
keyboard_state.shift = !is_release;
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
keyboard_state.ctrl = !is_release;
|
||||||
|
break;
|
||||||
|
case 56:
|
||||||
|
keyboard_state.alt = !is_release;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// not an modifier key
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void publish_key_event(unsigned char scan_code) {
|
||||||
|
bool is_release = false;
|
||||||
|
if (scan_code > 0x80) {
|
||||||
|
is_release = true;
|
||||||
|
scan_code -= 0x80;
|
||||||
|
}
|
||||||
|
handle_modifier_keys(scan_code, is_release);
|
||||||
|
|
||||||
|
char ascii_char = scancode_map_lowercase[scan_code];
|
||||||
|
if (keyboard_state.shift) {
|
||||||
|
if (scancode_map_uppercase[scan_code] != 0) {
|
||||||
|
ascii_char = scancode_map_uppercase[scan_code];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyEvent event = {
|
||||||
|
.scancode = scan_code,
|
||||||
|
.ascii_code = ascii_char,
|
||||||
|
.is_release = !is_release,
|
||||||
|
.shift = keyboard_state.shift,
|
||||||
|
.alt = keyboard_state.alt,
|
||||||
|
.ctrl = keyboard_state.ctrl,
|
||||||
|
};
|
||||||
|
ring_buffer_put(keyboard_event_buffer, &event);
|
||||||
|
}
|
||||||
|
|
||||||
static void keyboard_callback(registers_t regs) {
|
static void keyboard_callback(registers_t regs) {
|
||||||
unsigned char status = port_byte_in(PORT_PS2_STATUS);
|
unsigned char status = port_byte_in(PORT_PS2_STATUS);
|
||||||
@@ -40,31 +151,37 @@ static void keyboard_callback(registers_t regs) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned char scancode = port_byte_in(PORT_PS2_DATA);
|
unsigned char scancode = port_byte_in(PORT_PS2_DATA);
|
||||||
print_scancode(scancode);
|
publish_key_event(scancode);
|
||||||
|
// print_scancode(scancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_keyboard() {
|
void init_keyboard() {
|
||||||
register_interrupt_handler(IRQ1, keyboard_callback);
|
register_interrupt_handler(IRQ1, keyboard_callback);
|
||||||
|
keyboard_state.shift = 0;
|
||||||
|
keyboard_state.ctrl = 0;
|
||||||
|
keyboard_state.alt = 0;
|
||||||
|
keyboard_state.extended = 0;
|
||||||
|
keyboard_event_buffer = create_buffer(256, sizeof(KeyEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_scancode(unsigned char scancode) {
|
//void print_scancode(unsigned char scancode) {
|
||||||
char msg[256];
|
// char msg[256];
|
||||||
char release = 0;
|
// char release = 0;
|
||||||
if (scancode > 0x80) {
|
// if (scancode > 0x80) {
|
||||||
// release
|
// // release
|
||||||
release = 1;
|
// release = 1;
|
||||||
scancode -= 0x80;
|
// scancode -= 0x80;
|
||||||
}
|
// }
|
||||||
char code = scancodes_ascii[scancode];
|
// char code = scancodes_ascii[scancode];
|
||||||
if (code == 0) {
|
// if (code == 0) {
|
||||||
// special
|
// // special
|
||||||
} else {
|
// } else {
|
||||||
if (release && code > 0x60 && code < 0x7B) {
|
// if (release && code > 0x60 && code < 0x7B) {
|
||||||
code -= 0x20; // to lowercase
|
// code -= 0x20; // to lowercase
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
strcpy(msg, MSG_KEY);
|
// strcpy(msg, MSG_KEY);
|
||||||
msg[strlen(msg) - 3] = code;
|
// msg[strlen(msg) - 3] = code;
|
||||||
kprint(msg);
|
// kprint(msg);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
@@ -5,6 +5,26 @@
|
|||||||
#ifndef MY_KERNEL_KEYBOARD_H
|
#ifndef MY_KERNEL_KEYBOARD_H
|
||||||
#define MY_KERNEL_KEYBOARD_H
|
#define MY_KERNEL_KEYBOARD_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
typedef struct KeyEvent_t {
|
||||||
|
// KeyCode key;
|
||||||
|
u32 scancode;
|
||||||
|
char ascii_code;
|
||||||
|
u8 is_release: 1;
|
||||||
|
u8 shift: 1;
|
||||||
|
u8 alt: 1;
|
||||||
|
u8 ctrl: 1;
|
||||||
|
} KeyEvent;
|
||||||
|
|
||||||
|
char getc();
|
||||||
|
|
||||||
void init_keyboard();
|
void init_keyboard();
|
||||||
|
|
||||||
|
//const char *key_code_to_string(KeyCode key);
|
||||||
|
|
||||||
|
KeyEvent *get_next_event();
|
||||||
|
|
||||||
|
void free_event(KeyEvent *event);
|
||||||
|
|
||||||
#endif //MY_KERNEL_KEYBOARD_H
|
#endif //MY_KERNEL_KEYBOARD_H
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <drivers/ports.h>
|
#include <drivers/ports.h>
|
||||||
#include <drivers/vgascreen.h>
|
#include <drivers/vgascreen.h>
|
||||||
#include <libc/libc.h>
|
#include <libc/libc.h>
|
||||||
|
#include <libc/stdbool.h>
|
||||||
#include <cpu/isr.h>
|
#include <cpu/isr.h>
|
||||||
#include <cpu/timer.h>
|
#include <cpu/timer.h>
|
||||||
#include <drivers/keyboard.h>
|
#include <drivers/keyboard.h>
|
||||||
@@ -8,9 +9,12 @@
|
|||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
#include <drivers/serial.h>
|
#include <drivers/serial.h>
|
||||||
#include <kprint.h>
|
#include <kprint.h>
|
||||||
|
#include <libc/readline.h>
|
||||||
|
#include <libc/string.h>
|
||||||
|
|
||||||
char *msg_booted = "Booted Successfully!\n";
|
char *msg_booted = "Booted Successfully!\n";
|
||||||
|
|
||||||
|
void main_loop();
|
||||||
|
|
||||||
void kmain(multiboot_info_t *multiboot_info) {
|
void kmain(multiboot_info_t *multiboot_info) {
|
||||||
isr_install();
|
isr_install();
|
||||||
@@ -37,9 +41,39 @@ void kmain(multiboot_info_t *multiboot_info) {
|
|||||||
init_timer(50);
|
init_timer(50);
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
|
|
||||||
print_mmap_info();
|
// print_mmap_info();
|
||||||
|
while (true) {
|
||||||
|
main_loop();
|
||||||
|
}
|
||||||
|
|
||||||
// vga_set_raw(pos * 2, 'X');
|
// vga_set_raw(pos * 2, 'X');
|
||||||
// vga_set_raw(pos * 2 + 1, 0xf);
|
// vga_set_raw(pos * 2 + 1, 0xf);
|
||||||
do {} while (1);
|
do {} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* newline = "\n";
|
||||||
|
const char* msg_unknown_command = "Unknown command: ";
|
||||||
|
|
||||||
|
const char* cmd_echo = "echo";
|
||||||
|
const char* cmd_print_mmap = "print_mmap";
|
||||||
|
|
||||||
|
void main_loop() {
|
||||||
|
char* msg = readline(NULL);
|
||||||
|
char* args = strchr(msg, ' ') + 1;
|
||||||
|
args[-1] = 0;
|
||||||
|
if (strcmp(cmd_echo, msg) == 0) {
|
||||||
|
kprint(args);
|
||||||
|
kprint(newline);
|
||||||
|
goto _main_loop_end;
|
||||||
|
}
|
||||||
|
if (strcmp(cmd_print_mmap, msg) == 0) {
|
||||||
|
print_mmap_info();
|
||||||
|
goto _main_loop_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprint(msg_unknown_command);
|
||||||
|
kprint(msg);
|
||||||
|
kprint(newline);
|
||||||
|
_main_loop_end:
|
||||||
|
free(msg);
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ void kprint_register(kprint_handler handler) {
|
|||||||
// todo handle
|
// todo handle
|
||||||
}
|
}
|
||||||
|
|
||||||
void kprint(char *msg) {
|
void kprint(const char *msg) {
|
||||||
for (int i = 0; i < MAX_HANDLERS; ++i) {
|
for (int i = 0; i < MAX_HANDLERS; ++i) {
|
||||||
if (handlers[i] == NULL) {
|
if (handlers[i] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ typedef void (*kprint_handler)(const char *);
|
|||||||
|
|
||||||
void kprint_register(kprint_handler);
|
void kprint_register(kprint_handler);
|
||||||
|
|
||||||
void kprint(char *msg);
|
void kprint(const char *msg);
|
||||||
@@ -14,10 +14,6 @@ int memcpy(char *dst, char *src, int amount) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strcpy(char *dst, char *src) {
|
|
||||||
return memcpy(dst, src, strlen(src) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int memset(char *dst, char data, int amount) {
|
int memset(char *dst, char data, int amount) {
|
||||||
for (int i = 0; i < amount; ++i) {
|
for (int i = 0; i < amount; ++i) {
|
||||||
dst[i] = data;
|
dst[i] = data;
|
||||||
@@ -34,11 +30,9 @@ int itoa(int i, char *target) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strlen(char *str) {
|
int maxi(int a, int b) {
|
||||||
int length = 0;
|
if (a >= b) {
|
||||||
while (str[length] != 0) {
|
return a;
|
||||||
length++;
|
|
||||||
}
|
}
|
||||||
return length;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,10 @@
|
|||||||
|
|
||||||
int memcpy(char *dst, char *src, int amount);
|
int memcpy(char *dst, char *src, int amount);
|
||||||
|
|
||||||
int strcpy(char *dst, char *src);
|
|
||||||
|
|
||||||
int memset(char *dst, char data, int amount);
|
int memset(char *dst, char data, int amount);
|
||||||
|
|
||||||
int itoa(int i, char *target);
|
int itoa(int i, char *target);
|
||||||
|
|
||||||
int strlen(char *str);
|
int maxi(int a, int b);
|
||||||
|
|
||||||
#endif /* KERNEL_LIBC_LIBC_H_ */
|
#endif /* KERNEL_LIBC_LIBC_H_ */
|
||||||
|
|||||||
30
kernel/libc/readline.c
Normal file
30
kernel/libc/readline.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 01-02-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "readline.h"
|
||||||
|
#include <libc/libc.h>
|
||||||
|
#include <types.h>
|
||||||
|
#include <kprint.h>
|
||||||
|
#include <mem/mem.h>
|
||||||
|
#include <drivers/keyboard.h>
|
||||||
|
|
||||||
|
#define RESULT_SIZE 256
|
||||||
|
|
||||||
|
const char* default_msg = "> ";
|
||||||
|
|
||||||
|
char* readline(const char *prompt) {
|
||||||
|
kprint(prompt == NULL ? default_msg : prompt);
|
||||||
|
|
||||||
|
char* result = malloc(RESULT_SIZE);
|
||||||
|
memset(result, 0, RESULT_SIZE);
|
||||||
|
for (int i = 0; i < RESULT_SIZE; ++i) {
|
||||||
|
result[i] = getc();
|
||||||
|
kprint(&result[i]);
|
||||||
|
if (result[i] == '\n') {
|
||||||
|
result[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
10
kernel/libc/readline.h
Normal file
10
kernel/libc/readline.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 01-02-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEW_KERNEL_READLINE_H
|
||||||
|
#define NEW_KERNEL_READLINE_H
|
||||||
|
|
||||||
|
char* readline(const char *prompt);
|
||||||
|
|
||||||
|
#endif //NEW_KERNEL_READLINE_H
|
||||||
57
kernel/libc/ringqueue.c
Normal file
57
kernel/libc/ringqueue.c
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 30-01-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ringqueue.h"
|
||||||
|
#include <libc/libc.h>
|
||||||
|
#include <mem/mem.h>
|
||||||
|
|
||||||
|
#define calc_pos(buffer, index) ((buffer->object_size) * (index))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int object_size;
|
||||||
|
int count;
|
||||||
|
int read_pos;
|
||||||
|
int write_pos;
|
||||||
|
void *mem;
|
||||||
|
} ring_buffer_t;
|
||||||
|
|
||||||
|
void *create_buffer(int count, int object_size) {
|
||||||
|
ring_buffer_t *buffer = malloc(sizeof(ring_buffer_t));
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buffer->object_size = object_size;
|
||||||
|
buffer->count = count;
|
||||||
|
buffer->read_pos = 0;
|
||||||
|
buffer->write_pos = 0;
|
||||||
|
buffer->mem = malloc(count * object_size);
|
||||||
|
if (buffer->mem == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
void free_buffer(void *buffer) {
|
||||||
|
free(((ring_buffer_t *) buffer)->mem);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ring_buffer_put(void *buffer, void *item) {
|
||||||
|
ring_buffer_t *ring_buffer = (ring_buffer_t *) buffer;
|
||||||
|
// todo check if this write would overwrite the current reading pos
|
||||||
|
// todo handle the above case
|
||||||
|
memcpy(ring_buffer->mem + calc_pos(ring_buffer, ring_buffer->write_pos), item, ring_buffer->object_size);
|
||||||
|
ring_buffer->write_pos++;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ring_buffer_get(void *buffer, void* target) {
|
||||||
|
ring_buffer_t *ring_buffer = (ring_buffer_t *) buffer;
|
||||||
|
if (ring_buffer->read_pos == ring_buffer->write_pos) {
|
||||||
|
// nothing to read
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(target, ring_buffer->mem + calc_pos(ring_buffer, ring_buffer->read_pos++), ring_buffer->object_size);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
19
kernel/libc/ringqueue.h
Normal file
19
kernel/libc/ringqueue.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 30-01-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEW_KERNEL_RINGQUEUE_H
|
||||||
|
#define NEW_KERNEL_RINGQUEUE_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <libc/stdbool.h>
|
||||||
|
|
||||||
|
void *create_buffer(int count, int object_size);
|
||||||
|
|
||||||
|
void free_buffer(void *buffer);
|
||||||
|
|
||||||
|
void ring_buffer_put(void *buffer, void *item);
|
||||||
|
|
||||||
|
bool ring_buffer_get(void *buffer, void* target);
|
||||||
|
|
||||||
|
#endif //NEW_KERNEL_RINGQUEUE_H
|
||||||
5
kernel/libc/stdbool.c
Normal file
5
kernel/libc/stdbool.c
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 31-01-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdbool.h"
|
||||||
15
kernel/libc/stdbool.h
Normal file
15
kernel/libc/stdbool.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 31-01-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEW_KERNEL_STDBOOL_H
|
||||||
|
#define NEW_KERNEL_STDBOOL_H
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define true 1
|
||||||
|
#define FALSE 0
|
||||||
|
#define false 0
|
||||||
|
|
||||||
|
typedef unsigned char bool;
|
||||||
|
|
||||||
|
#endif //NEW_KERNEL_STDBOOL_H
|
||||||
60
kernel/libc/string.c
Normal file
60
kernel/libc/string.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 01-02-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "string.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include <libc/libc.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
int strcpy(char *dst, char *src) {
|
||||||
|
return memcpy(dst, src, strlen(src) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int strlen(const char *str) {
|
||||||
|
int length = 0;
|
||||||
|
while (str[length] != 0) {
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcmp(const char *s1, const char *s2) {
|
||||||
|
int len1 = strlen(s1);
|
||||||
|
int len2 = strlen(s1);
|
||||||
|
return strncmp(s1, s2, maxi(len1, len2));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *strchr(const char *s, char c) {
|
||||||
|
int index = 0;
|
||||||
|
while (true) {
|
||||||
|
if (s[index] == c) {
|
||||||
|
return &s[index];
|
||||||
|
}
|
||||||
|
if (s[index] == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int strncmp(const char *s1, const char *s2, int n) {
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
if (s1[i] == 0 && s2[i] == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (s1[i] == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (s2[i] == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (s1[i] > s2[i]) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (s2[i] < s1[i]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
kernel/libc/string.h
Normal file
18
kernel/libc/string.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 01-02-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEW_KERNEL_STRING_H
|
||||||
|
#define NEW_KERNEL_STRING_H
|
||||||
|
|
||||||
|
int strcpy(char *dst, char *src);
|
||||||
|
|
||||||
|
int strlen(const char *str);
|
||||||
|
|
||||||
|
const char *strchr(const char *s, char c);
|
||||||
|
|
||||||
|
int strcmp(const char *s1, const char *s2);
|
||||||
|
|
||||||
|
int strncmp(const char *s1, const char *s2, int n);
|
||||||
|
|
||||||
|
#endif //NEW_KERNEL_STRING_H
|
||||||
140
kernel/mem/mem.c
140
kernel/mem/mem.c
@@ -7,6 +7,27 @@
|
|||||||
#include <mem/mem.h>
|
#include <mem/mem.h>
|
||||||
#include <libc/libc.h>
|
#include <libc/libc.h>
|
||||||
|
|
||||||
|
#define MEMMAP_ENTRIES 16
|
||||||
|
|
||||||
|
#define MMAP_TYPE_UNDEFINED 0
|
||||||
|
#define MMAP_TYPE_AVAILABLE 1
|
||||||
|
#define MMAP_TYPE_RESERVED 2
|
||||||
|
#define MMAP_TYPE_ACPI_RECLAIMABLE 3
|
||||||
|
#define MMAP_TYPE_NVS 4
|
||||||
|
#define MMAP_TYPE_BADRAM 5
|
||||||
|
#define MMAP_TYPE_KERNEL 6
|
||||||
|
#define MMAP_TYPE_MALLOC 7
|
||||||
|
|
||||||
|
#define MALLOC_TYPE_FREE 0
|
||||||
|
#define MALLOC_TYPE_USED 1
|
||||||
|
|
||||||
|
#define kilobyte (1024)
|
||||||
|
//#define kernel_start (one_meg)
|
||||||
|
#define kernel_size (32 * kilobyte)
|
||||||
|
#define kernel_end (kernel_start + kernel_size)
|
||||||
|
extern void *kernel_start;
|
||||||
|
//extern void *kernel_end;
|
||||||
|
|
||||||
char *msg_index = "Idx: ";
|
char *msg_index = "Idx: ";
|
||||||
char *msg_addr = "Address: ";
|
char *msg_addr = "Address: ";
|
||||||
char *msg_len = "Length: ";
|
char *msg_len = "Length: ";
|
||||||
@@ -14,20 +35,18 @@ char *msg_type = "Type: ";
|
|||||||
char *msg_nl = "\n";
|
char *msg_nl = "\n";
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 address;
|
void *address;
|
||||||
u64 length;
|
u32 length;
|
||||||
#define MMAP_TYPE_UNDEFINED 0
|
|
||||||
#define MMAP_TYPE_AVAILABLE 1
|
|
||||||
#define MMAP_TYPE_RESERVED 2
|
|
||||||
#define MMAP_TYPE_ACPI_RECLAIMABLE 3
|
|
||||||
#define MMAP_TYPE_NVS 4
|
|
||||||
#define MMAP_TYPE_BADRAM 5
|
|
||||||
u32 type;
|
u32 type;
|
||||||
} __attribute((packed)) mmap_entry;
|
} __attribute((packed)) mmap_entry;
|
||||||
|
|
||||||
char *msg_lu = "0123456789ABCDEF";
|
char *msg_lu = "0123456789ABCDEF";
|
||||||
|
|
||||||
mmap_entry memmap[16] = {
|
int malloc_entries = 0;
|
||||||
|
int malloc_used = 0;
|
||||||
|
|
||||||
|
int last_memmap_entry = 0;
|
||||||
|
mmap_entry memmap[MEMMAP_ENTRIES] = {
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
@@ -46,14 +65,107 @@ mmap_entry memmap[16] = {
|
|||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct malloc_map {
|
||||||
|
struct malloc_map *next;
|
||||||
|
struct malloc_map *pref;
|
||||||
|
u32 size;
|
||||||
|
int type;
|
||||||
|
} malloc_map;
|
||||||
|
|
||||||
|
void use_mmap_entry(struct multiboot_mmap_entry *entry) {
|
||||||
|
mmap_entry *mm_entry = &memmap[last_memmap_entry++];
|
||||||
|
mm_entry->address = (void *) entry->addr;
|
||||||
|
mm_entry->length = entry->len;
|
||||||
|
mm_entry->type = entry->type;
|
||||||
|
if (last_memmap_entry == 1) {
|
||||||
|
// not using first map entry for now
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check if the entry overlaps with the kernel address space
|
||||||
|
if (kernel_start >= mm_entry->address && kernel_start <= mm_entry->address + mm_entry->length) {
|
||||||
|
// todo make this something proper
|
||||||
|
struct multiboot_mmap_entry extra_entry;
|
||||||
|
extra_entry.size = entry->size;
|
||||||
|
extra_entry.type = entry->type;
|
||||||
|
extra_entry.addr = entry->addr + kernel_size;
|
||||||
|
extra_entry.len = entry->size - kernel_size;
|
||||||
|
use_mmap_entry(&extra_entry);
|
||||||
|
|
||||||
|
mm_entry->length = kernel_size;
|
||||||
|
mm_entry->type = MMAP_TYPE_KERNEL;
|
||||||
|
}
|
||||||
|
if (mm_entry->type == MMAP_TYPE_AVAILABLE && (unsigned int) mm_entry->length > sizeof(malloc_map)) {
|
||||||
|
mm_entry->type = MMAP_TYPE_MALLOC;
|
||||||
|
malloc_map *map = (malloc_map *) mm_entry->address;
|
||||||
|
map->type = MALLOC_TYPE_FREE;
|
||||||
|
map->size = mm_entry->length - sizeof(malloc_map);
|
||||||
|
map->pref = map;
|
||||||
|
map->next = map;
|
||||||
|
malloc_entries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_mmap(struct multiboot_mmap_entry *entries, u32 count) {
|
void init_mmap(struct multiboot_mmap_entry *entries, u32 count) {
|
||||||
for (u32 i = 0; i < count; ++i) {
|
for (u32 i = 0; i < count; ++i) {
|
||||||
memmap[i].address = entries[i].addr;
|
use_mmap_entry(&entries[i]);
|
||||||
memmap[i].length = entries[i].len;
|
|
||||||
memmap[i].type = entries[i].type;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void split_malloc_map(malloc_map *entry, unsigned int size) {
|
||||||
|
malloc_entries++;
|
||||||
|
malloc_map *new_entry = entry + sizeof(malloc_map) + size;
|
||||||
|
new_entry->size = entry->size - size - sizeof(malloc_map);
|
||||||
|
new_entry->next = entry->next;
|
||||||
|
new_entry->pref = entry;
|
||||||
|
new_entry->type = MALLOC_TYPE_FREE;
|
||||||
|
entry->next->pref = new_entry;
|
||||||
|
entry->next = new_entry;
|
||||||
|
entry->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *malloc(unsigned int size) {
|
||||||
|
// todo replace this horrible mess!
|
||||||
|
// this lacks any page alignment and what so ever
|
||||||
|
for (int i = 0; i < MEMMAP_ENTRIES; ++i) {
|
||||||
|
if (memmap[i].type != MMAP_TYPE_MALLOC) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// get first first_map of address
|
||||||
|
malloc_map *first_map = (malloc_map *) memmap[i].address;
|
||||||
|
malloc_map *current_map = first_map;
|
||||||
|
// iterate through maps
|
||||||
|
do {
|
||||||
|
if (current_map->type == MALLOC_TYPE_USED) {
|
||||||
|
goto malloc_find_next;
|
||||||
|
}
|
||||||
|
if ((unsigned int) current_map->size < size) {
|
||||||
|
goto malloc_find_next;
|
||||||
|
}
|
||||||
|
if ((unsigned int) current_map->size > (size + sizeof(malloc_map))) {
|
||||||
|
// big enough to split
|
||||||
|
split_malloc_map(current_map, size);
|
||||||
|
}
|
||||||
|
malloc_used++;
|
||||||
|
current_map->type = MALLOC_TYPE_USED;
|
||||||
|
return ((void*)current_map) + sizeof(malloc_map);
|
||||||
|
|
||||||
|
malloc_find_next:
|
||||||
|
current_map = current_map->next;
|
||||||
|
} while (current_map != first_map);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void *mem) {
|
||||||
|
if (mem == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
malloc_used--;
|
||||||
|
malloc_map *map = (mem - sizeof(malloc_map));
|
||||||
|
map->type = MALLOC_TYPE_FREE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void print_hex_u64(u64 input) {
|
void print_hex_u64(u64 input) {
|
||||||
char msg[18] = "0x0000000000000000";
|
char msg[18] = "0x0000000000000000";
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
@@ -74,10 +186,10 @@ void print_mmap_info() {
|
|||||||
kprint(tmp_str);
|
kprint(tmp_str);
|
||||||
kprint(msg_nl);
|
kprint(msg_nl);
|
||||||
kprint(msg_addr);
|
kprint(msg_addr);
|
||||||
print_hex_u64(memmap[i].address);
|
print_hex_u64((u64) memmap[i].address);
|
||||||
kprint(msg_nl);
|
kprint(msg_nl);
|
||||||
kprint(msg_len);
|
kprint(msg_len);
|
||||||
print_hex_u64(memmap[i].length);
|
print_hex_u64((u64) memmap[i].length);
|
||||||
kprint(msg_nl);
|
kprint(msg_nl);
|
||||||
kprint(msg_type);
|
kprint(msg_type);
|
||||||
itoa(memmap[i].type, tmp_str);
|
itoa(memmap[i].type, tmp_str);
|
||||||
|
|||||||
@@ -11,4 +11,7 @@ void init_mmap(struct multiboot_mmap_entry *entries, u32 count);
|
|||||||
|
|
||||||
void print_mmap_info();
|
void print_mmap_info();
|
||||||
|
|
||||||
|
void* malloc(unsigned int size);
|
||||||
|
void free(void* mem);
|
||||||
|
|
||||||
#endif //NEW_KERNEL_MEM_H
|
#endif //NEW_KERNEL_MEM_H
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ SECTIONS
|
|||||||
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
||||||
loaded at by the bootloader. */
|
loaded at by the bootloader. */
|
||||||
. = 1M;
|
. = 1M;
|
||||||
|
kernel_start = .;
|
||||||
|
|
||||||
/* First put the multiboot header, as it is required to be put very early
|
/* First put the multiboot header, as it is required to be put very early
|
||||||
early in the image or the bootloader won't recognize the file format.
|
early in the image or the bootloader won't recognize the file format.
|
||||||
@@ -38,6 +39,13 @@ SECTIONS
|
|||||||
*(.bss)
|
*(.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.eh_frame);
|
||||||
|
*(.comment);
|
||||||
|
*(.gnu.hash);
|
||||||
|
*(.note.gnu.build-id);
|
||||||
|
}
|
||||||
|
|
||||||
/* The compiler may produce other sections, by default it will put them in
|
/* The compiler may produce other sections, by default it will put them in
|
||||||
a segment with the same name. Simply add stuff here as needed. */
|
a segment with the same name. Simply add stuff here as needed. */
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
nohup qemu-system-i386 -S -s -kernel cmake-build-debug/my-kernel.bin -d guest_errors,int -m 1G &
|
nohup qemu-system-i386 -S -s -kernel cmake-build-debug/my-kernel.bin -d guest_errors,int -m 1G > /dev/null &
|
||||||
disown
|
disown
|
||||||
|
|||||||
810
scancodes/set1.json
Normal file
810
scancodes/set1.json
Normal file
@@ -0,0 +1,810 @@
|
|||||||
|
[
|
||||||
|
[
|
||||||
|
"1",
|
||||||
|
"29/A9",
|
||||||
|
"0E/F0 0E",
|
||||||
|
"0E/F0 0E",
|
||||||
|
"`",
|
||||||
|
"~"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"2",
|
||||||
|
"02/82",
|
||||||
|
"16/F0 16",
|
||||||
|
"16/F0 16",
|
||||||
|
"1",
|
||||||
|
"!"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"3",
|
||||||
|
"03/83",
|
||||||
|
"1E/F0 1E",
|
||||||
|
"1E/F0 1E",
|
||||||
|
"2",
|
||||||
|
"@"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"4",
|
||||||
|
"04/84",
|
||||||
|
"26/F0 26",
|
||||||
|
"26/F0 26",
|
||||||
|
"3",
|
||||||
|
"#"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"5",
|
||||||
|
"05/85",
|
||||||
|
"25/F0 25",
|
||||||
|
"25/F0 25",
|
||||||
|
"4",
|
||||||
|
"$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"6",
|
||||||
|
"06/86",
|
||||||
|
"2E/F0 2E",
|
||||||
|
"2E/F0 2E",
|
||||||
|
"5",
|
||||||
|
"%"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"7",
|
||||||
|
"07/87",
|
||||||
|
"36/F0 36",
|
||||||
|
"36/F0 36",
|
||||||
|
"6",
|
||||||
|
"^"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"8",
|
||||||
|
"08/88",
|
||||||
|
"3D/F0 3D",
|
||||||
|
"3D/F0 3D",
|
||||||
|
"7",
|
||||||
|
"&"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"9",
|
||||||
|
"09/89",
|
||||||
|
"3E/F0 3E",
|
||||||
|
"3E/F0 3E",
|
||||||
|
"8",
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"10",
|
||||||
|
"0A/8A",
|
||||||
|
"46/F0 46",
|
||||||
|
"46/F0 46",
|
||||||
|
"9",
|
||||||
|
"("
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"11",
|
||||||
|
"0B/8B",
|
||||||
|
"45/F0 45",
|
||||||
|
"45/F0 45",
|
||||||
|
"0",
|
||||||
|
")"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"12",
|
||||||
|
"0C/8C",
|
||||||
|
"4E/F0 4E",
|
||||||
|
"4E/F0 4E",
|
||||||
|
"-",
|
||||||
|
"_"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"13",
|
||||||
|
"0D/8D",
|
||||||
|
"55/F0 55",
|
||||||
|
"55/F0 55",
|
||||||
|
"=",
|
||||||
|
"+"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"15",
|
||||||
|
"0E/8E",
|
||||||
|
"66/F0 66",
|
||||||
|
"66/F0 66",
|
||||||
|
"Backspace",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"16",
|
||||||
|
"0F/8F",
|
||||||
|
"0D/F0 0D",
|
||||||
|
"0D/F0 0D",
|
||||||
|
"Tab",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"17",
|
||||||
|
"10/90",
|
||||||
|
"15/F0 15",
|
||||||
|
"15/F0 15",
|
||||||
|
"q",
|
||||||
|
"Q"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"18",
|
||||||
|
"11/91",
|
||||||
|
"1D/F0 1D",
|
||||||
|
"1D/F0 1D",
|
||||||
|
"w",
|
||||||
|
"W"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"19",
|
||||||
|
"12/92",
|
||||||
|
"24/F0 24",
|
||||||
|
"24/F0 24",
|
||||||
|
"e",
|
||||||
|
"E"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"20",
|
||||||
|
"13/93",
|
||||||
|
"2D/F0 2D",
|
||||||
|
"2D/F0 2D",
|
||||||
|
"r",
|
||||||
|
"R"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"21",
|
||||||
|
"14/94",
|
||||||
|
"2C/F0 2C",
|
||||||
|
"2C/F0 2C",
|
||||||
|
"t",
|
||||||
|
"T"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"22",
|
||||||
|
"15/95",
|
||||||
|
"35/F0 35",
|
||||||
|
"35/F0 35",
|
||||||
|
"y",
|
||||||
|
"Y"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"23",
|
||||||
|
"16/96",
|
||||||
|
"3C/F0 3C",
|
||||||
|
"3C/F0 3C",
|
||||||
|
"u",
|
||||||
|
"U"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"24",
|
||||||
|
"17/97",
|
||||||
|
"43/F0 43",
|
||||||
|
"43/F0 43",
|
||||||
|
"i",
|
||||||
|
"I"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"25",
|
||||||
|
"18/98",
|
||||||
|
"44/F0 44",
|
||||||
|
"44/F0 44",
|
||||||
|
"o",
|
||||||
|
"O"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"26",
|
||||||
|
"19/99",
|
||||||
|
"4D/F0 4D",
|
||||||
|
"4D/F0 4D",
|
||||||
|
"p",
|
||||||
|
"P"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"27",
|
||||||
|
"1A/9A",
|
||||||
|
"54/F0 54",
|
||||||
|
"54/F0 54",
|
||||||
|
"[",
|
||||||
|
"{"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"28",
|
||||||
|
"1B/9B",
|
||||||
|
"5B/F0 5B",
|
||||||
|
"5B/F0 5B",
|
||||||
|
"]",
|
||||||
|
"}"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"30",
|
||||||
|
"3A/BA",
|
||||||
|
"58/F0 58",
|
||||||
|
"58/F0 58",
|
||||||
|
"Caps Lock",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"31",
|
||||||
|
"1E/9E",
|
||||||
|
"1C/F0 1C",
|
||||||
|
"1C/F0 1C",
|
||||||
|
"a",
|
||||||
|
"A"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"32",
|
||||||
|
"1F/9F",
|
||||||
|
"1B/F0 1B",
|
||||||
|
"1B/F0 1B",
|
||||||
|
"s",
|
||||||
|
"S"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"33",
|
||||||
|
"20/A0",
|
||||||
|
"23/F0 23",
|
||||||
|
"23/F0 23",
|
||||||
|
"d",
|
||||||
|
"D"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"34",
|
||||||
|
"21/A1",
|
||||||
|
"2B/F0 2B",
|
||||||
|
"2B/F0 2B",
|
||||||
|
"f",
|
||||||
|
"F"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"35",
|
||||||
|
"22/A2",
|
||||||
|
"34/F0 34",
|
||||||
|
"34/F0 34",
|
||||||
|
"g",
|
||||||
|
"G"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"36",
|
||||||
|
"23/A3",
|
||||||
|
"33/F0 33",
|
||||||
|
"33/F0 33",
|
||||||
|
"h",
|
||||||
|
"H"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"37",
|
||||||
|
"24/A4",
|
||||||
|
"3B/F0 3B",
|
||||||
|
"3B/F0 3B",
|
||||||
|
"j",
|
||||||
|
"J"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"38",
|
||||||
|
"25/A5",
|
||||||
|
"42/F0 42",
|
||||||
|
"42/F0 42",
|
||||||
|
"k",
|
||||||
|
"K"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"39",
|
||||||
|
"26/A6",
|
||||||
|
"4B/F0 4B",
|
||||||
|
"4B/F0 4B",
|
||||||
|
"l",
|
||||||
|
"L"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"40",
|
||||||
|
"27/A7",
|
||||||
|
"4C/F0 4C",
|
||||||
|
"4C/F0 4C",
|
||||||
|
";",
|
||||||
|
":"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"41",
|
||||||
|
"28/A8",
|
||||||
|
"52/F0 52",
|
||||||
|
"52/F0 52",
|
||||||
|
"'",
|
||||||
|
"\""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"43",
|
||||||
|
"1C/9C",
|
||||||
|
"5A/F0 5A",
|
||||||
|
"5A/F0 5A",
|
||||||
|
"Enter",
|
||||||
|
"Enter"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"44",
|
||||||
|
"2A/AA",
|
||||||
|
"12/F0 12",
|
||||||
|
"12/F0 12",
|
||||||
|
"Left Shift",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"46",
|
||||||
|
"2C/AC",
|
||||||
|
"1A/F0 1A",
|
||||||
|
"1A/F0 1A",
|
||||||
|
"z",
|
||||||
|
"Z"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"47",
|
||||||
|
"2D/AD",
|
||||||
|
"22/F0 22",
|
||||||
|
"22/F0 22",
|
||||||
|
"x",
|
||||||
|
"X"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"48",
|
||||||
|
"2E/AE",
|
||||||
|
"21/F0 21",
|
||||||
|
"21/F0 21",
|
||||||
|
"c",
|
||||||
|
"C"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"49",
|
||||||
|
"2F/AF",
|
||||||
|
"2A/F0 2A",
|
||||||
|
"2A/F0 2A",
|
||||||
|
"v",
|
||||||
|
"V"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"50",
|
||||||
|
"30/B0",
|
||||||
|
"32/F0 32",
|
||||||
|
"32/F0 32",
|
||||||
|
"b",
|
||||||
|
"B"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"51",
|
||||||
|
"31/B1",
|
||||||
|
"31/F0 31",
|
||||||
|
"31/F0 31",
|
||||||
|
"n",
|
||||||
|
"N"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"52",
|
||||||
|
"32/B2",
|
||||||
|
"3A/F0 3A",
|
||||||
|
"3A/F0 3A",
|
||||||
|
"m",
|
||||||
|
"M"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"53",
|
||||||
|
"33/B3",
|
||||||
|
"41/F0 41",
|
||||||
|
"41/F0 41",
|
||||||
|
",",
|
||||||
|
"<"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"54",
|
||||||
|
"34/B4",
|
||||||
|
"49/F0 49",
|
||||||
|
"49/F0 49",
|
||||||
|
".",
|
||||||
|
">"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"55",
|
||||||
|
"35/B5",
|
||||||
|
"4A/F0 4A",
|
||||||
|
"4A/F0 4A",
|
||||||
|
"/",
|
||||||
|
"?"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"57",
|
||||||
|
"36/B6",
|
||||||
|
"59/F0 59",
|
||||||
|
"59/F0 59",
|
||||||
|
"Right Shift",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"58",
|
||||||
|
"1D/9D",
|
||||||
|
"14/F0 14",
|
||||||
|
"11/F0 11",
|
||||||
|
"Left Ctrl",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"60",
|
||||||
|
"38/B8",
|
||||||
|
"11/F0 11",
|
||||||
|
"19/F0 19",
|
||||||
|
"Left Alt",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"61",
|
||||||
|
"39/B9",
|
||||||
|
"29/F0 29",
|
||||||
|
"29/F0 29",
|
||||||
|
"Spacebar",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"62",
|
||||||
|
"E0 38/E0 B8",
|
||||||
|
"E0 11/E0 F0 11",
|
||||||
|
"39/F0 39",
|
||||||
|
"Right Alt",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"64",
|
||||||
|
"E0 1D/E0 9D",
|
||||||
|
"E0 14/E0 F0 14",
|
||||||
|
"58/F0 58",
|
||||||
|
"Right Ctrl",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"75",
|
||||||
|
"E0 52/E0 D2 (base)",
|
||||||
|
"E0 70/E0 F0 70 (base)",
|
||||||
|
"67/F0 67",
|
||||||
|
"Insert",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"76",
|
||||||
|
"E0 4B/E0 CB (base)",
|
||||||
|
"E0 71/E0 F0 71 (base)",
|
||||||
|
"64/F0 64",
|
||||||
|
"Delete",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"79",
|
||||||
|
"E0 4B/E0 CB (base)",
|
||||||
|
"E0 6B/E0 F0 6B (base)",
|
||||||
|
"61/F0 61",
|
||||||
|
"Left Arrow",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"80",
|
||||||
|
"E0 47/E0 C7 (base)",
|
||||||
|
"E0 6C/E0 F0 6C (base)",
|
||||||
|
"6E/F0 6E",
|
||||||
|
"Home",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"81",
|
||||||
|
"E0 4F/E0 CF (base)",
|
||||||
|
"E0 69/E0 F0 69 (base)",
|
||||||
|
"65/F0 65",
|
||||||
|
"End",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"83",
|
||||||
|
"E0 48/E0 C8 (base)",
|
||||||
|
"E0 75/E0 F0 75 (base)",
|
||||||
|
"63/F0 63",
|
||||||
|
"Up Arrow",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"84",
|
||||||
|
"E0 50/E0 D0 (base)",
|
||||||
|
"E0 72/E0 F0 72 (base)",
|
||||||
|
"60/F0 60",
|
||||||
|
"Down Arrow",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"85",
|
||||||
|
"E0 49/E0 C9 (base)",
|
||||||
|
"E0 7D/E0 F0 7D (base)",
|
||||||
|
"6F/F0 6F",
|
||||||
|
"Page Up",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"86",
|
||||||
|
"E0 51/E0 D1 (base)",
|
||||||
|
"E0 7A/E0 F0 7A (base)",
|
||||||
|
"6D/F0 6D",
|
||||||
|
"Page Down",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"89",
|
||||||
|
"E0 4D/E0 CD (base)",
|
||||||
|
"E0 74/E0 F0 74 (base)",
|
||||||
|
"6A/F0 6A",
|
||||||
|
"Right Arrow",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"90",
|
||||||
|
"45/C5",
|
||||||
|
"77/F0 77",
|
||||||
|
"76/F0 76",
|
||||||
|
"Num Lock",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"91",
|
||||||
|
"47/C7",
|
||||||
|
"6C/F0 6C",
|
||||||
|
"6C/F0 6C",
|
||||||
|
"Keypad 7",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"92",
|
||||||
|
"4B/CB",
|
||||||
|
"6B/F0 6B",
|
||||||
|
"6B/F0 6B",
|
||||||
|
"Keypad 4",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"93",
|
||||||
|
"4F/CF",
|
||||||
|
"69/F0 69",
|
||||||
|
"69/F0 69",
|
||||||
|
"Keypad 1",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"95",
|
||||||
|
"E0 35/E0 B5 (base)",
|
||||||
|
"E0 4A/E0 F0 4A (base)",
|
||||||
|
"77/F0 77",
|
||||||
|
"Keypad /",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"96",
|
||||||
|
"48/C8",
|
||||||
|
"75/F0 75",
|
||||||
|
"75/F0 75",
|
||||||
|
"Keypad 8",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"97",
|
||||||
|
"4C/CC",
|
||||||
|
"73/F0 73",
|
||||||
|
"73/F0 73",
|
||||||
|
"Keypad 5",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"98",
|
||||||
|
"50/D0",
|
||||||
|
"72/F0 72",
|
||||||
|
"72/F0 72",
|
||||||
|
"Keypad 2",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"99",
|
||||||
|
"52/D2",
|
||||||
|
"70/F0 70",
|
||||||
|
"70/F0 70",
|
||||||
|
"Keypad 0",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"100",
|
||||||
|
"37/B7",
|
||||||
|
"7C/F0 7C",
|
||||||
|
"7E/F0 7E",
|
||||||
|
"Keypad *",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"101",
|
||||||
|
"49/C9",
|
||||||
|
"7D/F0 7D",
|
||||||
|
"7D/F0 7D",
|
||||||
|
"Keypad 9",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"102",
|
||||||
|
"4D/CD",
|
||||||
|
"74/F0 74",
|
||||||
|
"74/F0 74",
|
||||||
|
"Keypad 6",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"103",
|
||||||
|
"51/D1",
|
||||||
|
"7A/F0 7A",
|
||||||
|
"7A/F0 7A",
|
||||||
|
"Keypad 3",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"104",
|
||||||
|
"53/D3",
|
||||||
|
"71/F0 71",
|
||||||
|
"71/F0 71",
|
||||||
|
"Keypad .",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"105",
|
||||||
|
"4A/CA",
|
||||||
|
"7B/F0 7B",
|
||||||
|
"84/F0 84",
|
||||||
|
"Keypad -",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"106",
|
||||||
|
"4E/CE",
|
||||||
|
"79/F0 79",
|
||||||
|
"7C/F0 7C",
|
||||||
|
"Keypad +",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"108",
|
||||||
|
"E0 1C/E0 9C",
|
||||||
|
"E0 5A/E0 F0 5A",
|
||||||
|
"79/F0 79",
|
||||||
|
"Keypad Enter",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"110",
|
||||||
|
"01/81",
|
||||||
|
"76/F0 76",
|
||||||
|
"08/F0 08",
|
||||||
|
"Esc",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"112",
|
||||||
|
"3B/BB",
|
||||||
|
"05/F0 05",
|
||||||
|
"07/F0 07",
|
||||||
|
"F1",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"113",
|
||||||
|
"3C/BC",
|
||||||
|
"06/F0 06",
|
||||||
|
"0F/F0 0F",
|
||||||
|
"F2",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"114",
|
||||||
|
"3D/BD",
|
||||||
|
"04/F0 04",
|
||||||
|
"17/F0 17",
|
||||||
|
"F3",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"115",
|
||||||
|
"3E/BE",
|
||||||
|
"0C/F0 0C",
|
||||||
|
"1F/F0 1F",
|
||||||
|
"F4",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"116",
|
||||||
|
"3F/BF",
|
||||||
|
"03/F0 03",
|
||||||
|
"27/F0 27",
|
||||||
|
"F5",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"117",
|
||||||
|
"40/C0",
|
||||||
|
"0B/F0 0B",
|
||||||
|
"2F/F0 2F",
|
||||||
|
"F6",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"118",
|
||||||
|
"41/C1",
|
||||||
|
"83/F0 83",
|
||||||
|
"37/F0 37",
|
||||||
|
"F7",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"119",
|
||||||
|
"42/C2",
|
||||||
|
"0A/F0 0A",
|
||||||
|
"3F/F0 3F",
|
||||||
|
"F8",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"120",
|
||||||
|
"43/C3",
|
||||||
|
"01/F0 01",
|
||||||
|
"47/F0 47",
|
||||||
|
"F9",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"121",
|
||||||
|
"44/C4",
|
||||||
|
"09/F0 09",
|
||||||
|
"4F/F0 4F",
|
||||||
|
"F10",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"122",
|
||||||
|
"57/D7",
|
||||||
|
"78/F0 78",
|
||||||
|
"56/F0 56",
|
||||||
|
"F11",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"123",
|
||||||
|
"58/D8",
|
||||||
|
"07/F0 07",
|
||||||
|
"5E/F0 5E",
|
||||||
|
"F12",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"124",
|
||||||
|
"E0 2A E0 37/E0 B7 E0 AA",
|
||||||
|
"E0 12 E0 7C/E0 F0 7C E0 F0 12",
|
||||||
|
"57/F0 57",
|
||||||
|
"Print Screen",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"125",
|
||||||
|
"46/C6",
|
||||||
|
"7E/F0 7E",
|
||||||
|
"5F/F0 5F",
|
||||||
|
"Scroll Lock",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"126",
|
||||||
|
"E1 1D 45/E1 9D C5",
|
||||||
|
"E1 14 77 E1/F0 14 F0 77",
|
||||||
|
"62/F0 62",
|
||||||
|
"Pause Break",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"29 or 42*",
|
||||||
|
"2B/AB",
|
||||||
|
"5D/F0 5D",
|
||||||
|
"5C/F0 5C or 53/F0 53",
|
||||||
|
"\\",
|
||||||
|
"|"
|
||||||
|
]
|
||||||
|
]
|
||||||
124
scancodes/transform_scancodes.py
Normal file
124
scancodes/transform_scancodes.py
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import functools
|
||||||
|
import itertools
|
||||||
|
import json
|
||||||
|
import unicodedata
|
||||||
|
from typing import NamedTuple, List, Optional
|
||||||
|
import pyperclip
|
||||||
|
|
||||||
|
|
||||||
|
class KeyCode(NamedTuple):
|
||||||
|
scan_code: int
|
||||||
|
name_lower: str
|
||||||
|
name_upper: str
|
||||||
|
ascii_lower: Optional[str]
|
||||||
|
ascii_upper: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
# scancodes retrieved from https://wiki.osdev.org/PS/2_Keyboard
|
||||||
|
# scancodes transformed with https://www.convertjson.com/html-table-to-json.htm
|
||||||
|
|
||||||
|
|
||||||
|
blacklist_names = {'(zero)'}
|
||||||
|
|
||||||
|
special_map = {
|
||||||
|
'\\': 'forwardSlash',
|
||||||
|
'/': 'backSlash',
|
||||||
|
'[': 'bracketLeft',
|
||||||
|
']': 'bracketRight',
|
||||||
|
';': 'colonPressed',
|
||||||
|
"'": None,
|
||||||
|
'`': None,
|
||||||
|
',': 'comma',
|
||||||
|
'.': 'dot',
|
||||||
|
# todo keypad *
|
||||||
|
'-': 'dash',
|
||||||
|
'=': 'equals',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_unknown(i):
|
||||||
|
return KeyCode(i, f"Unknown{i:02x}Lower", f"Unknown{i:02x}Upper", None, None)
|
||||||
|
|
||||||
|
|
||||||
|
def not_in_blacklist(name: str) -> bool:
|
||||||
|
return name not in blacklist_names
|
||||||
|
|
||||||
|
|
||||||
|
def remove_braces(name: str) -> str:
|
||||||
|
name = name.lstrip('(').rstrip(')')
|
||||||
|
if name in special_map:
|
||||||
|
return special_map[name]
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def key_name_to_name(names: List[str]) -> str:
|
||||||
|
_names: List[str] = list(filter(lambda i: i is not None, map(remove_braces, filter(not_in_blacklist, names))))
|
||||||
|
_names_cap = itertools.chain([_names[0][0].lower() + _names[0][1:]],
|
||||||
|
map(lambda i: i[0].upper() + i[1:], _names[1:]))
|
||||||
|
return ''.join(_names_cap)
|
||||||
|
|
||||||
|
|
||||||
|
def get_name(item: str):
|
||||||
|
item = item.replace(' ', ' ')
|
||||||
|
if len(item) == 1:
|
||||||
|
item = unicodedata.name(item).title()
|
||||||
|
if item.startswith('Latin'):
|
||||||
|
return 'Letter' + item.split()[-1]
|
||||||
|
return item.replace(' ', '_') if item else None
|
||||||
|
|
||||||
|
|
||||||
|
def transform_set1(path):
|
||||||
|
codes = []
|
||||||
|
with open(path) as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
for ibm_number, make_break_1, _, _, lower, upper in data:
|
||||||
|
make_code, break_code = make_break_1.split('/')
|
||||||
|
if make_code.startswith('E0') or make_code.startswith('E1'):
|
||||||
|
# skipping multi codes for now
|
||||||
|
continue
|
||||||
|
make_code_i = int(make_code, base=16)
|
||||||
|
break_code_i = int(break_code, base=16)
|
||||||
|
if make_code_i != break_code_i ^ 0x80:
|
||||||
|
raise ValueError("Make/Break not equal" + ibm_number)
|
||||||
|
codes.append(KeyCode(
|
||||||
|
make_code_i,
|
||||||
|
get_name(lower),
|
||||||
|
get_name(upper),
|
||||||
|
lower,
|
||||||
|
upper,
|
||||||
|
))
|
||||||
|
|
||||||
|
codes_map = {}
|
||||||
|
|
||||||
|
for code in codes:
|
||||||
|
if code.scan_code in codes_map:
|
||||||
|
raise ValueError(f"Duplicate code {code!r}")
|
||||||
|
codes_map[code.scan_code] = code
|
||||||
|
|
||||||
|
# max_val = functools.reduce(lambda a, b: max(a, b), map(lambda x: x.scan_code, codes), 0)
|
||||||
|
return codes_map
|
||||||
|
# txts = []
|
||||||
|
# for i in range(max_val):
|
||||||
|
# code = codes_map.get(i) or get_unknown(i)
|
||||||
|
# txts.append(f'{code.scan_code}\t{code.name_lower}\t{code.name_upper}\t{code.ascii_lower or None}\t{code.ascii_upper or None}')
|
||||||
|
# pyperclip.copy('\n'.join(txts))
|
||||||
|
|
||||||
|
|
||||||
|
def get_ascii_val(val: str):
|
||||||
|
if not val:
|
||||||
|
return 'NULL'
|
||||||
|
if len(val) > 1:
|
||||||
|
return 'NULL'
|
||||||
|
if val == "'":
|
||||||
|
return "'\\''"
|
||||||
|
return repr(val)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
transform_set1()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user