Author Topic: 32bit operations in HuC  (Read 376 times)

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
32bit operations in HuC
« on: August 14, 2016, 06:05:51 PM »
While there doesn't seem to be a 32bit type for HuC, there does seem to be some internal functions for handling 32bit operations via pointers.

 Here's a list of library functions (some may not appear in the library reference help file):

Code: [Select]
/* default pragma's */
static char *pragma_init[] = {
/* far pointer support funcs */
"fastcall farpeekb(farptr _fbank:_fptr)",
"fastcall farpeekw(farptr _fbank:_fptr)",
"fastcall farmemget(word bx, farptr _fbank:_fptr, word acc)",
/* asm-lib wrappers */
"fastcall load_palette(byte al, farptr bl:si, byte cl)",
"fastcall load_bat(word di, farptr bl:si, byte cl, byte ch)",
"fastcall load_vram(word di, farptr bl:si, word cx)",
"fastcall load_vram2(word di, word si, byte bl, word cx)",
"fastcall snd_trkreg(byte al, farptr bl:si)",
/* text funcs */
"fastcall cls(word dx)",
"fastcall set_xres(word ax)",
"fastcall set_xres(word ax, byte cl)",
"fastcall set_font_color(byte al, byte acc)",
"fastcall load_font(farptr bl:si, byte cl)",
"fastcall load_font(farptr bl:si, byte cl, word di)",
"fastcall load_default_font(byte dl)",
"fastcall load_default_font(byte dl, word di)",
"fastcall put_digit(byte, word)",
"fastcall put_digit(byte, byte, byte)",
"fastcall put_char(byte, word)",
"fastcall put_char(byte, byte, byte)",
"fastcall put_raw(word, word)",
"fastcall put_raw(word, byte, byte)",
"fastcall put_number(word, byte, word)",
"fastcall put_number(word, byte, byte, byte)",
"fastcall put_hex(word, byte, word)",
"fastcall put_hex(word, byte, byte, byte)",
"fastcall put_string(word, word)",
"fastcall put_string(word, byte, byte)",
/* gfx lib funcs */
"fastcall gfx_plot(word bx, word cx, word acc)",
"fastcall gfx_point(word bx, word cx)",
"fastcall gfx_line(word bx, word cx, word si, word bp, word acc)",

"fastcall vram_addr(byte al, byte acc)",
"fastcall spr_ctrl(byte al, byte acc)",
"fastcall get_color(word color_reg)",
"fastcall set_color(word color_reg, word color_data) nop",
"fastcall set_color_rgb(word color_reg, byte al, byte ah, byte acc)",
"fastcall fade_color(word ax, byte acc)",
"fastcall fade_color(word color_reg, word ax, byte acc)",
/* map lib funcs */
"fastcall scan_map_table(word si, word ax, word cx)",
"fastcall load_map(byte al, byte ah, word, word, byte dl, byte dh)",
"fastcall set_map_data(word acc)",
"fastcall set_map_data(farptr bl:si, word ax, word acc)",
"fastcall set_map_data(farptr bl:si, word ax, word dx, byte acc)",
"fastcall set_tile_data(word di)",
"fastcall set_tile_data(farptr bl:si, word cx, farptr al:dx)",
"fastcall put_tile(word dx, word acc)",
"fastcall put_tile(word dx, byte al, byte acc)",
"fastcall map_get_tile(byte dl, byte acc)",
"fastcall map_put_tile(byte dl, byte dh, byte acc)",
/* misc funcs */
"fastcall get_joy_events(byte acc)",
"fastcall get_joy_events(byte al, byte acc)",
"fastcall set_joy_callback(byte dl, byte al, byte ah, farptr bl:si)",
"fastcall poke(word bx, word acc)",
"fastcall pokew(word bx, word acc)",
"fastcall srand32(word dx, word cx)",
/* 32-bit math funcs */
"fastcall mov32(word di, dword acc:ax|bx)",
"fastcall add32(word di, dword acc:ax|bx)",
"fastcall sub32(word di, dword acc:ax|bx)",
"fastcall mul32(word bp, dword acc:ax|bx)",
"fastcall div32(word bp, dword acc:ax|bx)",
"fastcall cmp32(word di, dword acc:ax|bx)",
"fastcall com32(word di)",
/* bcd math funcs */
"fastcall bcd_init(word bx, word acc)",
"fastcall bcd_set(word bx, word acc)",
"fastcall bcd_mov(word bx, word acc)",
"fastcall bcd_add(word di, word acc)",
/* bram funcs */
"fastcall bm_rawwrite(word bx, word acc)",
"fastcall bm_read(word di, word bx, word bp, word acc)",
"fastcall bm_write(word di, word bx, word bp, word acc)",
"fastcall bm_create(word bx, word acc)",
"fastcall bm_getptr(word bp, word acc)",
/* string funcs */
"fastcall strcpy(word di, word si)",
"fastcall strncpy(word di, word si, word acc)",
"fastcall strcat(word di, word si)",
"fastcall strncat(word di, word si, word acc)",
"fastcall strcmp(word di, word si)",
"fastcall strncmp(word di, word si, word acc)",
"fastcall memcpy(word di, word si, word acc)",
"fastcall memcmp(word di, word si, word acc)",
/* CDROM funcs */
"fastcall cd_trkinfo(word ax, word cx, word dx, word bp)",
"fastcall cd_playtrk(word bx, word cx, word acc)",
"fastcall cd_playmsf(byte al, byte ah, byte bl, byte cl, byte ch, byte dl, word acc)",
"fastcall cd_loadvram(word di, word si, word bx, word acc)",
"fastcall cd_loaddata(word di, word si, farptr bl:bp, word acc)",
/* ADPCM funcs */
"fastcall ad_trans(word di, word si, byte al, word bx)",
"fastcall ad_read(word cx, byte dh, word bx, word ax)",
"fastcall ad_write(word cx, byte dh, word bx, word ax)",
"fastcall ad_play(word bx, word ax, byte dh, byte dl)",
NULL

 And specifically these ones:
Code: [Select]
/* 32-bit math funcs */
"fastcall mov32(word di, dword acc:ax|bx)",
"fastcall add32(word di, dword acc:ax|bx)",
"fastcall sub32(word di, dword acc:ax|bx)",
"fastcall mul32(word bp, dword acc:ax|bx)",
"fastcall div32(word bp, dword acc:ax|bx)",
"fastcall cmp32(word di, dword acc:ax|bx)",
"fastcall com32(word di)",

And the comments to the libs are:
Code: [Select]
mov32(void *dst [di], void *src)
add32(void *dst [di], void *src) /* ax|bx */
sub32(void *dst [di], void *src)
mul32(void *dst [bp], void *src)
div32(void *dst [di], void *src)
cmp32(void *dst [di], void *src)
com32(void *dst)

The following code worked fine:
   
Code: [Select]
int _LSB0,_MSB0,_LSB1,_MSB1;
int* PTR_0;
int* PTR_1;
.
.
.
.

_LSB0=65535;
_MSB0=0;
_LSB1=65535;
_MSB1=0;
PTR_0 = &_LSB0;
PTR_1 = &_LSB1;
add32(PTR_0, PTR_1);
add32(&_LSB0, 99999);


 The code generation is decent, and doesn't use far pointers like most HuC stuff does. So it should be decently quick.

 Note: Not that it's probably needed, but you can't nest these inside an expression or use as an argument because there is no return type. Even if there was such a return type, HuC couldn't even handle it (it doesn't handle larger than 16bit expressions).

 Also something else to note as interesting; the source is a 32bit pointer but if a local pointer is used, it will just store 0's in the upper 16bits. I mean, it's not like it's using a far pointer or anything (at least from the macro that gets used in the source), but this presents a problem if you try to use the direct reference for the source (&_LSB1) - because it can't be resolved into a dword pointer for some reason (HuC thing).
« Last Edit: August 14, 2016, 06:11:00 PM by Bonknuts »

Bonknuts

  • Hero Member
  • *****
  • Posts: 3292
Re: 32bit operations in HuC
« Reply #1 on: August 15, 2016, 02:00:49 PM »
Just wanted to point out that 32bit operations might seem overkill, but when you need 16bit coords and at least and 8bit float part (fixed point numbers), outside of inline assembly - you aren't going to get it on HuC. Add32 and sub32 are a decent work around for that (16whole:16float).