Meta: Add files to repository
This commit is contained in:
parent
80a0428b66
commit
39198164cd
1029 changed files with 78311 additions and 0 deletions
10
System/Utilities/Dns.HC
Normal file
10
System/Utilities/Dns.HC
Normal file
|
@ -0,0 +1,10 @@
|
|||
U0 DnsQuery(U8* host)
|
||||
{
|
||||
U32 result = @dns_query(host);
|
||||
if (result == U32_MAX) {
|
||||
"Error looking up host %s\n", host;
|
||||
return;
|
||||
}
|
||||
"Query for %s: %d.%d.%d.%d\n", host, result.u8[3], result.u8[2], result.u8[1],
|
||||
result.u8[0];
|
||||
}
|
414
System/Utilities/Image.HC
Normal file
414
System/Utilities/Image.HC
Normal file
|
@ -0,0 +1,414 @@
|
|||
Silent(1); // This is needed to suppress "Function should return val" warnings for wrappers to non-HolyC functions
|
||||
|
||||
// class @image
|
||||
// {
|
||||
// CDC* (*FromBuffer)(U8* buffer, I64 len);
|
||||
// CDC* (*Load)(U8* filename);
|
||||
// CDC* (*Write)(U8* filename, CDC* dc);
|
||||
// };
|
||||
//
|
||||
// @image Image;
|
||||
|
||||
class @image_frame
|
||||
{
|
||||
CDC* dc;
|
||||
CSprite* sprite;
|
||||
I64 delay;
|
||||
};
|
||||
|
||||
class @image_collection
|
||||
{
|
||||
@image_frame** frames;
|
||||
I64 count;
|
||||
I64 current;
|
||||
I64 jiffies;
|
||||
I64 index;
|
||||
@image_collection* next;
|
||||
};
|
||||
|
||||
I64 @image_cbgr24_to_4_bit(CBGR24* ptr, Bool dither_probability)
|
||||
{
|
||||
I64 res, k;
|
||||
if (dither_probability) {
|
||||
k = RandU32;
|
||||
if (SqrI64(ptr->r) + SqrI64(ptr->g) + SqrI64(ptr->b) >= 3 * SqrI64(k.u8[0]))
|
||||
res = 8;
|
||||
else
|
||||
res = 0;
|
||||
if (ptr->r >= k.u8[1])
|
||||
res |= RED;
|
||||
if (ptr->g >= k.u8[2])
|
||||
res |= GREEN;
|
||||
if (ptr->b >= k.u8[3])
|
||||
res |= BLUE;
|
||||
} else {
|
||||
if (SqrI64(ptr->r) + SqrI64(ptr->g) + SqrI64(ptr->b) >= SqrI64(0x80)) {
|
||||
res = 8;
|
||||
if (ptr->r >= 0x80)
|
||||
res |= RED;
|
||||
if (ptr->g >= 0x80)
|
||||
res |= GREEN;
|
||||
if (ptr->b >= 0x80)
|
||||
res |= BLUE;
|
||||
} else {
|
||||
res = 0;
|
||||
if (ptr->r >= 0x40)
|
||||
res |= RED;
|
||||
if (ptr->g >= 0x40)
|
||||
res |= GREEN;
|
||||
if (ptr->b >= 0x40)
|
||||
res |= BLUE;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#define IMAGE_DITHER_NONE 0
|
||||
#define IMAGE_DITHER_NATIVE 1
|
||||
#define IMAGE_DITHER_FLOYDSTEINBERG 2
|
||||
|
||||
U0 @image_render_4bit_floydstein(U8* buffer, I32 width, I32 height)
|
||||
{
|
||||
U64 reg RDI rdi = buffer;
|
||||
U64 reg RSI rsi = width;
|
||||
U64 reg RDX rdx = height;
|
||||
no_warn rdi, rsi, rdx;
|
||||
asm {
|
||||
MOV RAX, RENDER_4BIT_FLOYDSTEIN
|
||||
CALL RAX
|
||||
}
|
||||
}
|
||||
|
||||
CDC* @image_render_16color_native(U8* pixels, I32 x, I32 y, Bool dither)
|
||||
{
|
||||
I64 i;
|
||||
I64 j;
|
||||
I64 cnt = 0;
|
||||
CBGR24 cbgr24;
|
||||
CDC* dc = DCNew(x, y);
|
||||
for (i = 0; i < y; i++)
|
||||
for (j = 0; j < x; j++) {
|
||||
cbgr24.r = pixels[cnt];
|
||||
cbgr24.g = pixels[cnt + 1];
|
||||
cbgr24.b = pixels[cnt + 2];
|
||||
if (!pixels[cnt + 3])
|
||||
dc->color = TRANSPARENT;
|
||||
else
|
||||
dc->color = @image_cbgr24_to_4_bit(&cbgr24, dither);
|
||||
GrPlot(dc, j, y - i - 1);
|
||||
cnt += 4;
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
CBGR24 @image_palette_std[COLORS_NUM] = {
|
||||
0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
|
||||
0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
|
||||
0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
|
||||
0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
|
||||
};
|
||||
|
||||
CBGR24 @image_dif_rgb(CBGR24 from, CBGR24 to)
|
||||
{
|
||||
CBGR24 dif;
|
||||
dif.r = to.r - from.r;
|
||||
dif.g = to.g - from.g;
|
||||
dif.b = to.b - from.b;
|
||||
return dif;
|
||||
}
|
||||
|
||||
F64 @image_dist_rgb(CBGR24 from, CBGR24 to)
|
||||
{
|
||||
CBGR24 dif = @image_dif_rgb(from, to);
|
||||
F64 dist = dif.r * dif.r + dif.g * dif.g + dif.b * dif.b;
|
||||
return dist;
|
||||
}
|
||||
|
||||
I64 @image_get_4bit_color(CBGR24* cbgr24)
|
||||
{
|
||||
F64 dist = -1, tempDist;
|
||||
I64 i;
|
||||
I64 color = TRANSPARENT;
|
||||
for (i = 0; i < COLORS_NUM; i++) {
|
||||
tempDist = @image_dist_rgb(*cbgr24, @image_palette_std[i]);
|
||||
if (tempDist < dist || dist < 0) {
|
||||
dist = tempDist;
|
||||
color = i;
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
CDC* @image_render_16color_floydsteinberg(U8* pixels, I32 width, I32 height)
|
||||
{
|
||||
@image_render_4bit_floydstein(pixels, width, height);
|
||||
I64 i;
|
||||
I64 j;
|
||||
I64 cnt = 0;
|
||||
CBGR24 cbgr24;
|
||||
CDC* dc = DCNew(width, height);
|
||||
for (i = 0; i < height; i++)
|
||||
for (j = 0; j < width; j++) {
|
||||
cbgr24.r = pixels[cnt];
|
||||
cbgr24.g = pixels[cnt + 1];
|
||||
cbgr24.b = pixels[cnt + 2];
|
||||
if (!pixels[cnt + 3])
|
||||
dc->color = TRANSPARENT;
|
||||
else
|
||||
dc->color = @image_get_4bit_color(&cbgr24);
|
||||
GrPlot(dc, j, height - i - 1);
|
||||
cnt += 4;
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
CDC* @image_generate_dc_from_pixels(U8* pixels, I32 width, I32 height, Bool dither = IMAGE_DITHER_FLOYDSTEINBERG)
|
||||
{
|
||||
switch (dither) {
|
||||
case IMAGE_DITHER_NONE:
|
||||
case IMAGE_DITHER_NATIVE:
|
||||
return @image_render_16color_native(pixels, width, height, dither);
|
||||
break;
|
||||
case IMAGE_DITHER_FLOYDSTEINBERG:
|
||||
return @image_render_16color_floydsteinberg(pixels, width, height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U8* @image_load_gif_from_memory(U8* buffer, I64 len, I64** delays, I64* x, I64* y,
|
||||
I64* z)
|
||||
{
|
||||
U64 reg RDI rdi = buffer;
|
||||
U64 reg RSI rsi = len;
|
||||
U64 reg RDX rdx = delays;
|
||||
U64 reg RCX rcx = x;
|
||||
U64 reg R8 r8 = y;
|
||||
U64 reg R9 r9 = z;
|
||||
no_warn rdi, rsi, rdx, rcx, r8, r9;
|
||||
asm {
|
||||
MOV RAX, IMAGE_LOAD_GIF_FROM_MEMORY
|
||||
CALL RAX
|
||||
}
|
||||
}
|
||||
|
||||
U8* @stbi_failure_reason()
|
||||
{
|
||||
asm {
|
||||
MOV RAX, STBI_FAILURE_REASON
|
||||
CALL RAX
|
||||
}
|
||||
}
|
||||
|
||||
I32 @stbi_info_from_memory(U8* buffer, I64 len, I64* x, I64* y, I64* comp)
|
||||
{
|
||||
U64 reg RDI rdi = buffer;
|
||||
U64 reg RSI rsi = len;
|
||||
U64 reg RDX rdx = x;
|
||||
U64 reg RCX rcx = y;
|
||||
U64 reg R8 r8 = comp;
|
||||
no_warn rdi, rsi, rdx, rcx, r8;
|
||||
asm {
|
||||
MOV RAX, STBI_INFO_FROM_MEMORY
|
||||
CALL RAX
|
||||
}
|
||||
}
|
||||
|
||||
U8* @stbi_load_from_memory(U8* buffer, I64 len, I64* x, I64* y,
|
||||
I64* channels_in_file, I64 desired_channels)
|
||||
{
|
||||
U64 reg RDI rdi = buffer;
|
||||
U64 reg RSI rsi = len;
|
||||
U64 reg RDX rdx = x;
|
||||
U64 reg RCX rcx = y;
|
||||
U64 reg R8 r8 = channels_in_file;
|
||||
U64 reg R9 r9 = desired_channels;
|
||||
no_warn rdi, rsi, rdx, rcx, r8, r9;
|
||||
asm {
|
||||
MOV RAX, STBI_LOAD_FROM_MEMORY
|
||||
CALL RAX
|
||||
}
|
||||
}
|
||||
|
||||
U32* @stbi_write_png_to_mem(U32* pixels, I32 stride_bytes, I32 x, I32 y, I32 n, I32* out_len)
|
||||
{
|
||||
U64 reg RDI rdi = pixels;
|
||||
U64 reg RSI rsi = stride_bytes;
|
||||
U64 reg RDX rdx = x;
|
||||
U64 reg RCX rcx = y;
|
||||
U64 reg R8 r8 = n;
|
||||
U64 reg R9 r9 = out_len;
|
||||
no_warn rdi, rsi, rdx, rcx, r8, r9;
|
||||
asm {
|
||||
MOV RAX, STBI_WRITE_PNG_TO_MEM
|
||||
CALL RAX
|
||||
}
|
||||
}
|
||||
|
||||
CDC* @image_load(U8* filename)
|
||||
{
|
||||
if (!filename || !FileFind(filename)) {
|
||||
// PrintErr("Image file not found.\n");
|
||||
return NULL;
|
||||
}
|
||||
I64 len;
|
||||
I32 x;
|
||||
I32 y;
|
||||
I32 comp;
|
||||
U8* buffer = FileRead(filename, &len);
|
||||
I32 code = @stbi_info_from_memory(buffer, len, &x, &y, &comp);
|
||||
if (code != 1) {
|
||||
Free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
U8* pixels = @stbi_load_from_memory(buffer, len, &x, &y, &comp, 4);
|
||||
Free(buffer);
|
||||
CDC* dc = @image_generate_dc_from_pixels(pixels, x, y);
|
||||
Free(pixels);
|
||||
return dc;
|
||||
}
|
||||
|
||||
U32 @image_rgba_color_table[16] = {
|
||||
0xff000000, 0xffaa0000, 0xff00aa00, 0xffaaaa00,
|
||||
0xff0000aa, 0xffaa00aa, 0xff0055aa, 0xffaaaaaa,
|
||||
0xff555555, 0xffff5555, 0xff55ff55, 0xffffff55,
|
||||
0xff5555ff, 0xffff55ff, 0xff55ffff, 0xffffffff
|
||||
};
|
||||
|
||||
U32 @image_get_rgba_color(I64 color)
|
||||
{
|
||||
if (color > 15)
|
||||
return 0;
|
||||
return @image_rgba_color_table[color];
|
||||
}
|
||||
|
||||
U32* @image_get_rgba_buffer_from_dc_body(CDC* dc)
|
||||
{
|
||||
if (!dc)
|
||||
return NULL;
|
||||
U32* pixels = CAlloc((dc->width * dc->height) * 4, erythros_mem_task);
|
||||
I64 x;
|
||||
I64 y;
|
||||
I64 p = 0;
|
||||
for (y = 0; y < dc->height; y++)
|
||||
for (x = 0; x < dc->width; x++)
|
||||
pixels[p++] = @image_get_rgba_color(GrPeek(dc, x, y));
|
||||
return pixels;
|
||||
}
|
||||
|
||||
U0 @image_write(U8* filename, CDC* dc)
|
||||
{
|
||||
if (!dc) {
|
||||
PrintErr("Device context is NULL.\n");
|
||||
return;
|
||||
}
|
||||
I32 out_len;
|
||||
U32* rgba_buffer = @image_get_rgba_buffer_from_dc_body(dc);
|
||||
if (!rgba_buffer) {
|
||||
PrintErr("RGBA buffer is NULL.\n");
|
||||
return;
|
||||
}
|
||||
U8* png_buffer = @stbi_write_png_to_mem(rgba_buffer, dc->width * 4, dc->width, dc->height, 4, &out_len);
|
||||
if (!png_buffer) {
|
||||
PrintErr("PNG buffer is NULL.\n");
|
||||
Free(rgba_buffer);
|
||||
return;
|
||||
}
|
||||
FileWrite(filename, png_buffer, out_len);
|
||||
Free(rgba_buffer);
|
||||
Free(png_buffer);
|
||||
}
|
||||
|
||||
U32 @image_pixel_flip_rgb_bgr(U32 src)
|
||||
{
|
||||
U32 dst;
|
||||
dst.u8[0] = src.u8[2];
|
||||
dst.u8[1] = src.u8[1];
|
||||
dst.u8[2] = src.u8[0];
|
||||
dst.u8[3] = src.u8[3];
|
||||
return dst;
|
||||
}
|
||||
|
||||
CDC* @image_from_buffer(U8* buffer, I64 len)
|
||||
{
|
||||
I32 x = 0;
|
||||
I32 y = 0;
|
||||
U8* pixels = NULL;
|
||||
CDC* dc = NULL;
|
||||
|
||||
I32 comp;
|
||||
I32 code = @stbi_info_from_memory(buffer, len, &x, &y, &comp);
|
||||
if (code != 1) {
|
||||
return NULL;
|
||||
}
|
||||
pixels = @stbi_load_from_memory(buffer, len, &x, &y, &comp, 4);
|
||||
if (!pixels)
|
||||
PopUpOk(@stbi_failure_reason);
|
||||
dc = @image_generate_dc_from_pixels(pixels, x, y);
|
||||
Free(pixels);
|
||||
return dc;
|
||||
}
|
||||
|
||||
@image_collection* @image_collection_from_buffer(U8* buffer, I64 len)
|
||||
{
|
||||
I64 i;
|
||||
I32* delays;
|
||||
I32 x;
|
||||
I32 y;
|
||||
I32 z;
|
||||
I32 comp;
|
||||
I32 code = @stbi_info_from_memory(buffer, len, &x, &y, &comp);
|
||||
if (code != 1) {
|
||||
return NULL;
|
||||
}
|
||||
U64 pixels = @image_load_gif_from_memory(buffer, len, &delays, &x, &y, &z);
|
||||
if (!pixels)
|
||||
PopUpOk(@stbi_failure_reason);
|
||||
if (!z)
|
||||
return NULL; // no frames?
|
||||
@image_collection* collection = CAlloc(sizeof(@image_collection), erythros_mem_task);
|
||||
@image_frame* frame;
|
||||
collection->frames = CAlloc(sizeof(@image_frame*) * z, erythros_mem_task);
|
||||
collection->count = z;
|
||||
for (i = 0; i < z; i++) {
|
||||
frame = CAlloc(sizeof(@image_frame), erythros_mem_task);
|
||||
frame->dc = @image_generate_dc_from_pixels(pixels, x, y);
|
||||
frame->sprite = DC2Sprite(frame->dc);
|
||||
frame->delay = delays[i];
|
||||
collection->frames[i] = frame;
|
||||
pixels += (x * y) * 4;
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
// Image.FromBuffer = &@image_from_buffer;
|
||||
// Image.Load = &@image_load;
|
||||
// Image.Write = &@image_write;
|
||||
|
||||
Silent(0);
|
||||
|
||||
U0 Screenshot(U8* custom_filename = NULL, Bool output_filename_to_focus_task = FALSE)
|
||||
{
|
||||
CDC* dc = DCScrnCapture;
|
||||
U8 filename[256];
|
||||
CDateStruct ds;
|
||||
if (custom_filename)
|
||||
StrCpy(filename, custom_filename);
|
||||
else {
|
||||
Date2Struct(&ds, Now);
|
||||
StrPrint(filename, "C:/Tmp/ScrnShots/%04d-%02d-%02d-%02d-%02d-%02d.png", ds.year, ds.mon, ds.day_of_mon, ds.hour, ds.min, ds.sec);
|
||||
}
|
||||
@image_write(filename, dc);
|
||||
DCDel(dc);
|
||||
if (output_filename_to_focus_task)
|
||||
XTalk(sys_focus_task, filename);
|
||||
};
|
||||
|
||||
U0 @screenshot_hotkey(I64)
|
||||
{
|
||||
Screenshot("C:/Home/Screenshot.png", TRUE);
|
||||
}
|
||||
|
||||
CtrlAltCBSet('S', &@screenshot_hotkey, "", , FALSE);
|
22
System/Utilities/NetRep.HC
Normal file
22
System/Utilities/NetRep.HC
Normal file
|
@ -0,0 +1,22 @@
|
|||
U0 NetRep()
|
||||
{
|
||||
NetInfoRequest* req = @net_info_request;
|
||||
"MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n", req->mac_address.u8[5], req->mac_address.u8[4],
|
||||
req->mac_address.u8[3], req->mac_address.u8[2],
|
||||
req->mac_address.u8[1], req->mac_address.u8[0];
|
||||
"IPv4 address : %d.%d.%d.%d\n", req->ipv4_address.u8[3], req->ipv4_address.u8[2],
|
||||
req->ipv4_address.u8[1], req->ipv4_address.u8[0];
|
||||
"IPv4 netmask : %d.%d.%d.%d\n", req->ipv4_netmask.u8[3], req->ipv4_netmask.u8[2],
|
||||
req->ipv4_netmask.u8[1], req->ipv4_netmask.u8[0];
|
||||
"IPv4 network : %d.%d.%d.%d\n", req->ipv4_network.u8[3], req->ipv4_network.u8[2],
|
||||
req->ipv4_network.u8[1], req->ipv4_network.u8[0];
|
||||
"IPv4 gateway : %d.%d.%d.%d\n", req->ipv4_gateway.u8[3], req->ipv4_gateway.u8[2],
|
||||
req->ipv4_gateway.u8[1], req->ipv4_gateway.u8[0];
|
||||
"DNS server (port) : %d.%d.%d.%d (%d)\n", req->dns_server_address.u8[3], req->dns_server_address.u8[2],
|
||||
req->dns_server_address.u8[1], req->dns_server_address.u8[0], req->dns_server_port;
|
||||
"RX bytes : %d\n", req->rx_bytes;
|
||||
"RX frames : %d\n", req->rx_frames;
|
||||
"TX bytes : %d\n", req->tx_bytes;
|
||||
"TX frames : %d\n", req->tx_frames;
|
||||
Free(req);
|
||||
}
|
72
System/Utilities/Ping.HC
Normal file
72
System/Utilities/Ping.HC
Normal file
|
@ -0,0 +1,72 @@
|
|||
#define PING_ERR_INVALID_HOST 1
|
||||
#define PING_ERR_HOST_NOT_FOUND 2
|
||||
|
||||
#define PING_PAYLOAD_SIZE 56
|
||||
|
||||
I64 @ping_err(I64 code)
|
||||
{
|
||||
switch (code) {
|
||||
case PING_ERR_INVALID_HOST:
|
||||
"Invalid host specified\n";
|
||||
return 1;
|
||||
break;
|
||||
case PING_ERR_HOST_NOT_FOUND:
|
||||
"Host not found\n";
|
||||
return 2;
|
||||
break;
|
||||
default:
|
||||
"Unspecified error\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
I64 Ping(U8* host, I64 count = 4)
|
||||
{
|
||||
if (!host)
|
||||
return @ping_err(PING_ERR_INVALID_HOST);
|
||||
if (!StrLen(host))
|
||||
return @ping_err(PING_ERR_INVALID_HOST);
|
||||
|
||||
U32 addr = @dns_query(host);
|
||||
if (addr == U32_MAX)
|
||||
return @ping_err(PING_ERR_HOST_NOT_FOUND);
|
||||
|
||||
U16 iden = (RandU16 * SysTimerRead) & 0xFFFF;
|
||||
I64 start_jiffies;
|
||||
U32 reply = NULL;
|
||||
I64 res = 0;
|
||||
U16 seq = 0;
|
||||
I64 loss = 0;
|
||||
|
||||
IcmpRequest* request = CAlloc(sizeof(IcmpRequest), Fs->code_heap);
|
||||
|
||||
"PING %s (%d.%d.%d.%d): %d data bytes\n",
|
||||
host, addr.u8[3], addr.u8[2], addr.u8[1], addr.u8[0], PING_PAYLOAD_SIZE;
|
||||
|
||||
I64 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
start_jiffies = cnts.jiffies;
|
||||
reply = @icmp_echo_request(addr, iden, seq, request, i);
|
||||
if (!reply) {
|
||||
"Request timeout for icmp_seq %d\n", seq;
|
||||
++loss;
|
||||
res = 1;
|
||||
} else {
|
||||
"%d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=%d time=%d ms\n",
|
||||
reply.u16[1], addr.u8[3], addr.u8[2], addr.u8[1], addr.u8[0], seq, reply.u16[0], cnts.jiffies - start_jiffies;
|
||||
}
|
||||
while (cnts.jiffies < start_jiffies + 1000 && i < (count - 1))
|
||||
Sleep(1);
|
||||
++seq;
|
||||
}
|
||||
|
||||
Free(request);
|
||||
|
||||
"--- %d.%d.%d.%d ping statistics ---\n", addr.u8[3], addr.u8[2], addr.u8[1], addr.u8[0];
|
||||
"%d packets transmitted, %d packets received, %0f",
|
||||
seq, seq - loss, (loss * 1.0 / seq * 1.0) * 100;
|
||||
PutChars(37);
|
||||
" packet loss\n";
|
||||
|
||||
return res;
|
||||
}
|
92
System/Utilities/Time.HC
Normal file
92
System/Utilities/Time.HC
Normal file
|
@ -0,0 +1,92 @@
|
|||
U0 @time_cmos_update_byte(I64 time_reg, I64 val)
|
||||
{
|
||||
OutU8(0x70, time_reg);
|
||||
OutU8(0x71, val);
|
||||
}
|
||||
|
||||
I64 @time_dec_to_bcd(I64 val)
|
||||
{
|
||||
return (((val / 10) << 4) | (val % 10));
|
||||
}
|
||||
|
||||
U0 @time_update(U8* date_str, I64 mS_delta, I64 hour_offset)
|
||||
{
|
||||
no_warn mS_delta;
|
||||
Bool is_bcd;
|
||||
OutU8(0x70, 0x0B);
|
||||
if (InU8(0x71) & 4)
|
||||
is_bcd = FALSE;
|
||||
else
|
||||
is_bcd = TRUE;
|
||||
|
||||
I64 date_argc;
|
||||
U8** date_argv = String.Split(date_str, ' ', &date_argc);
|
||||
|
||||
I64 month = DefineMatch(date_argv[2], "ST_MONTHS") + 1;
|
||||
I64 day = Str2I64(date_argv[1]);
|
||||
I64 year = Str2I64(date_argv[3] + 2);
|
||||
I64 century = 20;
|
||||
|
||||
date_argv[4][2] = NULL;
|
||||
date_argv[4][5] = NULL;
|
||||
|
||||
I64 hour = Str2I64(date_argv[4]);
|
||||
I64 minute = Str2I64(date_argv[4] + 3);
|
||||
I64 second = Str2I64(date_argv[4] + 6);
|
||||
|
||||
// FIXME: Handle month boundaries, and 12 hour time
|
||||
hour += hour_offset;
|
||||
if (hour < 0) {
|
||||
hour += 24;
|
||||
--day;
|
||||
} else if (hour > 23) {
|
||||
hour -= 24;
|
||||
++day;
|
||||
}
|
||||
|
||||
if (is_bcd) {
|
||||
century = @time_dec_to_bcd(century);
|
||||
year = @time_dec_to_bcd(year);
|
||||
month = @time_dec_to_bcd(month);
|
||||
day = @time_dec_to_bcd(day);
|
||||
hour = @time_dec_to_bcd(hour);
|
||||
minute = @time_dec_to_bcd(minute);
|
||||
second = @time_dec_to_bcd(second);
|
||||
}
|
||||
|
||||
@time_cmos_update_byte(0x32, century);
|
||||
@time_cmos_update_byte(0x09, year);
|
||||
@time_cmos_update_byte(0x08, month);
|
||||
@time_cmos_update_byte(0x07, day);
|
||||
@time_cmos_update_byte(0x04, hour);
|
||||
@time_cmos_update_byte(0x02, minute);
|
||||
@time_cmos_update_byte(0x00, second);
|
||||
}
|
||||
|
||||
I64 @time_tz_offset()
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
|
||||
U0 @time_query(Bool set = FALSE)
|
||||
{
|
||||
U8 buf[1024];
|
||||
@http_url* url = @http_parse_url("http://time.google.com");
|
||||
@http_response* resp = Http.Head(url, &buf);
|
||||
while (resp->state != HTTP_STATE_DONE)
|
||||
Sleep(1);
|
||||
I64 mS_delta = cnts.jiffies;
|
||||
"Set current date and time to %s ", resp->headers->@("Date");
|
||||
if (!set)
|
||||
set = YorN;
|
||||
else
|
||||
"\n";
|
||||
if (set)
|
||||
@time_update(resp->headers->@("Date"), mS_delta, @time_tz_offset);
|
||||
}
|
||||
|
||||
U0 TimeSync()
|
||||
{
|
||||
Sleep(500);
|
||||
@time_query(1);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue