From 257b43dc23442208256d9412244cd5146c552342 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 2 Mar 2025 15:10:04 -0500 Subject: [PATCH 1/2] Fix HuCC compiler bug when a call to a __fastcall function is split over multiple lines of the C source file. --- src/hucc/function.c | 55 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/hucc/function.c b/src/hucc/function.c index 114021ba..e29a4ae0 100644 --- a/src/hucc/function.c +++ b/src/hucc/function.c @@ -623,7 +623,20 @@ void callfunction (SYMBOL *ptr) out_ins(I_FUNCP_WR, 0, 0); } - if (!is_fc) { + if (is_fc) { + /* switch to the alternate instruction queue so that */ + /* the temporary stacking of arguments does not mess */ + /* up optimizing statements that use function calls. */ + if (which_queue++ == 0) { + saved_rd = q_rd; + saved_wr = q_wr; + saved_nb = q_nb; + q_ins = arg_queue; + q_rd = 0; + q_wr = Q_SIZE - 1; + q_nb = 0; + } + } else { /* fastcall functions should not count against C is_leaf_function status */ is_leaf_function = 0; /* calling regular functions in fastcall arguments is OK */ @@ -638,31 +651,10 @@ void callfunction (SYMBOL *ptr) if (is_fc) { int nfc = func_call_stack; - /* switch to the alternate instruction queue so that */ - /* the temporary stacking of arguments does not mess */ - /* up optimizing statements that use function calls. */ - if (which_queue++ == 0) { - saved_rd = q_rd; - saved_wr = q_wr; - saved_nb = q_nb; - q_ins = arg_queue; - q_rd = 0; - q_wr = Q_SIZE - 1; - q_nb = 0; - } - new_arg_stack(arg_idx++); expression(NO); flush_ins(); - /* switch back to the normal instruction queue */ - if (--which_queue == 0) { - q_ins = ins_queue; - q_rd = saved_rd; - q_wr = saved_wr; - q_nb = saved_nb; - } - stkp = stkp - INTSIZE; /* Check if we had a fastcall in our argument. */ @@ -684,23 +676,32 @@ void callfunction (SYMBOL *ptr) break; } - /* adjust arg stack */ + /* fastcall func */ if (is_fc) { + /* just in case the final match() caused an I_INFO output */ + flush_ins(); + + /* terminate the final stacked argument */ if (argcnt) { arg_list[arg_idx - 1][1] = arg_stack_idx; arg_idx -= argcnt; } - if (argcnt && arg_idx) arg_stack_idx = arg_list[arg_idx - 1][1]; else { arg_stack_idx = 0; arg_stack_flag = 0; } - } - /* fastcall func */ - if (is_fc) { + /* switch back to the normal instruction queue */ + if (--which_queue == 0) { + q_ins = ins_queue; + q_rd = saved_rd; + q_wr = saved_wr; + q_nb = saved_nb; + } + + /* confirm that a fastcall exists with this number of parameters */ is_fc = fastcall_look(ptr->name, argcnt, &fast); /* flush arg instruction stacks */ From d4fc61cc9616129594dc819e6c912a1def338cfd Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 2 Mar 2025 15:43:51 -0500 Subject: [PATCH 2/2] Add HuC's "scroll" example to HuCC, modified to use the new scroll library. --- examples/hucc/Makefile | 2 +- examples/hucc/scroll/Makefile | 10 ++ examples/hucc/scroll/make.cmd | 70 ++++++++++ examples/hucc/scroll/scroll.c | 229 ++++++++++++++++++++++++++++++++ examples/hucc/scroll/scroll.pcx | Bin 0 -> 4074 bytes 5 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 examples/hucc/scroll/Makefile create mode 100644 examples/hucc/scroll/make.cmd create mode 100644 examples/hucc/scroll/scroll.c create mode 100644 examples/hucc/scroll/scroll.pcx diff --git a/examples/hucc/Makefile b/examples/hucc/Makefile index 4d6c63c8..3c46cd25 100644 --- a/examples/hucc/Makefile +++ b/examples/hucc/Makefile @@ -2,7 +2,7 @@ # Makefile for examples # -SUBDIRS = sgx shmup +SUBDIRS = scroll sgx shmup all clean: @$(MAKE) $(SUBDIRS) "COMMAND=$@" diff --git a/examples/hucc/scroll/Makefile b/examples/hucc/scroll/Makefile new file mode 100644 index 00000000..5ad6fedc --- /dev/null +++ b/examples/hucc/scroll/Makefile @@ -0,0 +1,10 @@ +all: scroll.pce + +include ../Make_ex.inc + +SRC = scroll.c + +CFLAGS ?= -v -O2 -fno-recursive -gC + +scroll.pce: $(SRC) + $(CC) $(CFLAGS) $(SRC) $(LIBS) diff --git a/examples/hucc/scroll/make.cmd b/examples/hucc/scroll/make.cmd new file mode 100644 index 00000000..aaaa2510 --- /dev/null +++ b/examples/hucc/scroll/make.cmd @@ -0,0 +1,70 @@ +@rem ************************************************************************ +@rem ************************************************************************ +@rem +@rem make.cmd +@rem +@rem Build a project with a native Windows version of Linux and macOS "make". +@rem +@rem Copyright John Brandwood 2025. +@rem +@rem Distributed under the Boost Software License, Version 1.0. +@rem (See accompanying file LICENSE_1_0.txt or copy at +@rem http://www.boost.org/LICENSE_1_0.txt) +@rem +@rem ************************************************************************ +@rem ************************************************************************ +@rem +@rem Put this in your project's directory on Windows to automatically set the +@rem PATH and PCE_INCLUDE environment variables if your project is located in +@rem a directory within the main HuC folder tree. +@rem +@rem Then mingw32-make.exe is run to build the project using its Makefile. +@rem +@rem You can run this from a Windows "Command Prompt", or by navigating to it +@rem in Windows Explorer and then double-clicking on the file. +@rem +@rem ************************************************************************ +@rem ************************************************************************ + +@echo off + +setlocal + +call :findexe hucc.exe +if not [%EXEFILE%] == [""] goto :gotpath + +cd /d "%~dp0" +set rootdir="%~d0\" +:search +if not exist "%CD%\bin" goto :next +if not exist "%CD%\bin\hucc.exe" goto :next +set PATH=%CD%\bin;%PATH% +set PCE_INCLUDE=%CD%\include\hucc +goto :gotpath +:next +if not ["%CD%"] == [%rootdir%] ( + cd .. + goto :search +) +echo. +echo Unable to locate hucc.exe, please set up your PATH and PCE_INCLUDE +echo environment variables! +if /i "%comspec% /c %~0 " equ "%cmdcmdline:"=%" ( + echo. + pause +) +exit /b 1 + +:findexe +set EXEFILE="%~$PATH:1" +goto :eof + +:gotpath +cd /d "%~dp0" +mingw32-make.exe %* + +rem Pause if this was run by doubleclicking on the file in Explorer. +if /i "%comspec% /c %~0 " equ "%cmdcmdline:"=%" ( + echo. + pause +) diff --git a/examples/hucc/scroll/scroll.c b/examples/hucc/scroll/scroll.c new file mode 100644 index 00000000..df473b6c --- /dev/null +++ b/examples/hucc/scroll/scroll.c @@ -0,0 +1,229 @@ +/* + * file: scroll.c + * description: a three-screen horizontal scrolling demo + * author: David Michel (dmichel@easynet.fr) + * date: 2000.08.16 + * files: scroll.pcx + * version: 1.0 + */ + +#include "huc.h" +#include "hucc-scroll.h" + +#define TRUE 1 +#define FALSE 0 + +/* vram allocation */ +#define TILE_VRAM 0x1000 +#define PANEL_VRAM 0x2000 +#define SPRITE_VRAM 0x4000 + +/* palette allocation */ +#define TILE_PAL 0 +#define PANEL_PAL 2 +#define SPRITE_PAL 16 + +/* tiles */ +#inctile(tile_gfx, "scroll.pcx", 4, 3) +#incpal(tile_pal, "scroll.pcx", 0) + +/* sprites */ +#incspr(sprite, "scroll.pcx", 64, 0, 2, 1) +#incpal(sprite_pal, "scroll.pcx", 1) + +/* control panel */ +#incchr(panel_gfx, "scroll.pcx", 0, 48, 32, 4) +#incpal(panel_pal, "scroll.pcx", 2) +#incbat(panel_bat, "scroll.pcx", PANEL_VRAM, 0, 48, 32, 4) + +/* define the demo map + * + * (should be #incbin'ed if the map is big + * or uses more than a dozen of tiles) + */ +#define MAP_WIDTH 48 +#define MAP_HEIGHT 12 +#define NB_TILE 12 + +const char demo_map[] = { + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,6,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,4,5,4,5,4,5,4,5,4, 4,4,5,5,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,4,6,4,5,4,5,4,5,4, 5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,4,4,4,5,4,5,4,5,4, 5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,4,5,4,5,4,5,4,5,4, 6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,4,5,4,5,4,4,4,5,4, 4,4,5,5,4,5,6,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,0,8,2,2,2,2,2,2,2,2,2, 2,2,2,0,0,0,2,2,0,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6, 5,7,7,7,7,0,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,5,5,5,5,5,5,6, + 2,5,5,5,5,5,6,5,5,5,5,5,5,5,5,8, 2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,9,9,9,9,9,8,2, + 1,5,7,7,2,2,2,0,0,8,9,9,9,9,9,0, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,1, + 1,2,2,2,1,1,1,1,1,0,3,3,3,3,3,0, 1,1,1,1,1,1,1,1,1,0,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,1, + 1,1,1,1,1,1,1,1,1,0,3,3,3,3,3,0, 1,1,1,1,1,1,1,1,1,0,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,1 +}; + +/* palette index for tiles (one index per tile) */ +const char tile_pal_ref[NB_TILE] = { + TILE_PAL<<4, TILE_PAL<<4, TILE_PAL<<4, TILE_PAL<<4, + TILE_PAL<<4, TILE_PAL<<4, TILE_PAL<<4, TILE_PAL<<4, + TILE_PAL<<4, TILE_PAL<<4, TILE_PAL<<4, TILE_PAL<<4 +}; + +/* scroll vars */ +int tx; +int sx, sy; +int map_x; +int dir; + +pause() +{ + /* show 'paused' sprite */ + spr_set(0); + spr_pal(SPRITE_PAL); + spr_pattern(SPRITE_VRAM); + spr_ctrl(SIZE_MAS|FLIP_MAS, SZ_32x16|NO_FLIP); + spr_pri(1); + spr_x(112); + spr_y(88); + satb_update(); + + /* wait that the user press START again */ + do { + vsync(); + } while (!(joytrg(0) & JOY_STRT)); + + /* hide sprite */ + spr_hide(); + satb_update(); +} + +main() +{ + int flag; + int score; + + /* disable display */ + disp_off(); + + /* clear display */ + cls(); + + /* init sprite */ + load_sprites(SPRITE_VRAM, sprite, 1); + load_palette(SPRITE_PAL, sprite_pal, 1); + + /* init map */ + set_map_data(demo_map, MAP_WIDTH, MAP_HEIGHT); + set_tile_data(tile_gfx, NB_TILE, tile_pal_ref, 16); + load_tile(TILE_VRAM); + load_palette(TILE_PAL, tile_pal, 1); + load_map(0, 0, 0, 0, 17, 12); + + /* init font */ + set_font_color(1, 10); + set_font_pal(PANEL_PAL); + load_default_font(); + + /* init control panel */ + load_vram(PANEL_VRAM, panel_gfx, 2048); + load_bat(0x600, panel_bat, 32, 4); + load_palette(PANEL_PAL, panel_pal, 1); + put_string("score: ", 1, 25); + + /* split screen */ + scroll_split(0, 0, 0, 0, BKG_ON | SPR_ON); + scroll_split(1, 192, 0, 192, BKG_ON); + + /* enable display */ + disp_on(); + + /* init scroll */ + sx = 0; + tx = 0; + dir = 1; + map_x = 0; + score = 0; + + /* demo main loop */ + for (;;) + { + /* check if we should pause */ + if (joytrg(0) & JOY_STRT) { + pause(); + } + + /* get move direction */ + if (joy(0) & JOY_LEFT) { + dir = -1; + flag = TRUE; + } + else + if (joy(0) & JOY_RGHT) { + dir = 1; + flag = TRUE; + } + else { + flag = FALSE; + } + + /* calculate the new scroll position */ + if (flag == TRUE) + tx = sx + (dir << 1); + else + tx = sx + (dir); + + /* compare the old and new screen position + * (on a tile basis), and update the screen map + * if they are different + */ + if((tx & 0xFFF0) != (sx & 0xFFF0)) { + /* right dir */ + if (dir == 1) { + map_x = map_x + 1; + + if (map_x > MAP_WIDTH) + map_x -= MAP_WIDTH; + + load_map( + (tx + 256) >> 4, /* screen x coordinate (in tile unit) */ + 0, /* screen y */ + map_x + 16, /* map x */ + 0, /* map y */ + 1, /* nb of map column to load */ + 12); /* nb of row */ + } + + /* left dir */ + else { + map_x = map_x - 1; + + if (map_x < 0) + map_x += MAP_WIDTH; + + load_map( + (tx) >> 4, /* screen x coordinate */ + 0, /* screen y */ + map_x, /* map x */ + 0, /* map y */ + 1, /* nb of map column to load */ + 12); /* nb of row */ + } + score += 1; + } + + /* earthquake :) */ + if (!(joy(0) & (JOY_A | JOY_B))) + sy = 0; + else { + sy = rand() & 0x07; + score += sy; + } + + /* display score */ + put_number(score, 5, 8, 25); + + /* set new scroll position */ + sx = tx; + scroll_split(0, 0, sx, sy, BKG_ON | SPR_ON); + vsync(); + } +} + diff --git a/examples/hucc/scroll/scroll.pcx b/examples/hucc/scroll/scroll.pcx new file mode 100644 index 0000000000000000000000000000000000000000..89209d8df466ad9a093d47876f24d43c7e4babb0 GIT binary patch literal 4074 zcmeHKZ)g)|9DXj>|E1nw@rHH~eC4ohWgV3iHOOi*y(3%~vD($FMzA2tSK(EF2n z?|Gl!pZB@0!#tK9gm0bYBGN`fn#&2 z4={RH;`$I2OYx2V>DILrQfjfmpBUH7lf7+m9c28r}yW+O;ib0l#t)E7}edV z-r1{G6xHu_xzo{|sH^j(gA_O}>rwIMz8_*0o$X_6)#vuQeNL~_*Esx^>w^rmrumTR zPR!9=J_9qK5ZG+|czx`r0k+ybV!nv6X(N===QXUHAZ9aed#sZNB3BM)xYSQfwf3k zQ<%a8w)0}D5_WyXHyPznS?N-|P@Tg$98r&jgGb-uWH}PzWSq9JOB{AfE&-9fwB}cd zXl}sm7|jO$D83M0jCa`FkN5&=p@(rNtSX-Bge#rH77-RyW2Kdc@vx%`W^@GLWwjV` z{BHGr_pT~6r1j#|79CdoUxW}i{)8?$KII63t zPSjC(dbEaFsYUqRJF@jDa>IDa1Fr*ZN)EDJR` z>Pf38jjIxu*O9N{lOi$&tjLwS@=ie(^733pj#|<(qyZU}c)x?oFFb~}2(1L|Hni)| zrlDPemV-6{Z46opS`u9rR*71&k(QK(l$<5j*HNvaSZpRVj*}-jA+8s#Thh28QIPm* z9p|bzUBqa?m!TBMkf(GekYNuY%u4XlObClW3Ahbh2d05bKn|Dy#()%%1gz()^mLw9 zZK~y{lBSYHvj*J+eT%1gET6?}2KG^0IE?ZA7#V;?Jb-y3nw6Rw+D=! ze^o&X(-cWlWKCh4LYTHNv%*aJ==-Kfo8pow=FAyk=7f1nButSq#TTZy?Q_2u=A