diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2c769609..aa716cb3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,11 @@ name: build # upvote here https://github.com/github/feedback/discussions/4501 # # See https://github.com/marketplace/actions/setup-xcode-version +# +# Just for reference ... +# +# sudo xcode-select -s "/Applications/Xcode_13.4.1.app" + on: push: pull_request: @@ -20,11 +25,11 @@ jobs: build: strategy: matrix: - os: [ubuntu-20.04, macos-11, macos-12, windows-2022] + os: [ubuntu-22.04, macos-13, macos-14, windows-2022] runs-on: ${{ matrix.os }} steps: - name: Check out code from the repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Build on Linux @@ -38,14 +43,18 @@ jobs: ${{ env.MSYS2_INSTALL_FOLDER }}\msys2_shell.cmd -mingw64 -no-start -defterm -c "pacman -S binutils make mingw-w64-x86_64-gcc git --noconfirm" ${{ env.MSYS2_INSTALL_FOLDER }}\msys2_shell.cmd -mingw64 -no-start -defterm -where %CD% -c "make" echo Build Complete - - name: Build on Mac - if: startsWith(matrix.os, 'macos') + - name: Build on MacOs-13 + if: startsWith(matrix.os, 'macos-13') + run: | + make + echo Build Complete + - name: Build on MacOs-14 + if: startsWith(matrix.os, 'macos-14') run: | - sudo xcode-select -s "/Applications/Xcode_13.2.1.app" make echo Build Complete - name: Archive toolchain - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: toolchain-${{ matrix.os }} path: | @@ -58,14 +67,14 @@ jobs: test: strategy: matrix: - os: [ubuntu-20.04, macos-11, macos-12, windows-2022] + os: [ubuntu-22.04, macos-13, macos-14, windows-2022] runs-on: ${{ matrix.os }} needs: build steps: - name: Check out code from the repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get previoulsy built artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: toolchain-${{ matrix.os }} - name: Restore Execute Flags @@ -103,14 +112,14 @@ jobs: package: strategy: matrix: - os: [ubuntu-20.04, macos-12, windows-2022] + os: [ubuntu-22.04, macos-13, windows-2022] runs-on: ${{ matrix.os }} needs: build steps: - name: Check out code from the repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get previously built artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: toolchain-${{ matrix.os }} - name: Package ${{ matrix.os }} @@ -130,7 +139,7 @@ jobs: make package echo Package Complete - name: Archive package - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: package-${{ matrix.os }} path: | @@ -143,22 +152,23 @@ jobs: if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' steps: - name: Check out code from the repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get previoulsy built artifacts win64 - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: package-windows-2022 - name: Get previously built artifacts macos - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: package-macos-12 + name: package-macos-13 - name: Get previously built artifacts linux - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: package-ubuntu-20.04 + name: package-ubuntu-22.04 # https://github.com/pyTooling/Actions/tree/main/releaser # need to use composite on windows, since docker isn't available - - name: publish package + - name: publish release package + if: ${{ github.event_name == 'release' }} uses: pyTooling/Actions/releaser@r0 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -166,4 +176,12 @@ jobs: rm: true # do not keep old latest artifacts files: | *.zip - + - name: publish current package + if: ${{ github.event_name != 'release' }} + uses: pyTooling/Actions/releaser@r0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + tag: "current" + rm: true # do not keep old latest artifacts + files: | + *.zip diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1b359132..7434484b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,11 +39,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: # debug: true languages: ${{ matrix.language }} @@ -58,7 +58,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -71,4 +71,4 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.gitignore b/.gitignore index 0d2a1d03..643e20db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,22 @@ .DS_Store *.iso -*.ovl +*.lst *.o +*.out +*.ovl *.pce +*.s *.sgx *.sym -*.s -/huc/ -/huc/tgemu/tgemu* -/huc/src/huc/huc -/huc/src/huc/huc.exe -/huc/src/isolink/huc.exe -/huc/src/mkit/as/pceas.exe -/huc/src/mkit/as/fujias.exe -/huc/src/mkit/as/nesasm.exe -/huc/src/tools/mml/mml.exe -/huc/src/tools/mod2mml/mod2mml.exe -/huc/src/tools/pcxtool/pcxtool.exe -*.lst - +*.user +.vs +.x86 +.x64 bin -examples/acd/ac_test.iso -examples/sgx/sgx_test.iso -examples/sgx/sgx_test.sgx -examples/shmup/bgm.asm -examples/shmup/mod2mml.log -examples/shmup/shmup.iso - src/huc/huc src/huc/huc.exe +src/hucc/hucc +src/hucc/hucc.exe src/isolink/isolink src/isolink/isolink.exe src/mkit/as/fujias @@ -38,19 +26,20 @@ src/mkit/as/nesasm.exe src/mkit/as/pceas src/mkit/as/pceas.exe src/mkit/as/pngread/pngread.a +src/tools/hulz/hulz +src/tools/hulz/hulz.exe src/tools/mml/mml src/tools/mml/mml.exe src/tools/mod2mml/mod2mml src/tools/mod2mml/mod2mml.exe +src/tools/pce2png/pce2png +src/tools/pce2png/pce2png.exe +src/tools/pce2png/pngwrite/pngwrite.a +src/tools/pce2png/pngwrite/pngwrite.lib src/tools/pcxtool/pcxtool src/tools/pcxtool/pcxtool.exe src/tools/sym2inc/sym2inc src/tools/sym2inc/sym2inc.exe src/tools/wav2vox/wav2vox src/tools/wav2vox/wav2vox.exe -src/tools/pce2png/pce2png -src/tools/pce2png/pce2png.exe -src/tools/pce2png/pngwrite/pngwrite.a -src/tools/pce2png/pngwrite/pngwrite.lib tgemu/tgemu* -src/version.h diff --git a/Makefile b/Makefile index 150acb96..fea951aa 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ install: test: @cd test ; /bin/sh ./test_compiler.sh + @cd test ; /bin/sh ./test_hucc.sh check: @cd test ; /bin/sh ./test_examples.sh diff --git a/doc/hucc/hucc_function_ref.md b/doc/hucc/hucc_function_ref.md new file mode 100644 index 00000000..f68410d1 --- /dev/null +++ b/doc/hucc/hucc_function_ref.md @@ -0,0 +1,565 @@ +# HuCC Function Reference + +## **Video Functions** + +`cls( void );` +`cls( unsigned int tile );` +Clear the entire screen. Without parameters the screen is filled with a space character otherwise it's filled with the bat-value given as the argument. + +`disp_on( void );` +Enable display output. + +`disp_off( void );` +Blank/Turn off the display output. + +`vsync( void );` +`vsync( unsigned char count );` +Synchronize the program to the video Vertical Blanking Signal (VBL), which is around 1/60th of a second. + +Without parameters this function returns as soon as a VBL signal has been received, else your program will be synchronized to the number of frames you requested. So for example to run your game at 20fps, just use vsync(3) at the end of your game loop. + +`set_256x224( void );` +Sets the screen to 32 characters wide and 28 characters tall. + +`set_screen_size( unsigned char value );` +Change the virtual screen size. By default the startup code initializes a virtual screen of 64 characters wide and 32 character tall, but other values are possible, namely : 32x32, 128x32, 32x64, 64x64, or 128x64. The larger the virtual screen is the less video memory you will have for your graphics (font, tiles, sprites). + +`set_xres( unsigned int x_pixels );` +Change the horizontal resolution to '*x_pixels*' (in pixels). This changes the video controller's registers to display more pixels on the screen; it does not affect any virtual calculations. + +`set_xres( unsigned int x_pixels, unsigned char blur_flag );` +Change the horizontal resolution to '*x_pixels*' (in pixels). This changes the video controller's registers to display more pixels on the screen; it does not affect any virtual calculations. + +`'blur_flag'` indicates what kind of smoothing will be used: **XRES_SHARP** or **XRES_SOFT** (default). + +Note: The 5MHz dot clock will be used up to a horizontal resolutions of 268 pixels. The 7MHz dot clock will be used up to 356 pixels and the 10MHz dot clock will be used beyond this. The maximum visible resolution seems to be around 512 pixels. + +`vram_addr( unsigned char bat_x, unsigned char bat_y );` + +`get_vram( unsigned int address );` + +`put_vram( unsigned int address, unsigned int data );` + +`peek( unsigned int addr );` +`peekw( unsigned int addr );` +Read the contents of memory location 'addr'. peek() is char-sized access, whereas peekw() is word-sized. + +`poke( unsigned int addr, unsigned char with );` +`pokew( unsigned int addr, unsigned int with );` +Write '*val*' value at memory location 'addr'. `poke()` is char-sized access, whereas `pokew()` is word-sized. +This function can be used to access the hardware I/O ports located at 0x0000 to 0x1FFF. + +## **Joypad Functions** + +`joy( unsigned int which );` +Return the current status of joypad number 'which'. This function is 6 button compliant. + +`joytrg( unsigned int which );` +Return informations about newly pressed buttons and directions of joypad number '*which*'. But beware of this function, these informations are refreshed every frame, so if your game loop is not fast enough you could miss some keypresses. + +## **Color and Palette Functions** + +`set_color( unsigned int index, unsigned int value );` +Set the specified color `index` (0-511) to the given rgb-value. + +`set_color_rgb( unsigned int index, unsigned char r, unsigned char g, unsigned char b );` +Set the specified color to the given rgb component values. This function is easier to use than `set_color()`, but it is slower. + +`get_color( unsigned int index );` +Retrieve the rgb-value of the specified color. + +`load_palette( unsigned char palette, unsigned char __far *data, unsigned int num_palettes );` +Load one or more 16-color palette-blocks at once. `palette` is the index of the first block (0-31) to load, and `num_palettes` the number of blocks. This function can be used to load palettes defined using `#defpal` or included with `#incpal` directives. + +`set_sprpal( unsigned char palette, unsigned char __far *data );` +`set_sprpal( unsigned char palette, unsigned char __far *data, unsigned int num_palettes );` +Exactly the same function as `load_palette()`, but this function offers direct access to sprite palette-blocks. Sprite palette-blocks are standard block number 16 to 31, but with this function you can simply access them with indexes 0 to 15. This function and the `set_bgpal()` function make sprite and character palette-block manipulation easier; with them you don't have to know the real block indexes. Without the third arguments, the function loads only one block. + +`set_bgpal( unsigned char palette, unsigned char __far *data );` +`set_bgpal( unsigned char palette, unsigned char __far *data, unsigned int num_palettes );` +Exactly the same function has `load_palette()`, but this function offers direct access to charachter palette-blocks. Character palette-blocks are standard block number 16 to 31, but with this function you can simply access them with indexes 0 to 15. This function and the `set_sprpal()` function make sprite and character palette-blocks manipulation easier; with them you don't have to know the real block indexes. Without the third arguments, the function loads only one block. + +## **Clock Functions** +*** +`clock_hh( void );` +`clock_mm( void );` +`clock_ss( void );` +`clock_tt( void );` +Return the number of *hours, minutes, seconds*, or '*ticks* (one VSYNC interval, or 1/60th of a second) since the last `clock_reset()`. + +Note: The accuracy of this clock will be "off" by about 2 seconds per whole hour. This is due to the fact that NTSC VSYNC frequency is actually 59.94Hz, rather than 60Hz (whilst the VCE "refreshes" at around 59.82Hz). + +`clock_reset( void );` +Resets the clock timer. + +## **Number Functions** +`abs( int value );` + +`srand( unsigned char seed );` +Change the random seed. You can use this function to improve randomness by giving a value based on when the player presses start for the first time, for example. + +`rand( void );` +Return a 16-bit random number. + +`rand8( void );` + +`random8( unsigned char limit );` + +`random( unsigned char limit );` +Return a random value between 0 and A-1. + +## **Tile & Map Functions** +`set_tile_address( unsigned int vram );` + +`set_tile_data( unsigned char __far *tiles, unsigned char num_tiles, unsigned char __far *palette_table, unsigned char tile_type );` +Define an array of tile to be used by all the tile and map functions. `tile_data` is the address of the tile graphics data in memory, `nb_tile` is the number of tile (max. 256), and `pal_ref` is the address of a palette-index array to use for tiles; each tile has its own palette index attached to it (note that palette indexes must be shifted to the left by four bits, ie. 0x40 for palette index 4). + +The new 1-parameter form is used together with `#inctile_ex()` or `#incchr_ex()` directives, where all other relevant data is already conveyed in the `#incxxx_ex()` directive. Also, this form automatically recognizes whether it is being used with 8x8 (`incchr_ex`) or 16x16 (`inctile_ex`) tiles. + +`load_vram( unsigned int vram, unsigned char __far *data, unsigned int num_words );` +Generic function to load data (BAT, CG, sprites) in video memory, at address `vram`. '*num_words*' is the number of 16-bit words to load. + +`load_tile( unsigned int vram );` +Load tile graphics data in video memory, at address '*vram*'. You must first have defined a tile array with `set_tile_data()` before using this function. + +`load_bat( unsigned int vram, unsigned char __far *data, unsigned char tiles_w, unsigned char tiles_h );` +Load a rectangular character attribute table (BAT) of width 'w' and of height 'h' in video memory at address '*vram*'. + +`put_tile( unsigned char tile, unsigned char bat_x, unsigned char bat_y );` +Put individual tiles on the screen, either directly at video memory location '*vaddr*', or at screen coordinates 'x/y' (in tile unit). '*tile*' is a tile index in the tile array defined by the most recent call to `set_tile_data()`. + +`map_put_tile( unsigned char map_x, unsigned char map_y, unsigned char tile );` +Modifies the map data (sets a map element to a new tile ID), but works only when the map is stored in RAM - ie. a Super CDROM game which is loaded into RAM, and executes there. 'x' and 'y' are specified in the same units as `map_get_tile()` (ie. pixels, not tiles). + +`map_get_tile( unsigned char map_x, unsigned char map_y );` +Return the tile index as defined in the tile array used in the most recent call to `set_tile_data()`. The 'x/y' argument is in pixel units, unlike the put_tile functions and thus this function is ideal for colision routines. + +`load_map( unsigned char bat_x, unsigned char bat_y, int map_x, int map_y, unsigned char tiles_w, unsigned char tiles_h );` +Load a part of a map on the screen. 'sx' and 'sy' are screen coordinates (in tile unit; 16 pixels), 'mx' and 'my' are position in the map, and 'w' and 'h' are respectively the number of tile-index to load horizontaly and verticaly. This function doesn't do any screen clipping, so you must not pass incorrect or too big screen coordinates to it as that would corrupt the video memory. + +`set_map_data( unsigned char __far *map, unsigned char w, unsigned char h );` + +`set_map_pals( unsigned char __far *palette_table );` + +`set_map_tile_type( unsigned char tile_type );` + +`set_map_tile_base( unsigned int vram );` + +`load_background( unsigned char __far *tiles, unsigned char __far *palettes, unsigned char __far *bat, unsigned char w, unsigned char h );` +This function is an all-in-one function, it is used to display an entire background image on the screen, like a game title image. It will load BG character data, it will load the palette, and finaly if will load the BAT. Use it with directives *#incchr*, *#incpal* and *#incbat* to manage the different types of data. The BG character data will be stored at address 0x1000 to 0x5000 in video memory. + +## **Font Related Functions** + +`set_font_addr( unsigned int vram );` +Set the font address in video memory. Use this function to change the current font; to use several font on the same screen, or when you load yourself a font and need to tell the library where it is. + +`set_font_pal( unsigned char palette );` +Set the font palette index (0-15) to use. + +`load_font( char __far *font, unsigned char count );` +`load_font( char __far *font, unsigned char count, unsigned int vram );` +Load a custom font in video memory. Used together with the *#incchr* directive it will allow you to load a font from a PCX file. + +Note: Custom fonts are "*colored*" fonts, so they won't be affected by any previous call to `set_font_color()`. The number of characters to load ranges from 0 to 224, ASCII characters 0 to 31 are never used, and can't be defined so you must start your font at the space character which is ASCII code 32. + +If you don't implicitely give a video memory address, the function will load your font just above the BAT (usualy it's address 0x800). + +`set_font_color( unsigned char foreground, unsigned char background );` +Set the default font foreground and background colors (colors range from 0 to 15). Changes won't take effect immediately, you must re-load the font by calling `load_default_font()`. + +`load_default_font( void ); char num, int vaddr)` +Loads a default font in video memory. Without parameters the first default font is loaded just above the BAT in video memory; usualy it's address 0x800. Otherwise you can select the font number, and eventualy the address in video memory. In its current implementation the library supports only one default font, but in the future more fonts could be made available. + +## **Text Output Functions** +All the text output functions have two forms, one where you directly specify the video memory address, and another one where you specify x/y coordinates (in character units). The second form is a bit slower but more user-friendly. + +`put_digit( unsigned char digit, unsigned char bat_x, unsigned char bat_y );` +Output a digit character '0'-'9' given its numeric value. Hexa digits ('A'-'F') are also supported, a value of 10 will output 'A', a value of 11 will output 'B', and so on... + +`put_char( unsigned char digit, unsigned char bat_x, unsigned char bat_y );` +Output an ASCII character. + +`put_hex( unsigned int number, unsigned char length, unsigned char bat_x, unsigned char bat_y );` +Output an hexa number. The 'length' argument is used to format the number. As many as 'length' digit(s) will be displayed. If the number has less than 'lgenth' digit(s), blank spaces will be added to its left. + +`put_number( unsigned int number, unsigned char length, unsigned char bat_x, unsigned char bat_y );` +Output a signed number. The 'length' argument is used to format the number. As many as 'length' digit(s) will be displayed. If the number has less than 'lgenth' digit(s), blank spaces will be added to its left. If the number is negative, a '-' sign is added. + +`put_string( unsigned char *string, unsigned char bat_x, unsigned char bat_y );` +Output a null terminated ASCII string. + +## **Graphics Functions** +`gfx_init( unsigned int start_vram_addr );` +Initialize screen to point to sequential graphics tiles, located starting at address '*start_vram_addr*' in VRAM. + +`gfx_clear( unsigned int start_vram_addr );` +Clear graphical screen. Starting at address '*start_vram_addr*' in VRAM, this function sets sequential tiles in VRAM to all zeroes, with a size based on the virtual map. + +`gfx_plot( unsigned int x, unsigned int y, char color );` +Set a pixel at (x,y) to color listed. '*color*' should be avalue between 0 and 15. + +`gfx_line( unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned char color );` +Draw a line from (x1, y1) to (x2, y2) in color listed. '*color*' should be a value between 0 and 15. + +## **Scroll Functions** + +`scroll( unsigned char num, unsigned int x, unsigned int y, unsigned char top, unsigned char bottom, unsigned char disp );` +Define screen window '*num*'. Up to four window can be defined. '*top*' and '*bottom*' are the screen top and bottom limits of the window (limits are included in the window area). '*disp*' controls the type of the window, if bit 7 is set background graphics will be displayed in this window, and if bit 6 is set sprites will also be displayed. If none of these bits are set the window will stay blank. 'x' and 'y' are the top-left coordinates of the area in the virtual screen that will be displayed in the window. + +`scroll_disable( unsigned char num );` +Disable scrolling for the screen window '*num*'. + +`scroll_split( unsigned char index, unsigned char top, unsigned int x, unsigned int y, unsigned char disp );` + +`disable_split( unsigned char index );` + +## **Sprite Functions** + +`init_satb( void );` +Initialize the internal Sprite Attribute Table (SATB) used by the library to handle sprites. This function must be called before any other sprite function is called. + +`reset_satb( void );` +Reset the internal SATB, this has the effect to disable and reset all the sprites. + +`satb_update( void );` +Copy the internal sprite attribute table to the video ram. This will refresh sprites on the screen. Use this function regularly to update the sprite display. The best place to call `satb_update()` is after every `vsync()` call, but no need to call `satb_update()` if you didn't change any sprite attribute. '*nb*' specifys the number of sprite to refresh; starting from sprite 0. By default the library refreshes only the sprites you use, but if you need to implicitely refresh a certain number of sprites then you can use '*nb*'. + +`spr_set( unsigned char num );` +Select sprite '*num*' (0-63) as the current sprite. + +`spr_hide( void );` +Without parameters this function will hide the current sprite. Use '*num*' to hide a different sprite than the current one. + +`spr_show( void );` +Show a sprite that has been hidden using the `spr_hide()` function. + +`spr_x( unsigned int value );` +Set the x coordinate of the current sprite. Negative values will make the sprite disappear under the left border, while values higher than the screen width will make it disappear under the right border. + +`spr_y( unsigned int value );` +Set the y coordinate of the current sprite. + +`spr_pattern( unsigned int vaddr );` +Set the pattern address in video memory of the current sprite. + +`spr_ctrl( unsigned char mask, unsigned char value );` +Set different attributes of the current sprite. With this function you can change the sprite size (16x16, 32x32, ...) and the sprite orientation (horizontal/vertical flipping). + +`spr_pal( unsigned char palette );` +Set the palette-block index (0-15) of the current sprite. + +`spr_pri( unsigned char priority );` +Set the priority of the current sprite. '0' will make it appear behind the background (through color 0), '1' will make it appear in front of the background. + +`spr_get_x( void );` +Return the x coordinate of the current sprite. + +`spr_get_y( void );` +Return the y coordinate of the current sprite. + + +## **String Manipulation functions** + +`strcpy( char *destination, char *source );` +Copy the source information to the destination area, as in ANSI 'C'. + +`strcat( char *destination, char *source );` +Concatenate source string onto the end od destination string, as in ANSI 'C'. + +`strlen( char *source );` +Computes the length of the specified string, up to but not including the terminating null character. + +`strlcpy( char *destination, char *source, unsigned char size );` +Copy the source information to the destination area, as in ANSI 'C'. + +`strlcat( char *destination, char *source, unsigned char size );` +Concatenate source string onto the end od destination string, as in ANSI 'C'. + +`memcpy( unsigned char *destination, unsigned char *source, unsigned int count );` +Copy the source information to the destination area, as in ANSI 'C'. + +`mempcpy( unsigned char *destination, unsigned char *source, unsigned int count );` +Copy the source information to the destination area, as in ANSI 'C'. + +`memset( unsigned char *destination, unsigned char value, unsigned int count );` + +`strcmp( char *destination, char *source );` +Compare the source information against the destination information, as in ANSI 'C'. + +`strncmp( char *destination, char *source, unsigned int count );` +Compare the source information against the destination information, as in ANSI 'C'. + +`memcmp( unsigned char *destination, unsigned char *source, unsigned int count );` +Compare the source information against the destination information, as in ANSI 'C'. + +## **CD Overlay functions** + +`cd_execoverlay( unsigned char ovl_index );` +Loads a program overlay specified by '*ovl_index*', and execute it. If an error occurs during loading, the previous context (ie. the overlay running until that moment) is reloaded and an error value is returned to the program. + +## **CDROM functions** + +`cd_boot( void );` + +`cd_getver( void );` +Returns CDROM system card version number in BCD. (ie. Japanese Super System card = 0x0300, American Duo = 0x301) + +`cd_reset( void );` +Reset the CDROM drive, and stop the motor + +`cd_pause( void );` +Pause the CDROM drive during play of an audio track. Probably most useful if the player pauses the game in the middle of a level which is synchronized to music. + +`cd_unpause( void );` +Continue the CDROM audio audio track after pause. + +`cd_fade( unsigned char type );` + +`cd_playtrk( unsigned char start_track, unsigned char end_track, unsigned char mode );` +Play one or more CDROM audio tracks in a few different modes. This will not play '*end*' track, so '*end*' >= 'start'+1. If you wish to play until end of disc (or if 'start' track is final track), then set 'end' to value '**CDPLAY_ENDOFDISC**'. + + Attempts to play data tracks will not play, and will return non-zero error code. + + Valid modes Meaning + ----------- ------- + CDPLAY_MUTE Plays audio without sound (muted) + CDPLAY_REPEAT Plays audio, repeating when track(s) complete + CDPLAY_NORMAL Plays audio only until completion of track(s) + +`cd_playmsf( unsigned char start_minute, unsigned char start_second, unsigned char start_frame, unsigned char end_minute, unsigned char end_second, unsigned char end_frame, unsigned char mode );` +Play CDROM audio in a few different modes, as above. +M/S/F = minute/second/frame indexing technique. +(Note: there are 75 frames per second) + +(See `cd_playtrk()` for valid values of '*mode*') + +`cd_loadvram( unsigned char ovl_index, unsigned int sect_offset, unsigned int vramaddr, unsigned int bytes );` +Read data from the CDROM directly into video RAM at address specified by '*vramaddr*', for a length of '*bytes*'. Note that 2 bytes are required to fill one VRAM word. + +Read it from the overlay segment specified by '*ovl_index*', with sector offset (ie. multiples of 2048 bytes) of '*sect_offset*'. + +Non-zero return values indicate errors. + +`cd_loaddata( unsigned char ovl_index, unsigned int sect_offset, unsigned char __far *buffer, unsigned int bytes );` +Read data from the CDROM into area (or overlay 'const' or other data) specified by '*destaddr*', for a length of '*bytes*'. + +Read it from the overlay segment specified by '*ovl_index*', with sector offset (ie. multiples of 2048 bytes) of '*sect_offset*'. + +Non-zero return values indicate errors. + +`cd_loadbank( unsigned char ovl_index, unsigned int sect_offset, unsigned char bank, unsigned int sectors );` + +`cd_status( unsigned char mode );` +Checks the status of the CDROM device. + + Valid Mode Meaning Return value & meaning + ---------- ------- ---------------------- + 0 Drive Busy Check 0 = Drive Not Busy + other = Drive Busy + other Drive Ready Check 0 = Drive Ready + other = Sub Error Code + +Non-zero return values indicate errors. + +## **ADPCM Hardware Functions** + +`ad_reset( void );` +Resets ADPCM hardware. + +`ad_trans( unsigned char ovl_index, unsigned int sect_offset, unsigned char nb_sectors, unsigned int ad_addr );` +Transfer data from CDROM into ADPCM buffer. Read it from the overlay segment specified by '*ovl_index*', with sector offset (ie. multiples of 2048 bytes) of '*sect_offset*'. Read '*nb_sectors*' sectors and store data into ADPCM buffer starting from offset '*ad_addr*'. Non-zero return values indicate errors. + +`ad_read( unsigned int ad_addr, unsigned char mode, unsigned int buf, unsigned int bytes );` +Read data from the ADPCM buffer. Read '*bytes*' bytes starting at offset '*ad_addr*' in ADPCM buffer. The mode '*mode*' determines the meaning of the '*buf*' offset. + + Valid modes Meaning of 'buf' + ----------- ---------------- + 0 Offset in the mapped ram. + 2-6 Directly into memory mapped to MMR #'mode' + 0xFF Offset in video ram. + +Non-zero return values indicate errors. + +`ad_write( unsigned int ad_addr, unsigned char mode, unsigned int buf, unsigned int bytes );` +Write data into the ADPCM buffer. Write '*bytes*' bytes starting at offset '*ad_addr*' in ADPCM buffer. The mode '*mode*' determines the meaning of the '*buf*' offset. + + Valid modes Meaning of 'buf' + ----------- ---------------- + 0 Offset in the mapped ram. + 2-6 Directly into memory mapped to MMR #'mode' + 0xFF Offset in video ram. + +Non-zero return values indicate errors. + +`ad_play( unsigned int ad_addr, unsigned int bytes, unsigned char freq, unsigned char mode );` +Play ADPCM sound from data loaded in the ADPCM buffer. Start playing from '*ad_addr*' offset in the ADPCM buffer, for '*bytes*' bytes. The frequency used for playback is computed from '*freq*' using the following formula : `real_frequency_in_khz = 32 / (16 - 'freq')`. Valid range for '*freq*' is 0-15. If bit 0 of 'mode' is on, values of '*ad_addr*', '*bytes*' and '*freq*' from the previous `ad_play()` call are reused. If bit 7 of '*mode*' is on, playback loops instead of stopping at the end of the range. + +`ad_cplay( unsigned char ovl_index, unsigned int sect_offset, unsigned int nb_sectors, unsigned char freq );` + +`ad_stop( void );` +Stop playing ADPCM. + +`ad_stat( void );` +Returns current ADPCM status. Return **FALSE(0)** if ADPCM playing isn't in progress else returns a non zero value. + +## **Backup Ram Functions** + +`bm_check( void );` +Return whether the backup ram is available. + +`bm_format( void );` +Format the whole backup ram. Does not format if data is already formatted. Actually, data isn't erased but the header data reports so. You should be able to find old data in the bram using raw reads in the backup ram bank but not through the usual HuC functions. Return backup ram status as defined in the hucc.h file. + +`bm_free( void );` +Return the number of free bytes available for user data. The amount required for the data header and the necessary 2-byte termination are already deducted from this amount. The value returned is the number of bytes free for user data. + +`bm_read( unsigned char *buffer, unsigned char *name, unsigned int offset, unsigned int length );` +Read '*nb*' bytes from file named '*name*' and put them into '*buf*'. I'm not sure whether the '*offset*' is relative to the buffer or the file ... Return backup ram status as defined in the hucc.h file. + +`bm_write( unsigned char *buffer, unsigned char *name, unsigned int offset, unsigned int length );` +Write into the file named '*name*'. Data to write are in the buffer '*buf*' and '*nb*' bytes are written from offset '*offset*' in the buffer. Return backup ram status as defined in the hucc.h file. + +`bm_delete( unsigned char *name );` +Delete BRAM entry with a given name + +`bm_exist( unsigned char *name );` +Check whether a backup ram file exists. This returns **TRUE (!= 0)** if good; **FALSE (0)** if bad. The name structure is not just an ASCII name; it begins with a 2-byte "uniqueness ID" which is almost always 00 00, followed by 10 bytes of ASCII name - which should be padded with trailing spaces. + +`bm_create( unsigned char *name, unsigned int length );` +Create a new file names '*name*' with a size of '*size*' bytes. Return backup ram status as defined in the hucc.h file. + +## **ZX0 COMPRESSION FUNCTIONS** +ZX0 "modern" format is not supported, because it costs an extra 4 bytes of code in this decompressor, and it runs slower. +Use Emmanuel Marty's SALVADOR ZX0 compressor which can be found here ... https://github.com/emmanuel-marty/salvador + +To create a ZX0 file to decompress to RAM +*salvador -classic * + +To create a ZX0 file to decompress to VRAM, using a 2KB ring-buffer in RAM +*salvador -classic -w 2048 * + +`zx0_to_vdc( unsigned int vaddr, char far *compressed );` +`zx0_to_sgx( unsigned int vaddr, char far *compressed );` + +## **SuperGrafx Equivalent Functions** + +`sgx_detect( void );` +Returns **TRUE (1)** if exists; **FALSE(0)** if not. + +`sgx_set_screen_size( unsigned char value );` +`sgx_set_xres( unsigned int x_pixels, unsigned char blur_flag );` + +`sgx_vram_addr( unsigned char bat_x, unsigned char bat_y );` +Simple function to return the screen video memory address of the character located at position x/y. + +`sgx_get_vram( unsigned int address );` + +`sgx_put_vram( unsigned int address, unsigned int data );` + +`sgx_set_tile_address( unsigned int vram );` + +`sgx_set_tile_data( unsigned char __far *tiles, unsigned char num_tiles, unsigned char __far *palette_table, unsigned char tile_type );` + +`sgx_load_vram( unsigned int vram, unsigned char __far *data, unsigned int num_words );` + +`sgx_load_tile( unsigned int vram );` + +`sgx_load_bat( unsigned int vram, unsigned char __far *data, unsigned char tiles_w, unsigned char tiles_h );` + +`sgx_set_map_data( unsigned char __far *map, unsigned char w, unsigned char h );` + +`sgx_load_map( unsigned char bat_x, unsigned char bat_y, int map_x, int map_y, unsigned char tiles_w, unsigned char tiles_h );` + +`sgx_map_get_tile( unsigned char map_x, unsigned char map_y );` + +`sgx_map_put_tile( unsigned char map_x, unsigned char map_y, unsigned char tile );` + +`sgx_put_tile( unsigned char tile, unsigned char bat_x, unsigned char bat_y );` + +`sgx_set_map_pals( unsigned char __far *palette_table );` + +`sgx_set_map_tile_type( unsigned char tile_type );` + +`sgx_set_map_tile_base( unsigned int vram );` + +`sgx_init_satb( void );` + +`sgx_reset_satb( void );` + +`sgx_satb_update( void );` + +`sgx_spr_set( unsigned char num );` + +`sgx_spr_hide( void );` + +`sgx_spr_show( void );` + +`sgx_spr_x( unsigned int value );` + +`sgx_spr_y( unsigned int value );` + +`sgx_spr_pattern( unsigned int vaddr );` + +`sgx_spr_ctrl( unsigned char mask, unsigned char value );` + +`sgx_spr_pal( unsigned char palette );` + +`sgx_spr_pri( unsigned char priority );` + +`sgx_spr_get_x( void );` + +`sgx_spr_get_y( void );` + +`sgx_scroll_split( unsigned char index, unsigned char top, unsigned int x, unsigned int y, unsigned char disp );` + +`sgx_disable_split( unsigned char index );` + +## **Arcade Card Functions** + +`ac_exists( void );` +Returns **TRUE (1)** if exists; **FALSE (0)** if not. + + + +## **Special cases, for compatibility with existing apps ONLY, not to be used** +`__builtin_ffs` +"find first set bit". It counts the number of bits in an int until it finds one that is set. + +`abort()` + +`error()` + +## **HUC Functions currently NOT Supported in HuCC (as of 09/29/24)** +`get_font_pal` +`get_font_addr` +`put_raw` +`strncpy` +`get_tile` +`set_map_data` +`gfx_setbgpal` +`gfx_point` +`load_sprites` +`spr_get_pal` +`spr_get_pattern` +`set_joy_callback` +`get_joy_events` +`clear_joy_events` +`mouse_exists` +`mouse_enable` +`mouse_disable` +`mouse_x` +`mouse_y` +`bm_size` +`bm_rawread` +`bm_rawwrite` +`bm_errno` +`bm_sizeof` +`bm_getptr` +`bm_open` +`bm_enable` +`bm_disable` +`bm_checksum` +`bm_setup_ptr` +`cd_numtrk` +`cd_trktype` +`cd_trkinfo` diff --git a/examples/asm/elmer/Make_ex.inc b/examples/asm/elmer/Make_ex.inc index b6a27ab2..22737609 100644 --- a/examples/asm/elmer/Make_ex.inc +++ b/examples/asm/elmer/Make_ex.inc @@ -12,7 +12,9 @@ BINDIR := ../../../../bin # endif # endif -CC = $(BINDIR)/huc +export PATH := $(PWD)/../../../../bin:$(PATH) + +CC = $(BINDIR)/sdcc AS = $(BINDIR)/pceas IL = $(BINDIR)/isolink S2I = $(BINDIR)/sym2inc @@ -36,7 +38,7 @@ endif # GNU Make wants UNIX path separators in the makefile. -VPATH = ../include:../font:../data +VPATH = ../include:../font:../data:../../../../include/hucc # PCE_INCLUDE needs platform-specific path separators. diff --git a/examples/asm/elmer/Makefile b/examples/asm/elmer/Makefile index f5d43750..707122cd 100644 --- a/examples/asm/elmer/Makefile +++ b/examples/asm/elmer/Makefile @@ -2,9 +2,11 @@ # PREREQS = ipl-scd -SUBDIRS = rom-bare-tiatest rom-bare-vdctest scd-bios-hello scd-bios-hello-error \ - rom-core-hello rom-core-okitest \ - cd-core-1stage cd-core-2stage scd-core-1stage scd-core-1stage-error \ +SUBDIRS = rom-bare-buftest rom-bare-mwrtest rom-bare-rcrtest rom-bare-tiatest \ + rom-core-hello rom-core-hugerom rom-core-okitest \ + scd-bios-hello scd-bios-hello-error \ + cd-core-1stage cd-core-2stage cd-core-scsitest \ + scd-core-1stage scd-core-1stage-error \ scd-core-2stage scd-core-2stage-error scd-core-fastcd \ rom-kickc-hello rom-kickc-shmup ted2-core-hwdetect ted2-core-sdcard \ ted2-core-gulliver diff --git a/examples/asm/elmer/README.md b/examples/asm/elmer/README.md index 534cf0c7..4ff79bb5 100644 --- a/examples/asm/elmer/README.md +++ b/examples/asm/elmer/README.md @@ -14,12 +14,18 @@ This directory contains a number of example programs and utilities for developin * ted2-bios-usbcd - A modified System Card 3.0 HuCARD that runs a CD-ROM overlay uploaded through USB, rather than loading it from CD-ROM. +* rom-bare-buftest + - A HuCARD ROM to compare a PC Engine emulator's buffered VDC reading with real PC Engine console hardware. + +* rom-bare-mwrtest + - A HuCARD ROM to compare a PC Engine emulator's VDC VRAM read/write timings with real PC Engine console hardware. + +* rom-bare-rcrtest + - A HuCARD ROM to compare a PC Engine emulator's RCR interrupt handling with real PC Engine console hardware. + * rom-bare-tiatest - A HuCARD ROM to compare a PC Engine emulator's TIA-to-VDC cycle timing with real PC Engine console hardware. -* rom-bare-vdctest - - A HuCARD ROM to compare a PC Engine emulator's VDC RCR interrupt handling with real PC Engine console hardware. - * rom-core-okitest - A HuCARD ROM to compare a PC Engine emulator's ADPCM playback flags and ADPCM write speed with real PC Engine console hardware. @@ -41,12 +47,18 @@ The "CORE(not TM)" PC Engine library is a small and configurable set of library * rom-core-hello - A simple example of creating a HuCARD ROM. +* rom-core-hugerom + - A simple example of creating a HuCARD ROM for the Street Fighter II mapper. + * cd-core-1stage - A simple example of creating an ISO for a CD-ROM, and loading the "CORE(not TM)" kernel code from the overlay program. * cd-core-2stage - A simple example of creating an ISO for a CD-ROM, and loading the "CORE(not TM)" kernel code in a startup overlay. +* cd-core-scsitest + - A CD-ROM and a HuCARD for testing some low-level details of the PC Engine's SCSI CD-ROM behavior. + * scd-core-1stage - A simple example of creating an ISO for a Super CD-ROM, and loading the "CORE(not TM)" kernel code from the overlay program. diff --git a/examples/asm/elmer/cd-core-2stage/Makefile b/examples/asm/elmer/cd-core-2stage/Makefile index 2b16c454..0da819fb 100644 --- a/examples/asm/elmer/cd-core-2stage/Makefile +++ b/examples/asm/elmer/cd-core-2stage/Makefile @@ -7,7 +7,7 @@ AFLAGS ?= -newproc -strip -m -l 2 -S -overlay SRC1_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm SRC1_OVL = core-stage1.asm core-config.inc -SRC2_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm +SRC2_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm unpack-zx0.asm SRC2_OVL = stage2.asm core-config.inc SRC_ISO = core-stage1.bin stage2.ovl @@ -19,7 +19,7 @@ core-stage1.bin core-stage1.sym: $(SRC1_OVL) $(SRC1_INC) $(AS) $(AFLAGS) -cd -trim core-stage1.asm core-stage1.s: core-stage1.s2i core-stage1.sym - $(S2I) ../include/core-stage1.s2i + $(S2I) core-stage1.s2i stage2.ovl: $(SRC2_OVL) $(SRC2_INC) core-stage1.s $(AS) $(AFLAGS) -cd stage2.asm diff --git a/examples/asm/elmer/cd-core-2stage/stage2.asm b/examples/asm/elmer/cd-core-2stage/stage2.asm index 33382a17..2180005c 100644 --- a/examples/asm/elmer/cd-core-2stage/stage2.asm +++ b/examples/asm/elmer/cd-core-2stage/stage2.asm @@ -65,6 +65,12 @@ CHR_0x20 = CHR_ZERO + 32 ; ASCII ' ' CHR tile #. USING_STAGE1 = 1 + ; + ; Since we don't use it here, let's verify that this works. + ; + +SUPPORT_ZX0VRAM = 0 ; Include decompress-to-VRAM? + ; ; Include the library, reading the project's configuration ; settings from the local "core-config.inc", if it exists. diff --git a/examples/asm/elmer/cd-core-scsitest/Makefile b/examples/asm/elmer/cd-core-scsitest/Makefile new file mode 100644 index 00000000..08a4b661 --- /dev/null +++ b/examples/asm/elmer/cd-core-scsitest/Makefile @@ -0,0 +1,19 @@ +all: core-scsitest.iso scsitest.pce + +include ../Make_ex.inc + +AFLAGS ?= -newproc -strip -m -l 2 -S + +SRC_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm adpcm.asm cdrom.asm +SRC_OVL = scsitest.asm core-config.inc + +SRC_ISO = scsitest.ovl ../data/alice.vdc ../data/alice.ram ../data/umbrella-16k.vox + +core-scsitest.iso: $(SRC_ISO) + $(IL) core-scsitest.iso -ipl="test-CD CD-ROM2",0x4000,0x4000,0,1,2,3,4 -asm $(SRC_ISO) + +scsitest.ovl: $(SRC_OVL) $(SRC_INC) scsitest.pce + $(AS) $(AFLAGS) -cd -overlay scsitest.asm cdrom.asm + +scsitest.pce: $(SRC_OVL) $(SRC_INC) + $(AS) $(AFLAGS) -raw scsitest.asm cdrom.asm diff --git a/examples/asm/elmer/cd-core-scsitest/core-scsitest.cue b/examples/asm/elmer/cd-core-scsitest/core-scsitest.cue new file mode 100644 index 00000000..5652adee --- /dev/null +++ b/examples/asm/elmer/cd-core-scsitest/core-scsitest.cue @@ -0,0 +1,3 @@ +FILE core-scsitest.iso BINARY + TRACK 01 MODE1/2048 + INDEX 01 00:00:00 diff --git a/examples/asm/elmer/cd-core-scsitest/scsitest.asm b/examples/asm/elmer/cd-core-scsitest/scsitest.asm new file mode 100644 index 00000000..22adb5f0 --- /dev/null +++ b/examples/asm/elmer/cd-core-scsitest/scsitest.asm @@ -0,0 +1,1648 @@ +; *************************************************************************** +; *************************************************************************** +; +; scsitest.asm +; +; Testing program to investigate the PC Engine's SCSI CD-ROM behavior. +; +; This could be used by emulator authors to compare a real PCE vs emulation. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; When running on a HuCARD the setup is standard for the CORE library. +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM with Stack & ZP +; MPR2 = bank $00 : HuCard ROM +; MPR3 = bank $01 : HuCard ROM +; MPR4 = bank $02 : HuCard ROM +; MPR5 = bank $03 : HuCard ROM +; MPR6 = bank $xx : HuCard ROM banked ASM library procedures. +; MPR7 = bank $00 : HuCard ROM with "CORE(not TM)" kernel and IRQ vectors. +; +; If it is running on an old CD-ROM2 System the overlay is loaded from the +; ISO into banks $80-$87 (64KB max). +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM with Stack & ZP & "CORE(not TM)" kernel +; MPR2 = bank $80 : CD RAM +; MPR3 = bank $81 : CD RAM +; MPR4 = bank $82 : CD RAM +; MPR5 = bank $83 : CD RAM +; MPR6 = bank $84 : CD RAM +; MPR6 = bank $xx : CD RAM banked ASM library procedures. +; MPR7 = bank $80 : CD RAM or System Card's bank $00 +; +; *************************************************************************** +; *************************************************************************** + + + ; + ; Create some equates for a very generic VRAM layout, with a + ; 64*32 BAT, followed by the SAT, then followed by the tiles + ; for the ASCII character set. + ; + ; This uses the first 8KBytes of VRAM ($0000-$0FFF). + ; + +BAT_LINE = 64 +BAT_SIZE = 64 * 32 +SAT_ADDR = BAT_SIZE ; SAT takes 16 tiles of VRAM. +CHR_ZERO = BAT_SIZE / 16 ; 1st tile # after the BAT. +CHR_0x10 = CHR_ZERO + 16 ; 1st tile # after the SAT. +CHR_0x20 = CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + + ; + ; Include the library, reading the project's configuration + ; settings from the local "core-config.inc", if it exists. + ; + + include "core.inc" ; Basic includes. + + .list + .mlist + + include "common.asm" ; Common helpers. + include "vdc.asm" ; Useful VDC routines. + include "font.asm" ; Useful font routines. + include "tty.asm" ; Useful TTY print routines. + +; This is needed, but is included on the PCEAS command line in the makefile +; instead just to confirm that the multiple-input-file functionality works. +; +; include "cdrom.asm" ; Fast CD-ROM routines. + + + +; *************************************************************************** +; *************************************************************************** +; +; Constants and Variables. +; + + .zp + +timer_val: ds 2 +data_relative: ds 1 ; $80=DATA_IN clears timer. + + .bss + + ; Display variables. + +count_was: ds 2 +timer_was: ds 2 +text_message: ds 80 + +retry_count: ds 2 + +lba_top: ds 1 +lba_add: ds 1 + + ; Hacks to the CD-ROM test_read() to create bad behavior. + ; + ; Neither the System Card nor Hudson's "fast" code ever do + ; stupid things like these, but all the Sherlock Holmes CD + ; games rely on this behavior. + ; + +exit_on_data: ds 1 ; Exit cd_read early? +exit_on_stat: ds 1 ; Exit cd_read early? +exit_on_mesg: ds 1 ; Exit cd_read early? + +delay_data: ds 1 ; Add delay after DATA_IN? + + .code + +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; +; core_main - This is executed after "CORE(not TM)" library initialization. +; +; This is the first code assembled after the library includes, so we're still +; in the CORE_BANK, usually ".bank 0"; and because this is assembled with the +; default configuration from "include/core-config.inc", which sets the option +; "USING_MPR7", then we're running in MPR7 ($E000-$FFFF). +; + + .code + +core_main: ; Turn the display off and initialize the screen mode. + + call init_512x224 ; Initialize VDC & VRAM. + + ; Upload the font to VRAM. + + stz <_di + 0 ; Destination VRAM address. + lda #>(CHR_0x10 * 16) + sta <_di + 1 + + lda #$FF ; Put font in colors 4-7, + sta <_al ; so bitplane 2 = $FF and + stz <_ah ; bitplane 3 = $00. + + lda #16 + 96 ; 16 box graphics + 96 ASCII. + sta <_bl + + lda #my_font + sta <_bp + 1 + ldy #^my_font + + call dropfntbox_vdc ; Upload font to VRAM. + + ; Upload the 8x8 font to VRAM in colors 0-3, with box tiles + ; using colors 4-7. + ; + ; Thus we call dropfntbox_vdc() instead of dropfnt8x8_vdc()! + + stz <_di + 0 ; Destination VRAM address. + lda #>(CHR_0x10 * 16) + sta <_di + 1 + + lda #$FF ; Put font in colors 4-7, + sta <_al ; so bitplane 2 = $FF and + stz <_ah ; bitplane 3 = $00. + + lda #16 + 96 ; 16 graphics + 96 ASCII. + sta <_bl + + lda #my_font + sta <_bp + 1 + ldy #^my_font + + call dropfnt8x8_vdc ; Upload font to VRAM. + + ; Upload the palette data to the VCE. + + stz <_al ; Start at palette 0 (BG). + lda #3 ; Copy 3 palettes of 16 colors. + sta <_ah + lda #cpc464_colors + sta.h <_bp + ldy #^cpc464_colors + call load_palettes ; Add to the palette queue. + + ; Turn on the BG & SPR layers, then wait for a soft-reset. + + setvec vsync_hook, .vblank_irq ; Enable vsync_hook. + smb4 7144 cycles -> 1.00124457ms + + lda.l #timer_irq ; Install timer_irq vector. + sta.l timer_hook + lda.h #timer_irq + sta.h timer_hook + smb2 = MAX_TAGS) + .fail Too many TAGs, increase MAX_TAGS! + .endif + .endif + .data +!string: db (!end+ - !string-) ; PASCAL-style string. + db \1 +!end: db 0 +SAVED_BANK .set bank(*) - _bank_base ; Remember data bank. +SAVED_ADDR .set * ; Remember data addr. + .bank CORE_BANK + .org tagtbl_lo + tag_number + db !string- + .org tagtbl_bk + tag_number + db ^!string- + .bank SAVED_BANK ; Restore data bank. + .org SAVED_ADDR ; Restore data addr. + .code + .endm + +TAG_FLG .macro + TAG \1 + ldy #tag_number + jsr log_flg + .endm + +TAG_A .macro + TAG \1 + ldy #tag_number + jsr log_tag + .endm + + ; + ; Clear the current log entries. + ; + +clear_log: php + sei + nop + stz width = total # chr on line = 42 chr ; VDC @ 7.16MHz -> width = total # chr on line = 56 chr ; VDC @ 10.74MHz -> width = total # chr on line = 85 chr @@ -75,46 +74,67 @@ ; Sprites-per-line shown (@ 1-clk-per-access) = (width - 2 - (hdw + 1)) * 2 ; Sprites-per-line shown (@ 2-clk-per-access) = (width - 2 - (hdw + 1)) ; +; The hdw value also limits the number of sprite SAT entries that the VDC is +; able to scan to find the sprites that are on the next line. +; ; ; VDC @ 5.36MHz, MWR=$x0 (1-clk-per-access) ; -; hds $02 hdw $1F -> 32 chr = 256 pxl -> 16 sprites -; hds $02 hdw $20 -> 33 chr = 264 pxl -> 14 sprites -; hds $02 hdw $21 -> 34 chr = 272 pxl -> 12 sprites +; hds $02 hdw $1C -> 29 chr = 232 pxl -> 59 SAT searched, 16 sprites shown +; hds $02 hdw $1D -> 30 chr = 240 pxl -> 61 SAT searched, 16 sprites shown +; hds $02 hdw $1E -> 31 chr = 248 pxl -> 63 SAT searched, 16 sprites shown +; hds $02 hdw $1F -> 32 chr = 256 pxl -> 64 SAT searched, 16 sprites shown +; hds $02 hdw $20 -> 33 chr = 264 pxl -> 64 SAT searched, 14 sprites shown +; hds $02 hdw $21 -> 34 chr = 272 pxl -> 64 SAT searched, 12 sprites shown ; ; ; VDC @ 7.16MHz, MWR=$x0 (1-clk-per-access) ; -; hds $06 hdw $25 -> 38 chr = 304 pxl -> 16 sprites +; hds $07 hdw $1C -> 29 chr = 232 pxl -> 59 SAT searched, 16 sprites shown +; hds $07 hdw $1D -> 30 chr = 240 pxl -> 61 SAT searched, 16 sprites shown +; hds $07 hdw $1E -> 31 chr = 248 pxl -> 63 SAT searched, 16 sprites shown +; hds $07 hdw $1F -> 32 chr = 256 pxl -> 64 SAT searched, 16 sprites shown ; ... -; hds $03 hdw $2B -> 44 chr = 352 pxl -> 16 sprites -; hds $03 hdw $2C -> 45 chr = 360 pxl -> 16 sprites -; hds $03 hdw $2D -> 46 chr = 368 pxl -> 16 sprites -; hds $03 hdw $2E -> 47 chr = 376 pxl -> 14 sprites -; hds $03 hdw $2F -> 48 chr = 384 pxl -> 12 sprites +; hds $06 hdw $25 -> 38 chr = 304 pxl -> 64 SAT searched, 16 sprites shown +; ... +; hds $03 hdw $2B -> 44 chr = 352 pxl -> 64 SAT searched, 16 sprites shown +; hds $03 hdw $2C -> 45 chr = 360 pxl -> 64 SAT searched, 16 sprites shown +; hds $03 hdw $2D -> 46 chr = 368 pxl -> 64 SAT searched, 16 sprites shown +; hds $03 hdw $2E -> 47 chr = 376 pxl -> 64 SAT searched, 14 sprites shown +; hds $03 hdw $2F -> 48 chr = 384 pxl -> 64 SAT searched, 12 sprites shown ; ; ; VDC @ 7.16MHz, MWR=$xA (2-clk-per-access) ; -; hds $06 hdw $25 -> 38 chr = 304 pxl -> 16 sprites -; hds $05 hdw $26 -> 39 chr = 312 pxl -> 15 sprites -; hds $05 hdw $27 -> 40 chr = 320 pxl -> 14 sprites -; hds $04 hdw $28 -> 41 chr = 328 pxl -> 13 sprites -; hds $04 hdw $29 -> 42 chr = 336 pxl -> 12 sprites -; hds $03 hdw $2A -> 43 chr = 344 pxl -> 11 sprites -; hds $03 hdw $2B -> 44 chr = 352 pxl -> 10 sprites +; hds $07 hdw $1C -> 29 chr = 232 pxl -> 58 SAT searched, 16 sprites shown +; hds $07 hdw $1D -> 30 chr = 240 pxl -> 60 SAT searched, 16 sprites shown +; hds $07 hdw $1E -> 31 chr = 248 pxl -> 62 SAT searched, 16 sprites shown +; hds $07 hdw $1F -> 32 chr = 256 pxl -> 64 SAT searched, 16 sprites shown +; ... +; hds $06 hdw $25 -> 38 chr = 304 pxl -> 64 SAT searched, 16 sprites shown +; hds $05 hdw $26 -> 39 chr = 312 pxl -> 64 SAT searched, 15 sprites shown +; hds $05 hdw $27 -> 40 chr = 320 pxl -> 64 SAT searched, 14 sprites shown +; hds $04 hdw $28 -> 41 chr = 328 pxl -> 64 SAT searched, 13 sprites shown +; hds $04 hdw $29 -> 42 chr = 336 pxl -> 64 SAT searched, 12 sprites shown +; hds $03 hdw $2A -> 43 chr = 344 pxl -> 64 SAT searched, 11 sprites shown +; hds $03 hdw $2B -> 44 chr = 352 pxl -> 64 SAT searched, 10 sprites shown ; ; ; VDC @ 10.74MHz, MWR=$xA (2-clk-per-access) ; -; hds $0B hdw $3B -> 60 chr = 480 pxl -> 16 sprites +; hds $17 hdw $1C -> 29 chr = 232 pxl -> 58 SAT searched, 16 sprites shown +; hds $17 hdw $1D -> 30 chr = 240 pxl -> 60 SAT searched, 16 sprites shown +; hds $17 hdw $1E -> 31 chr = 248 pxl -> 62 SAT searched, 16 sprites shown +; hds $17 hdw $1F -> 32 chr = 256 pxl -> 64 SAT searched, 16 sprites shown ; ... -; hds $0B hdw $3F -> 64 chr = 512 pxl -> 16 sprites -; hds $0B hdw $40 -> 65 chr = 520 pxl -> 16 sprites -; hds $0B hdw $41 -> 66 chr = 528 pxl -> 16 sprites -; hds $0B hdw $42 -> 67 chr = 536 pxl -> 16 sprites -; hds $0B hdw $43 -> 68 chr = 544 pxl -> 15 sprites -; hds $0B hdw $44 -> 69 chr = 552 pxl -> 14 sprites +; hds $0B hdw $3B -> 60 chr = 480 pxl -> 64 SAT searched, 16 sprites shown +; ... +; hds $0B hdw $3F -> 64 chr = 512 pxl -> 64 SAT searched, 16 sprites shown +; hds $0B hdw $40 -> 65 chr = 520 pxl -> 64 SAT searched, 16 sprites shown +; hds $0B hdw $41 -> 66 chr = 528 pxl -> 64 SAT searched, 16 sprites shown +; hds $0B hdw $42 -> 67 chr = 536 pxl -> 64 SAT searched, 16 sprites shown +; hds $0B hdw $43 -> 68 chr = 544 pxl -> 64 SAT searched, 15 sprites shown +; hds $0B hdw $44 -> 69 chr = 552 pxl -> 64 SAT searched, 14 sprites shown ; @@ -132,6 +152,9 @@ ; (88 to BYR & CR, 90 to BXR from HW IRQ1, including 8-cycle CPU response) ; Safe to write BYR @ 67 cpu cycles if width=264 hdw=$20 ; +; Flashing (i.e. unstable latching) at 5.36MHz (with MWR = $x0), width=256 .. +; (87 cycles to BYR & CR, 89 to BXR from HW IRQ1, including 8-cycle CPU response) +; ; ; 7.16MHz (with MWR = $x0) ; @@ -142,6 +165,9 @@ ; Safe to write BYR @ 74 cpu cycles if width=352 hdw=$2B ; (83 to BYR, 84 to CR, 85 to BXR from HW IRQ1, including 8-cycle CPU response) ; +; Flashing (i.e. unstable latching) at 7.16MHz (with MWR = $x0), width=352 .. +; (82 cycles to BYR & CR, 84 to BXR from HW IRQ1, including 8-cycle CPU response) +; ; ; 10.74MHz (with MWR = $xA) ; @@ -163,8 +189,7 @@ ; instruction, and not to the start of the instruction. ; ; Note: The VDC shadows/locks the BYR register a cycle before -; the BXR register, so write BYR first. After BXR, the -; CR register is shadowed/locked next. +; the BXR register, so write BYR first. ; @@ -179,3 +204,21 @@ fedcba98765zzzzz = 32-word granularity = 64-byte granularity, designed for 16x16 -------YY--zzzzz = for 64-high fedcba9yyx0----- = 512-word granularity = 1KB-byte granularity, designed for 32x64-4bpp + + + +; *************************************************************************** +; PC ENGINE VDC BURST MODE +; *************************************************************************** + +When is Burst Mode triggered (i.e. locked in for the next frame) so that any +changes to the VDC's R05 BG and SPR bits will be ignored for the next frame? + +For a centered 208 high screen, Burst Mode is triggered between lines 229/230. +For a centered 224 high screen, Burst Mode is triggered between lines 237/238. +For a centered 240 high screen, Burst Mode is triggered between lines 245/246. + +These basically correspond to VCE line 260, which is the start of the VSYNC +pulse. + +(N.B. Add +64 for the RCR line.) diff --git a/examples/asm/elmer/font/font8x8-bold-short-etswst-pt.fon b/examples/asm/elmer/font/font8x8-bold-short-etswst-pt.fon new file mode 100644 index 00000000..867c3905 Binary files /dev/null and b/examples/asm/elmer/font/font8x8-bold-short-etswst-pt.fon differ diff --git a/examples/asm/elmer/font/font8x8-bold-short-iso646-de.fon b/examples/asm/elmer/font/font8x8-bold-short-iso646-de.fon index 05b5c5a7..5d20155f 100644 Binary files a/examples/asm/elmer/font/font8x8-bold-short-iso646-de.fon and b/examples/asm/elmer/font/font8x8-bold-short-iso646-de.fon differ diff --git a/examples/asm/elmer/font/font8x8-bold-short-iso646-en.fon b/examples/asm/elmer/font/font8x8-bold-short-iso646-en.fon index c98e4bde..c13a7d2c 100644 Binary files a/examples/asm/elmer/font/font8x8-bold-short-iso646-en.fon and b/examples/asm/elmer/font/font8x8-bold-short-iso646-en.fon differ diff --git a/examples/asm/elmer/font/font8x8-bold-short-iso646-fr.fon b/examples/asm/elmer/font/font8x8-bold-short-iso646-fr.fon index 025db683..cc95c1c1 100644 Binary files a/examples/asm/elmer/font/font8x8-bold-short-iso646-fr.fon and b/examples/asm/elmer/font/font8x8-bold-short-iso646-fr.fon differ diff --git a/examples/asm/elmer/font/font8x8-bold-short-iso646-it.fon b/examples/asm/elmer/font/font8x8-bold-short-iso646-it.fon index b979659d..7e3c1d02 100644 Binary files a/examples/asm/elmer/font/font8x8-bold-short-iso646-it.fon and b/examples/asm/elmer/font/font8x8-bold-short-iso646-it.fon differ diff --git a/examples/asm/elmer/font/font8x8-bold-short-iso646-jp.fon b/examples/asm/elmer/font/font8x8-bold-short-iso646-jp.fon new file mode 100644 index 00000000..89bc8c15 Binary files /dev/null and b/examples/asm/elmer/font/font8x8-bold-short-iso646-jp.fon differ diff --git a/examples/asm/elmer/include/bare-startup.asm b/examples/asm/elmer/include/bare-startup.asm index 6de5f3da..6c63e11f 100644 --- a/examples/asm/elmer/include/bare-startup.asm +++ b/examples/asm/elmer/include/bare-startup.asm @@ -367,19 +367,17 @@ DATA_BANK = BASE_BANK + 1 + RESERVE_BANKS .zp .org $2000 -_temp ds 2 ; Use within any ASM routine. -_bank ds 1 ; Use within any ASM routine. +__temp ds 2 ; Use within any ASM routine. +_bp_bank ds 1 ; Use within any ASM routine. -base_zp1st = $2003 ; 1st free user address. -base_zpend = $20EC +base_zp1st = $F8:2003 ; 1st free user address. +base_zpend = $F8:20EC -base_ram1st = $22D0 ; After the System Card! +base_ram1st = $F8:22D0 ; After the System Card! .bss .org base_ram1st -DATA_BANK = 1 - .data .bank DATA_BANK .org $6000 diff --git a/examples/asm/elmer/include/cdrom.asm b/examples/asm/elmer/include/cdrom.asm index 652afd70..49e706c6 100644 --- a/examples/asm/elmer/include/cdrom.asm +++ b/examples/asm/elmer/include/cdrom.asm @@ -107,6 +107,9 @@ SUPPORT_TIMING = 0 ; SCSI bus signals. +SCSI_SEL = $81 ; IFU_SCSI_CTL When PCE selects the CD-ROM device +SCSI_RST = $60 ; IFU_SCSI_CTL When aborting the current command + SCSI_MSK = $F8 ; IFU_SCSI_FLG SCSI_BSY = $80 ; IFU_SCSI_FLG Bus is Busy or Free SCSI_REQ = $40 ; IFU_SCSI_FLG Target Requests next Xfer @@ -114,7 +117,7 @@ SCSI_MSG = $20 ; IFU_SCSI_FLG Bus contains a Message SCSI_CXD = $10 ; IFU_SCSI_FLG Bus contains Control or /Data SCSI_IXO = $08 ; IFU_SCSI_FLG Bus Initiator or Target -SCSI_ACK = $80 ; IFU_IRQ_MSK +SCSI_ACK = $80 ; IFU_IRQ_MSK Initiator's side of REQ/ACK handshake ; SCSI bus phases. @@ -198,7 +201,7 @@ cplay_scsi_buf = scsi_send_buf ; Reuse the SCSI buffer. .if SUPPORT_TIMING scsi_stat_indx: ds 1 ; Track CD-ROM loading speed -scsi_stat_time: ds 256 ; (cdr_read_bnk & +scsi_stat_time: ds 256 ; (cdr_read_bnk & .endif SUPPORT_TIMING .code @@ -222,7 +225,12 @@ scsi_stat_time: ds 256 ; (cdr_read_bnk & ; *************************************************************************** ; *************************************************************************** ; -; scsi_handshake - Clock a byte of data onto the SCSI bus. +; scsi_handshake - Clock a byte of data on the SCSI bus in or out. +; +; Used after a SCSI_REQ from the CD-ROM target to acknowledge the data byte +; sent or received to/from IFU_SCSI_DAT. +; +; This is the manual version of using IFU_SCSI_AUTO to read a byte. ; ; N.B. On a HuCARD, this must be available for cdr_cplay_irq2! ; @@ -317,8 +325,7 @@ cdr_cplay_irq2: pha .got_int_stop: lda #IFU_INT_END ; Disable IFU_INT_END. trb IFU_IRQ_MSK - lda #$01 ; Disable IRQ2 vector. - trb 16-bit unsigned multiply. ; -; Args: _ax = 16-bit Multiplicand / Result -; Args: _cl = 8-bit Multiplier +; Args: _al = 8-bit Multiplier +; Args: _cl = 16-bit Multiplicand +; +; Returns: _ax = 16-bit Result +; +; Returns: Y=0,Z-flag,N-flag. +; +; Preserved: _cx,_dx +; +; Derived from Leo J Scanlon's 16x16 multiply in the book "6502 Software +; Design" with an optimization to rotate the result into the multiplier. +; +; This is very similar to TobyLobster's modificaton to the 16x16 multiply +; from "The Merlin 128 Macro Assembler" disk, but with optimized branches. +; +; See https://github.com/TobyLobster/multiply_test/blob/main/tests/mult2.a +; +; Takes between 158..190 cycles, 174 on average. +; +; Note: Unrolling the loop once saves 16 cycles, but IMHO that's not worth +; the extra 8-bytes of code. +; +; Note: Fully unrolling the loop saves 36 cycles, but the extra 49 bytes of +; code mean that it should be a procedure, and then the trampoline overhead +; would actually make it no faster! ; -mul_8x16u: .proc +mul_8x8u: cla ; Clear top byte of result. - cla ; Clear Result. - clx - lsr <_cl ; Shift and test multiplier. - bcc .loop + ldy #8 ; Loop 8 times. -.add: clc ; Add _ax to the Result. - adc.l <_ax - sax - adc.h <_ax - sax + lsr <_ax + 0 ; Divide multiplier by 2 and + bcc .rotate ; clear 8th bit (important). -.loop: asl.l <_ax ; _ax = _ax * 2 - rol.h <_ax - lsr <_cl ; Shift and test multiplier. - bcs .add - bne .loop - sta.l <_ax ; Save Result. - stx.h <_ax +.add: clc ; Add the 8-bit multiplicand + adc <_cl ; to top 8-bits of the result. + +.rotate: ror a ; Rotate result into the top + ror <_ax + 0 ; bits of the multiplier. + + dey + bcs .add ; Add multiplicand to top byte? + bne .rotate ; Completed 8 loops? + + sta <_ax + 1 ; Save top byte of result. + + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; mul_16x8u - Simple 16-bit x 8-bit -> 24-bit unsigned multiply. +; +; Args: _al = 8-bit Multiplier +; Args: _cx = 16-bit Multiplicand +; +; Returns: _ax,_bl = 24-bit Result +; +; Returns: A=Y=0,Z-flag,N-flag. +; +; Preserved: _cx,_dx +; +; Derived from Leo J Scanlon's 16x16 multiply in the book "6502 Software +; Design" with an optimization to rotate the result into the multiplier. +; +; This is very similar to TobyLobster's modificaton to the 16x16 multiply +; from "The Merlin 128 Macro Assembler" disk, but with optimized branches. +; +; See https://github.com/TobyLobster/multiply_test/blob/main/tests/mult2.a +; +; Takes between 243..403 cycles, 323 on average, including 47 cycle procedure +; call overhead vs 14 cycles for a JSR+RTS. +; + +mul_16x8u: .proc + + cla ; Clear top word of result. + sta <_ax + 1 + + ldy #8 ; Loop 8 times. + + lsr <_ax + 0 ; Divide multiplier by 2 and + bcc .rotate ; clear 8th bit (important). + +.add: tax ; Preserve top byte of result. + + clc ; Add the 16-bit multiplicand + lda <_ax + 1 ; to top 16-bits of the result. + adc.l <_cx + sta <_ax + 1 + + txa ; Restore top byte of result. + adc.h <_cx + +.rotate: ror a ; Rotate result into the top + ror <_ax + 1 ; bits of the multiplier ... + + ror <_ax + 0 ; and divide multiplier by 2. + + dey + bcs .add ; Add multiplicand to top word? + bne .rotate ; Completed 8 loops? + + sta <_ax + 2 ; Save top byte of result. leave @@ -55,38 +137,287 @@ mul_8x16u: .proc ; *************************************************************************** ; *************************************************************************** ; -; mul_8x24u - Simple 24-bit x 8-bit multiply. +; mul_16x16u - Simple 16-bit x 16-bit -> 32-bit unsigned multiply. ; -; Args: _ax,_bl = 24-bit Multiplicand / Result -; Args: _cl = 8-bit Multiplier +; Args: _ax = 16-bit Multiplier +; Args: _cx = 16-bit Multiplicand +; +; Returns: _ax,_bx = 32-bit Result +; +; Returns: A=Y=0,Z-flag,N-flag. +; +; Preserved: _cx,_dx +; +; Derived from Leo J Scanlon's 16x16 multiply in the book "6502 Software +; Design" with an optimization to rotate the result into the multiplier. +; +; This is the same as TobyLobster's modificaton to the 16x16 multiply from +; Dr Jefyll "http://forum.6502.org/viewtopic.php?f=9&t=689&start=0#p19958", +; but with optimized branches. +; +; See https://github.com/TobyLobster/multiply_test/blob/main/tests/mult60.a +; +; Takes between 441..809 cycles, 625 on average, including 47 cycle procedure +; call overhead vs 14 cycles for a JSR+RTS. +; +; Note: Unrolling the outer loop saves 12..60 cycles, but IMHO that's not +; worth the extra 22-bytes of code! ; -mul_8x24u: .proc +mul_16x16u: .proc - cla ; Clear Result. - clx - cly - lsr <_cl ; Shift and test multiplier. - bcc .loop + cla ; Clear top word of result. + sta <_ax + 2 -.add: clc ; Add _ax to the Result. - adc <_ax + 0 - sax ; x = lo-byte, a = mi-byte - adc <_ax + 1 - sax - say ; y = lo-byte, a = hi-byte - adc <_ax + 2 - say + ldx #-2 ; Multiplier is 2 bytes long. -.loop: asl <_ax + 0 ; _ax = _ax * 2 - rol <_ax + 1 - rol <_ax + 2 - lsr <_cl ; Shift and test multiplier. - bcs .add - bne .loop - sta <_ax + 0 ; Save Result. - stx <_ax + 1 - sty <_ax + 2 +.loop: ldy #8 ; 8 bits in a byte. + + lsr <_ax + 2, x ; Divide multiplier by 2 and + bcc .rotate ; clear 8th bit (important). + +.add: pha ; Preserve top byte of result. + + clc ; Add the 16-bit multiplicand + lda <_ax + 2 ; to top 16-bits of the result. + adc.l <_cx + sta <_ax + 2 + + pla ; Restore top byte of result. + adc.h <_cx + +.rotate: ror a ; Rotate result into the top + ror <_ax + 2 ; bits of the multiplier ... + + ror <_ax + 2, x ; and divide multiplier by 2. + + dey + bcs .add ; Add multiplicand to top word? + bne .rotate ; Completed 8 bits? + + inx ; Loop to the next higher byte + bne .loop ; in the multiplier. + + sta <_ax + 3 ; Save top byte of result. + + leave + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; mul_24x8u - Simple 24-bit x 8-bit -> 32-bit unsigned multiply. +; +; Args: _al = 8-bit Multiplier +; Args: _cx,_dl = 24-bit Multiplicand +; +; Returns: _ax,_bx = 32-bit Result +; +; Returns: A=Y=0,Z-flag,N-flag. +; +; Preserved: _cx,_dx +; +; Derived from Leo J Scanlon's 16x16 multiply in the book "6502 Software +; Design" with an optimization to rotate the result into the multiplier. +; +; This is very similar to TobyLobster's modificaton to the 16x16 multiply +; from "The Merlin 128 Macro Assembler" disk, but with optimized branches. +; +; See https://github.com/TobyLobster/multiply_test/blob/main/tests/mult2.a +; +; Takes between 295..551 cycles, 423 on average, including 47 cycle procedure +; call overhead vs 14 cycles for a JSR+RTS. +; + +mul_24x8u: .proc + + cla ; Clear top 24-bits of result. + sta <_ax + 2 + sta <_ax + 1 + + ldy #8 ; Loop 8 times. + + lsr <_ax + 0 ; Divide multiplier by 2 and + bcc .rotate ; clear 8th bit (important). + +.add: tax ; Preserve top byte of result. + + clc ; Add the 24-bit multiplicand + lda <_ax + 1 ; to top 24-bits of the result. + adc <_cx + 0 + sta <_ax + 1 + + lda <_ax + 2 + adc <_cx + 1 + sta <_ax + 2 + + txa ; Restore top byte of result. + adc <_cx + 2 + +.rotate: ror a ; Rotate result into the top + ror <_ax + 2 ; bits of the multiplier ... + ror <_ax + 1 + + ror <_ax + 0 ; and divide multiplier by 2. + + dey + bcs .add ; Add multiplicand to top bits? + bne .rotate ; Completed 8 loops? + + sta <_ax + 3 ; Save top byte of result. + + leave + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; mul_24x16u - Simple 24-bit x 16-bit -> 40-bit unsigned multiply. +; +; Args: _ax = 16-bit Multiplier +; Args: _cx,_dl = 24-bit Multiplicand +; +; Returns: _ax,_bx,Y = 40-bit Result +; +; Returns: A=Y,Z-flag,N-flag. +; +; Preserved: _cx,_dx +; +; Derived from Leo J Scanlon's 16x16 multiply in the book "6502 Software +; Design" with an optimization to rotate the result into the multiplier. +; +; This is the same as TobyLobster's modificaton to the 16x16 multiply from +; Dr Jefyll "http://forum.6502.org/viewtopic.php?f=9&t=689&start=0#p19958", +; but with optimized branches. +; +; See https://github.com/TobyLobster/multiply_test/blob/main/tests/mult60.a +; +; Takes between 539..1099 cycles, 819 on average, including 47 cycle procedure +; call overhead vs 14 cycles for a JSR+RTS. +; + +mul_24x16u: .proc + + cla ; Clear top 24-bits of result. + sta <_ax + 3 + sta <_ax + 2 + + ldx #-2 ; Multiplier is 2 bytes long. + +.loop: ldy #8 ; 8 bits in a byte. + + lsr <_ax + 2, x ; Divide multiplier by 2 and + bcc .rotate ; clear 8th bit (important). + +.add: pha ; Preserve top byte of result. + + clc ; Add the 24-bit multiplicand + lda <_ax + 2 ; to top 24-bits of the result. + adc <_cx + 0 + sta <_ax + 2 + + lda <_ax + 3 + adc <_cx + 1 + sta <_ax + 3 + + pla ; Restore top byte of result. + adc <_cx + 2 + +.rotate: ror a ; Rotate result into the top + ror <_ax + 3 ; bits of the multiplier ... + ror <_ax + 2 + + ror <_ax + 2, x ; and divide multiplier by 2. + + dey + bcs .add ; Add multiplicand to top bits? + bne .rotate ; Completed 8 bits? + + inx ; Loop to the next higher byte + bne .loop ; in the multiplier. + + tay ; Save top byte of result. + + leave + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; mul_32x8u - Simple 32-bit x 8-bit -> 40-bit unsigned multiply. +; +; Args: _ax = 8-bit Multiplier +; Args: _cx,_dx = 32-bit Multiplicand +; +; Returns: _ax,_bx,Y = 40-bit Result +; +; Returns: A=Y,Z-flag,N-flag. +; +; Preserved: _cx,_dx +; +; Derived from Leo J Scanlon's 16x16 multiply in the book "6502 Software +; Design" with an optimization to rotate the result into the multiplier. +; +; This is very similar to TobyLobster's modificaton to the 16x16 multiply +; from "The Merlin 128 Macro Assembler" disk, but with optimized branches. +; +; See https://github.com/TobyLobster/multiply_test/blob/main/tests/mult2.a +; +; Takes between 345..697 cycles, 521 on average, including 47 cycle procedure +; call overhead vs 14 cycles for a JSR+RTS. +; + +mul_32x8u: .proc + + cla ; Clear top 32-bits of result. + sta <_ax + 3 + sta <_ax + 2 + sta <_ax + 1 + + ldy #8 ; Loop 8 times. + + lsr <_ax + 0 ; Divide multiplier by 2 and + bcc .rotate ; clear 8th bit (important). + +.add: tax ; Preserve top byte of result. + + clc ; Add the 32-bit multiplicand + lda <_ax + 1 ; to top 32-bits of the result. + adc <_cx + 0 + sta <_ax + 1 + + lda <_ax + 2 + adc <_cx + 1 + sta <_ax + 2 + + lda <_ax + 3 + adc <_cx + 2 + sta <_ax + 3 + + txa ; Restore top byte of result. + adc <_cx + 3 + +.rotate: ror a ; Rotate result into the top + ror <_ax + 3 ; bits of the multiplier ... + ror <_ax + 2 + ror <_ax + 1 + + ror <_ax + 0 ; and divide multiplier by 2. + + dey + bcs .add ; Add multiplicand to top bits? + bne .rotate ; Completed 8 loops? + + tay ; Save top byte of result. leave @@ -101,10 +432,12 @@ mul_8x24u: .proc ; ; Args: _ax = Dividend / Quotient ; Args: _bx = Dividend / Quotient (if 32-bit) -; Args: _cl = Dividor +; Args: _cl = Divisor ; ; Returns: Y=A,Z-flag,N-flag = Remainder. ; +; Preserved: _cx,_dx +; div16_7u .proc @@ -139,6 +472,8 @@ div16_7u .proc ; ; Returns: Y=A,Z-flag,N-flag = Remainder. ; +; Preserved: _cx,_dx +; div32_7u .proc diff --git a/examples/asm/elmer/include/mb128-base.asm b/examples/asm/elmer/include/mb128-base.asm index ca03181f..84650da0 100644 --- a/examples/asm/elmer/include/mb128-base.asm +++ b/examples/asm/elmer/include/mb128-base.asm @@ -101,7 +101,7 @@ mb1_detected: ds 1 ; NZ if MB128 ever detected. ; Args: _al = Sector address (0..255). ; Args: _ah = Sector count (0..255). ; -; Uses: _temp +; Uses: __temp ; ; Returns: Y,A,Z-flag,N-flag = MB1_OK or an error code. ; @@ -189,7 +189,7 @@ mb1_read_data .proc ; Args: _al = Sector address (0..255). ; Args: _ah = Sector count (0..255). ; -; Uses: _temp +; Uses: __temp ; ; Returns: Y,A,Z-flag,N-flag = MB1_OK or an error code. ; @@ -279,7 +279,7 @@ mb1_write_data .proc ; Args: _al = Sector address (0..255). ; Args: _ah = Sector count (0..255). ; -; Uses: _temp +; Uses: __temp ; ; Returns: Y,A,Z-flag,N-flag = MB1_OK or an error code. ; @@ -371,7 +371,7 @@ mb1_check_data .proc ; ; mb1_detect - Detect whether an MB128 is present. ; -; Uses: _temp +; Uses: __temp ; ; Returns: Y,A,Z-flag,N-flag = MB1_OK or an error code. ; @@ -421,7 +421,7 @@ mb1_detect .proc ; ; Returns: Y,A,Z-flag,N-flag = MB1_OK or an error code. ; -; Uses: _temp +; Uses: __temp ; ; N.B. For INTERNAL use, not for APPLICATION use! ; @@ -438,7 +438,7 @@ mb1_wakeup: ldy #$80 + 1 ; Max 128KB of data to "unjam". lda IO_PORT ; Read buttons. and #$0F - sta <_temp + sta <__temp lda #%11 ; Send '1' bit to MB128. jsr mb1_send_bits ; Selects direction-pad. @@ -449,7 +449,7 @@ mb1_wakeup: ldy #$80 + 1 ; Max 128KB of data to "unjam". asl a asl a -.self_mod: ora <_temp ; Composite the buttons. +.self_mod: ora <__temp ; Composite the buttons. cmp #$40 ; Magic value for detection. bne .not_detected ; L, R, U, RUN, SEL, I & II. diff --git a/examples/asm/elmer/include/movie.asm b/examples/asm/elmer/include/movie.asm index 4094a31b..bc65431d 100644 --- a/examples/asm/elmer/include/movie.asm +++ b/examples/asm/elmer/include/movie.asm @@ -78,6 +78,127 @@ ; ; *************************************************************************** ; *************************************************************************** +; +; Suggested video sizes for new 8-frames-per-second HuVIDEO data streams ... +; +; +; 256x104 (approximately 2.39x1) +; 32x13 = 416 CHR +; $3400 tiles ($0770 bytes-per-tick * 7 -> $3410) +; $0200 palettes +; $00D0 tile palettes +; $03E8 adpcm (1000 bytes, 2000 samples) +; $0028 adpcm resync +; = +; $3AE0 -> $3B00 * 8 -> 118KB/s +; +; +; 224x120 (approximately 16x9) +; 28x15 = 420 CHR +; $3480 tiles ($0780 bytes-per-tick * 7 -> $3480) +; $0200 palettes +; $00D2 tile palettes +; $03E8 adpcm (1000 bytes, 2000 samples) +; $0028 adpcm resync +; = +; $3B62 -> $3C00 * 8 -> 120KB/s +; +; +; 192x144 (approximately 4x3) +; 24x18 = 432 CHR +; $3600 tiles ($07C0 bytes-per-tick * 7 -> $3640) +; $0200 palettes +; $00D8 tile palettes +; $03E8 adpcm (1000 bytes, 2000 samples) +; $0028 adpcm resync +; = +; $3CE8 -> $3D00 * 8 -> 122KB/s +; +; +; Suggested video sizes for new 10-frames-per-second HuVIDEO data streams ... +; +; +; 224x96 (approximately 2.39x1) +; 28x12 = 336 CHR +; $2A00 tiles ($0700 bytes-per-tick * 6 -> $2A00) +; $0200 palettes +; $00A8 tile palettes +; $0320 adpcm (800 bytes, 1600 samples) +; $0028 adpcm resync +; = +; $2FF0 -> $3000 * 10 -> 120KB/s +; +; +; 192x112 (approximately 16x9) +; 24x14 = 336 CHR +; $2A00 tiles ($0700 bytes-per-tick * 6 -> $2A00) +; $0200 palettes +; $00A8 tile palettes +; $0320 adpcm (800 bytes, 1600 samples) +; $0028 adpcm resync +; = +; $2FF0 -> $3000 * 10 -> 120KB/s +; +; +; 176x120 (approximately 4x3) +; 22x15 = 330 CHR +; $2940 tiles ($06E0 bytes-per-tick * 6 -> $2940) +; $0200 palettes +; $00A5 tile palettes +; $0320 adpcm (800 bytes, 1600 samples) +; $0028 adpcm resync +; = +; $2F2D -> $3000 * 10 -> 120KB/s +; +; +; Suggested video sizes for new 12-frames-per-second HuVIDEO data streams ... +; +; +; 208x88 (approximately 2.39x1) +; 26x11 = 286 CHR +; $23C0 tiles ($0730 bytes-per-tick * 5 -> $23F0) +; $01E0 palettes **NOTE** +; $008F tile palettes +; $02A0 adpcm (669 bytes, 1338 samples) +; $0028 adpcm resync +; = +; $28F7 -> $2900 * 12 -> 123KB/s +; +; +; 176x104 (approximately 16x9) +; 22x13 = 286 CHR +; $23C0 tiles ($0730 bytes-per-tick * 5 -> $23F0) +; $01E0 palettes **NOTE** +; $008F tile palettes +; $02A0 adpcm (669 bytes, 1338 samples) +; $0028 adpcm resync +; = +; $28F7 -> $2900 * 12 -> 123KB/s +; +; +; 184x96 (approximately 16x9) +; 23x12 = 276 CHR +; $2280 tiles ($06F0 bytes-per-tick * 5 -> $22B0) +; $0200 palettes +; $0090 tile palettes +; $02A0 adpcm (669 bytes, 1338 samples) +; $0028 adpcm resync +; = +; $27D8 -> $2800 * 12 -> 120KB/s +; +; +; 160x112 (approximately 4x3) +; 20x14 = 280 CHR +; $2300 tiles ($0700 bytes-per-tick * 5 -> $2300) +; $0200 palettes +; $008C tile palettes +; $02A0 adpcm (669 bytes, 1338 samples) +; $0028 adpcm resync +; = +; $2854 -> $2900 * 12 -> 123KB/s +; +; *************************************************************************** +; *************************************************************************** ; ; Configure Library ... @@ -418,10 +539,10 @@ huv_proc_header:lda #BUFFER_1ST_BANK ; Map the workspace into MPR3. lda.l HUV_FRM_COUNT ; Save the #frames in sta.l 24-bit lda <_ax + 0 ; Preserve page-offset into and #7 ; the sector. @@ -526,10 +646,10 @@ huv_play_from: stz.l bg_x1 ; Reset screen flip. lda.l = val. -f32_cluster_msk:dd $0FFFFFFF ; Mask out the top 4-bits. .endp ; f32_mount_vol @@ -769,6 +766,10 @@ f32_use_cluster:ldy #3 ; Copy the cluster # from the .bad_cluster: ldy #F32_ERR_INVALID ; Invalid cluster. rts +f32_cluster_bad:dd $0FFFFFF7 ; Test if == val. +f32_cluster_eoc:dd $0FFFFFF8 ; Test if >= val. +f32_cluster_msk:dd $0FFFFFFF ; Mask out the top 4-bits. + ; *************************************************************************** @@ -806,7 +807,7 @@ f32_set_cluster:clx ; Copy the cluster # from the ; N.B. This includes unused ($E5) and end-of-directory ($00) entries. ; ; Uses: f32_ptr = Pointer to directory entry within f32_cache_buf. -; Uses: _temp = Temporary variable (trashed). +; Uses: __temp = Temporary variable (trashed). ; ; Returns: f32_ptr, Y,Z-flag,N-flag = F32_OK or an error code ; @@ -1010,7 +1011,7 @@ f32_nxt_entry .proc pla jmp !nxt_entry- ; Get the next part of it! -.copy_utf16: sta <_temp ; Copy UTF16 glyphs to the +.copy_utf16: sta <__temp ; Copy UTF16 glyphs to the .copy_loop: lda [f32_ptr], y ; long name buffer. sta f32_long_name, x iny @@ -1027,7 +1028,7 @@ f32_nxt_entry .proc .copy_next: iny inx beq .too_long ; Is name > than 255 glyphs? - cpy <_temp + cpy <__temp bne .copy_loop rts @@ -1390,7 +1391,7 @@ f32_seek_cur .proc sta <_ax + 0 bsr f32_next_frag ; Move forward to next fragment. - bra f32_seek_cur ; Try again. + jmp f32_seek_cur ; Try again. ; frag_len > seek_len diff --git a/examples/asm/elmer/include/ted2-sd.asm b/examples/asm/elmer/include/ted2-sd.asm index f2b11316..6ba3ac8a 100644 --- a/examples/asm/elmer/include/ted2-sd.asm +++ b/examples/asm/elmer/include/ted2-sd.asm @@ -121,7 +121,7 @@ _disk_write_err:db " SDC write sector failed!",$0D,0 .endif SDC_PRINT_MESSAGES - .procgroup ; Group ted2-sd in 1 bank! +ted2_sd .procgroup ; Group ted2-sd in 1 bank! ; Use const_0000 from core-kernal.asm if possible! diff --git a/examples/asm/elmer/include/tty.asm b/examples/asm/elmer/include/tty.asm index c9cd2af1..1bcf16d9 100644 --- a/examples/asm/elmer/include/tty.asm +++ b/examples/asm/elmer/include/tty.asm @@ -297,13 +297,9 @@ tty_printf_huc .proc ; HuC entry point. tma3 ; Preserve MPR3. pha - tya ; Map farptr to MPR3. - beq !+ - tam3 - inc a - tam4 + jsr set_bp_to_mpr34 ; Map farptr to MPR3 & MPR4. -!: stz tty_xyok ; Make sure VRAM addr is set! + stz tty_xyok ; Make sure VRAM addr is set! lda [_bp] ; Get string length from the inc a ; PASCAL-format string, the @@ -489,9 +485,9 @@ tty_printf_huc .proc ; HuC entry point. .endif TTY_NO_DOT == 0 .read_minimum: sbc #'0' ; Initialize the width. - sta <_temp + sta <__temp jsr .next_decimal ; Read the rest. - ldx <_temp ; Set the minimum output. + ldx <__temp ; Set the minimum output. stx tty_outmin .if TTY_NO_DOT == 0 @@ -505,7 +501,7 @@ tty_printf_huc .proc ; HuC entry point. bne .read_length jsr .read_decimal ; Read the precision value. - ldx <_temp ; Set the maximum output. + ldx <__temp ; Set the maximum output. stx tty_outmax cmp '#' ; Or read the maximum from @@ -816,14 +812,14 @@ tty_printf_huc .proc ; HuC entry point. beq .set_xlhs .set_xpos: jsr .read_decimal ; Read decimal, return chr. - ldx <_temp + ldx <__temp stx tty_xpos stz tty_xyok jmp .test_chr ; Process the next chr. .set_xlhs: iny ; Swallow the 'L'. jsr .read_decimal ; Read decimal, return chr. - ldx <_temp + ldx <__temp stx tty_xlhs jmp .test_chr ; Process the next chr. @@ -839,14 +835,14 @@ tty_printf_huc .proc ; HuC entry point. beq .set_ytop .set_ypos: jsr .read_decimal ; Read decimal, return chr. - ldx <_temp + ldx <__temp stx tty_ypos stz tty_xyok jmp .test_chr ; Process the next chr. .set_ytop: iny ; Swallow the 'T'. jsr .read_decimal ; Read decimal, return chr. - ldx <_temp + ldx <__temp stx tty_ytop jmp .test_chr ; Process the next chr. @@ -897,19 +893,19 @@ tty_printf_huc .proc ; HuC entry point. jsr .read_decimal ; Box width. cmp #',' bne .box_done ; Abort if parameter missing. - lda <_temp + lda <__temp sta <_al jsr .read_decimal ; Box height. cmp #',' bne .box_done ; Abort if parameter missing. - lda <_temp + lda <__temp sta <_ah jsr .read_decimal ; Box type. phy ; Preserve string index. pha ; Preserve next string char. - lda <_temp + lda <__temp sta <_bl call tty_draw_box @@ -994,7 +990,7 @@ tty_printf_huc .proc ; HuC entry point. ; Read decimal number (returns next non-decimal chr read). ; -.read_decimal: stz <_temp ; Initialize to zero. +.read_decimal: stz <__temp ; Initialize to zero. .next_decimal: lda [_bp], y ; Read char from string. iny @@ -1004,12 +1000,12 @@ tty_printf_huc .proc ; HuC entry point. bcc .param_exit sbc #'0' ; Accumulate the decimal value - asl <_temp ; within the range (0..255). - adc <_temp - asl <_temp - asl <_temp - adc <_temp - sta <_temp + asl <__temp ; within the range (0..255). + adc <__temp + asl <__temp + asl <__temp + adc <__temp + sta <__temp bra .next_decimal ; @@ -1327,8 +1323,8 @@ tty_dump_line .proc phx phy - stx.l <_temp - sty.h <_temp + stx.l <__temp + sty.h <__temp cly @@ -1362,7 +1358,7 @@ tty_dump_line .proc phy ldx #1 -.addr_loop: lda <_temp, x +.addr_loop: lda <__temp, x lsr a lsr a lsr a @@ -1374,7 +1370,7 @@ tty_dump_line .proc .addr_lo: sta VDC_DL st2.h #CHR_ZERO - lda <_temp, x + lda <__temp, x and #$0F ora.l #CHR_ZERO + '0' cmp.l #CHR_ZERO + '0' + 10 @@ -1391,7 +1387,7 @@ tty_dump_line .proc st1.l #CHR_ZERO + ' ' st2.h #CHR_ZERO -.byte_loop: lda [_temp], y +.byte_loop: lda [__temp], y lsr a lsr a lsr a @@ -1403,7 +1399,7 @@ tty_dump_line .proc .skip_lo: sta VDC_DL st2.h #CHR_ZERO - lda [_temp], y + lda [__temp], y and #$0F ora.l #CHR_ZERO + '0' cmp.l #CHR_ZERO + '0' + 10 @@ -1425,7 +1421,7 @@ tty_dump_line .proc ply -.char_loop: lda [_temp], y +.char_loop: lda [__temp], y cmp #$20 bcc .non_ascii cmp #$7F diff --git a/examples/asm/elmer/include/unpack-lzsa1.asm b/examples/asm/elmer/include/unpack-lzsa1.asm index eeff1b31..1e5f6b21 100644 --- a/examples/asm/elmer/include/unpack-lzsa1.asm +++ b/examples/asm/elmer/include/unpack-lzsa1.asm @@ -5,9 +5,9 @@ ; ; HuC6280 decompressor for Emmanuel Marty's LZSA1 format. ; -; The code is 171 bytes for the small version, and 197 bytes for the normal. +; The code is 172 bytes for the small version, and 198 bytes for the normal. ; -; Copyright John Brandwood 2019-2021. +; Copyright John Brandwood 2019-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -15,6 +15,18 @@ ; ; *************************************************************************** ; *************************************************************************** +; +; N.B. The decompressor expects the data to be compressed without a header! +; +; Use Emmanuel Marty's LZSA compressor which can be found here ... +; https://github.com/emmanuel-marty/lzsa +; +; To create an LZSA1 file to decompress to RAM +; +; lzsa -r -f 1 +; +; *************************************************************************** +; *************************************************************************** @@ -72,7 +84,9 @@ lzsa1_offset = lzsa1_winptr ; lzsa1_to_ram - Decompress data stored in Emmanuel Marty's LZSA1 format. ; ; Args: _bp, Y = _farptr to compressed data in MPR3. -; Args: _di = ptr to output address in RAM. +; Args: _di = ptr to output address in RAM (anywhere except MPR3!). +; +; Returns: _bp, Y = _farptr to byte after compressed data. ; ; Uses: _bp, _di, _ax, _bl ! ; @@ -82,11 +96,9 @@ lzsa1_to_ram .proc tma3 ; Preserve MPR3. pha - tya ; Map lzsa1_srcptr to MPR3. - beq !+ - tam3 + jsr set_bp_to_mpr3 ; Map lzsa1_srcptr to MPR3. -!: clx ; Initialize hi-byte of length. + clx ; Initialize hi-byte of length. cly ; Initialize source index. ; @@ -291,6 +303,9 @@ lzsa1_to_ram .proc pla ; Decompression completed, pop pla ; return address. + tma3 ; Return final MPR3 in Y reg. + tay + pla ; Restore MPR3. tam3 diff --git a/examples/asm/elmer/include/unpack-lzsa2.asm b/examples/asm/elmer/include/unpack-lzsa2.asm index cb6d3308..98112b84 100644 --- a/examples/asm/elmer/include/unpack-lzsa2.asm +++ b/examples/asm/elmer/include/unpack-lzsa2.asm @@ -5,9 +5,9 @@ ; ; HuC6280 decompressor for Emmanuel Marty's LZSA2 format. ; -; The code is 247 bytes for the small version, and 262 bytes for the normal. +; The code is 248 bytes for the small version, and 263 bytes for the normal. ; -; Copyright John Brandwood 2019-2021. +; Copyright John Brandwood 2019-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -15,6 +15,18 @@ ; ; *************************************************************************** ; *************************************************************************** +; +; N.B. The decompressor expects the data to be compressed without a header! +; +; Use Emmanuel Marty's LZSA compressor which can be found here ... +; https://github.com/emmanuel-marty/lzsa +; +; To create an LZSA2 file to decompress to RAM +; +; lzsa -r -f 2 +; +; *************************************************************************** +; *************************************************************************** @@ -73,7 +85,9 @@ lzsa2_nibble = _dl ; 1 byte. ; lzsa2_to_ram - Decompress data stored in Emmanuel Marty's LZSA2 format. ; ; Args: _bp, Y = _farptr to compressed data in MPR3. -; Args: _di = ptr to output address in RAM. +; Args: _di = ptr to output address in RAM (anywhere except MPR3!). +; +; Returns: _bp, Y = _farptr to byte after compressed data. ; ; Uses: _bp, _di, _ax, _bx, _cx, _dl ! ; @@ -83,11 +97,9 @@ lzsa2_to_ram .proc tma3 ; Preserve MPR3. pha - tya ; Map lzsa2_srcptr to MPR3. - beq !+ - tam3 + jsr set_bp_to_mpr3 ; Map lzsa2_srcptr to MPR3. -!: clx ; Hi-byte of length or offset. + clx ; Hi-byte of length or offset. cly ; Initialize source index. stz > 8 ; Default to a 2KB window in -ZX0_WINMSK = ($0800 - 1) >> 8 ; RAM, located at $3800. - - .endif - - - -; *************************************************************************** -; *************************************************************************** -; -; Data usage is 11 bytes of zero-page, using aliases for clarity. -; - -zx0_srcptr = _bp ; 1 word. -zx0_dstptr = _di ; 1 word. - -zx0_length = _ax ; 1 word. -zx0_offset = _bx ; 1 word. -zx0_winptr = _cx ; 1 word. -zx0_bitbuf = _dl ; 1 byte. - - - -; *************************************************************************** -; *************************************************************************** -; -; zx0_to_ram - Decompress data stored in Einar Saukas's ZX0 "classic" format. -; -; Args: _bp, Y = _farptr to compressed data in MPR3. -; Args: _di = ptr to output address in RAM. -; -; Uses: _bp, _di, _ax, _bx, _cx, _dh ! -; - -zx0_to_ram .proc - - tma3 ; Preserve MPR3. - pha - - .ifdef _KICKC - jsr set_bp_to_mpr3 ; Map zx0_srcptr to MPR3. - .else - tya ; Map zx0_srcptr to MPR3. - beq !+ - tam3 - .endif - -!: ldx #$40 ; Initialize bit-buffer. - - ldy #$FF ; Initialize offset to $FFFF. - sty (CHR_0x10 * 16) + sta <_di + 1 + + lda #$FF ; Put font in colors 4-7, + sta <_al ; so bitplane 2 = $FF and + stz <_ah ; bitplane 3 = $00. + + lda #16 + 96 ; 16 graphics + 96 ASCII. + sta <_bl + + lda #my_font + sta <_bp + 1 + ldy #^my_font + + call dropfnt8x8_vdc ; Upload font to VRAM. + + ; Upload the palette data to the VCE. + + stz <_al ; Start at palette 0 (BG). + lda #2 ; Copy 2 palettes of 16 colors. + sta <_ah + lda #screen_pal + sta <_bp + 1 + ldy #^screen_pal + call load_palettes ; Add to the palette queue. + + call xfer_palettes ; Transfer queue to VCE now. + + ; Turn on the BG & SPR layers, then wait for a soft-reset. + + call set_dspon ; Enable background. + + ; + + PRINTF "\e<\eX1\eY1\eP0***PC ENGINE VDC R/W BUFFER***\n\n\eP1" + + stz.l <_di ; _di = $8000 + lda #$80 + sta <_di + + jsr vdc_di_to_mawr ; Set MAWR=$8000. + + lda #$34 ; Write $1234 to VRAM $8000. + sta VDC_DL + lda #$12 + sta VDC_DH + + tii $2200,$2200,16 ; 113 cycle delay. + + jsr vdc_di_to_marr ; Set MARR=$8000, trigger read. + + tii $2200,$2200,16 ; 113 cycle delay. + + jsr vdc_di_to_mawr ; Set MAWR=$8000. + + lda #$55 ; Write $AA55 to VRAM $8000. + sta VDC_DL + lda #$AA + sta VDC_DH + + tii $2200,$2200,16 ; 113 cycle delay. + + lda VDC_DL ; Read contents of VRAM $8000. + sta.l (CHR_0x10 * 16) + sta <_di + 1 + + lda #$FF ; Put font in colors 4-7, + sta <_al ; so bitplane 2 = $FF and + stz <_ah ; bitplane 3 = $00. + + lda #16 + 96 ; 16 graphics + 96 ASCII. + sta <_bl + + lda #my_font + sta <_bp + 1 + ldy #^my_font + + call dropfnt8x8_vdc ; Upload font to VRAM. + + ; Upload the palette data to the VCE. + + stz <_al ; Start at palette 0 (BG). + lda #3 ; Copy 3 palettes of 16 colors. + sta <_ah + lda #screen_pal + sta <_bp + 1 + ldy #^screen_pal + call load_palettes ; Add to the palette queue. + + call xfer_palettes ; Transfer queue to VCE now. + + ; Identify this program. + + PRINTF "\e<\eX1\eY1\eP0**PC ENGINE VDC MWR VRAM R/W**\eP1\eX3\eY3\x1C\x1D\eP0:Change Test\eP1 \x1E\x1F\eP0:VDC Mode\eP2\n\n" + + ldy $7000 ; 5 + st0 #VDC_MAWR ; 5 + st1 #<$7000 ; 5 + st2 #>$7000 ; 5 + + cli ; 2 Allow next RCR. + + ; Make sure that the next line's RCR interrupt is stable. + +.wait: ds 256, $EA ; 256 NOP instructions. + + jmp .wait ; Shouldn't get here! + + + +; *************************************************************************** +; *************************************************************************** +; +; hsync_proc2 - Wait (455 + want_delay) cycles before starting a TIA. +; +; It takes 23 cycles to get to "hsync_proc2" (including IRQ response). +; + +hsync_proc2: pla ; 4 Throw away the flags and + pla ; 4 the return address to + pla ; 4 hsync_proc1 + + bit VDC_SR ; 6 Acknowledge IRQ. + + ; It takes 41 cycles from RCR to get to here ... + + jsr set_next_rcr ; 75 = 7 + 68 + + st0 #VDC_VWR ; 5 + lda #VDC_VWR ; 2 + sta #cycles. + rol.h tia_delay, x + + clc ; Add the delay_count that + lda.l tia_delay, x ; we used. + adc.l delay_count + sta.l tia_delay, x + lda.h tia_delay, x + adc.h delay_count + sta.h tia_delay, x + + sec ; Subtract 8, i.e. + lda.l tia_delay, x ; (want_delay - delay_count) + sbc.l #8 + sta.l tia_delay, x + lda.h tia_delay, x + sbc.h #8 + sta.h tia_delay, x + + sec ; Subtract the #cycles total + lda.l #455 * WAIT_LINES ; from the time between the + sbc.l tia_delay, x ; two RCR interrupts to get + sta.l tia_delay, x ; the time taken for the TIA. + lda.h #455 * WAIT_LINES + sbc.h tia_delay, x + sta.h tia_delay, x + + .endif + + rmb0 .BAT_SIZE ; Size of BAT in words. + sta <_bl + + call clear_vram_vdc ; Clear VRAM. + .if SUPPORT_SGX + call clear_vram_sgx + .endif + + lda #<.mode_240x192 ; Disable BKG & SPR layers but + sta.l <_bp ; enable RCR & VBLANK IRQ. + lda #>.mode_240x192 + sta.h <_bp + + .if SUPPORT_SGX + call sgx_detect ; Are we really on an SGX? + beq !+ + ldy #^.mode_240x192 ; Set SGX 1st, with no VBL. + call set_mode_sgx + .endif +!: ldy #^.mode_240x192 ; Set VDC 2nd, VBL allowed. + call set_mode_vdc + + call wait_vsync ; Wait for the next VBLANK. + + leave ; All done, phew! + + ; A reduced 240x192 screen to run the tests during VBLANK. + +.mode_240x192: db $80 ; VCE Control Register. + db VCE_CR_5MHz ; Video Clock + + db VDC_MWR ; Memory-access Width Register + dw VDC_MWR_64x32 + VDC_MWR_1CYCLE + db VDC_HSR ; Horizontal Sync Register + dw VDC_HSR_240 + db VDC_HDR ; Horizontal Display Register + dw VDC_HDR_240 + db VDC_VPR ; Vertical Sync Register + dw VDC_VPR_192 + db VDC_VDW ; Vertical Display Register + dw VDC_VDW_192 + db VDC_VCR ; Vertical Display END position Register + dw VDC_VCR_192 + db VDC_DCR ; DMA Control Register + dw $0010 ; Enable automatic VRAM->SATB + db VDC_DVSSR ; VRAM->SATB address $0400 + dw $0800 + db VDC_BXR ; Background X-Scroll Register + dw $0008 + db VDC_BYR ; Background Y-Scroll Register + dw $0000 + db VDC_RCR ; Raster Counter Register + dw $0000 ; Never occurs! + db VDC_CR ; Control Register + dw $000C ; Enable VSYNC & RCR IRQ + db 0 + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; init_336x224 - R-Type USA's 336x224 screen with slow 2-cycle MWR. +; + +init_336x224 .proc + +.BAT_SIZE = 64 * 32 +.SAT_ADDR = .BAT_SIZE ; SAT takes 16 tiles of VRAM. +.CHR_ZERO = .BAT_SIZE / 16 ; 1st tile # after the BAT. +.CHR_0x10 = .CHR_ZERO + 16 ; 1st tile # after the SAT. +.CHR_0x20 = .CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + + call clear_vce ; Clear all palettes. + + lda.l #.CHR_0x20 ; Tile # of ' ' CHR. + sta.l <_ax + lda.h #.CHR_0x20 + sta.h <_ax + + lda #>.BAT_SIZE ; Size of BAT in words. + sta <_bl + + call clear_vram_vdc ; Clear VRAM. + .if SUPPORT_SGX + call clear_vram_sgx + .endif + + lda #<.mode_336x224 ; Disable BKG & SPR layers but + sta.l <_bp ; enable RCR & VBLANK IRQ. + lda #>.mode_336x224 + sta.h <_bp + + .if SUPPORT_SGX + call sgx_detect ; Are we really on an SGX? + beq !+ + ldy #^.mode_336x224 ; Set SGX 1st, with no VBL. + call set_mode_sgx + .endif +!: ldy #^.mode_336x224 ; Set VDC 2nd, VBL allowed. + call set_mode_vdc + + call wait_vsync ; Wait for the next VBLANK. + + leave ; All done, phew! + + ; R-Type USA's 336x224 screen with slow 2-cycle MWR. + +.mode_336x224: db $80 ; VCE Control Register. + db VCE_CR_7MHz + 4 ; Video Clock + Artifact Reduction + + db VDC_MWR ; Memory-access Width Register + dw VDC_MWR_64x32 + VDC_MWR_2CYCLE + db VDC_HSR ; Horizontal Sync Register + dw VDC_HSR_336 + db VDC_HDR ; Horizontal Display Register + dw VDC_HDR_336 + db VDC_VPR ; Vertical Sync Register + dw VDC_VPR_224 + db VDC_VDW ; Vertical Display Register + dw VDC_VDW_224 + db VDC_VCR ; Vertical Display END position Register + dw VDC_VCR_224 + db VDC_DCR ; DMA Control Register + dw $0010 ; Enable automatic VRAM->SATB + db VDC_DVSSR ; VRAM->SATB address $0800 + dw $0800 + db VDC_BXR ; Background X-Scroll Register + dw $0008 + db VDC_BYR ; Background Y-Scroll Register + dw $0000 + db VDC_RCR ; Raster Counter Register + dw $0000 ; Never occurs! + db VDC_CR ; Control Register + dw $000C ; Enable VSYNC & RCR IRQ + db 0 + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; init_vdc_rez - Switch between screen resolutions. +; + + .code + +init_vdc_rez: lda > 5 dw %0011000010000001 ; CGY=3, CGX=0 (16x64). + + dw 64 + 80 - 4 ; '0' sprite. + dw 32 + $C0 + dw $1000 >> 5 + dw %0011000010000000 ; CGY=3, CGX=0 (16x64). + + dw 64 + 80 + 4 ; '1' sprite. + dw 32 + $C8 + dw $1040 >> 5 + dw %0011000010000001 ; CGY=3, CGX=0 (16x64). diff --git a/examples/asm/elmer/rom-core-hugerom/Makefile b/examples/asm/elmer/rom-core-hugerom/Makefile new file mode 100644 index 00000000..36205cd8 --- /dev/null +++ b/examples/asm/elmer/rom-core-hugerom/Makefile @@ -0,0 +1,14 @@ +all: hugerom.pce hugerom.s + +include ../Make_ex.inc + +AFLAGS ?= -newproc -strip -m -l 2 -S + +SRC_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm common.asm vdc.asm unpack-zx0.asm +SRC_OVL = hugerom.asm core-config.inc + +hugerom.pce hugerom.sym: $(SRC_OVL) $(SRC_INC) + $(AS) $(AFLAGS) -sf2 -raw hugerom.asm + +hugerom.s: hugerom.s2i hugerom.sym + $(S2I) hugerom.s2i diff --git a/examples/asm/elmer/rom-core-hugerom/hugerom.asm b/examples/asm/elmer/rom-core-hugerom/hugerom.asm new file mode 100644 index 00000000..5423f6c7 --- /dev/null +++ b/examples/asm/elmer/rom-core-hugerom/hugerom.asm @@ -0,0 +1,353 @@ +; *************************************************************************** +; *************************************************************************** +; +; hugerom.asm +; +; A simple (mostly empty) test of using the Street Fighter 2 mapper. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; This is an example of a simple HuCARD ROM that uses the "CORE(not TM)" +; library to provide interrupt-handling and joypad reading. +; +; It is running on a HuCARD, without Turbo Everdrive support, so the setup +; is the simplest possible! +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM with Stack & ZP +; MPR2 = bank $00 : HuCard ROM +; MPR3 = bank $01 : HuCard ROM +; MPR4 = bank $02 : HuCard ROM +; MPR5 = bank $03 : HuCard ROM +; MPR6 = bank $04 : HuCard ROM +; MPR7 = bank $00 : HuCard ROM with "CORE(not TM)" kernel and IRQ vectors. +; +; *************************************************************************** +; *************************************************************************** + + ; + ; Create a 2MB (homebrew) or 2.5MB (standard) sized HuCARD? + ; + +CREATE_2MB_ROM = 1 + + ; + ; Create some equates for a very generic VRAM layout, with a + ; 64*32 BAT, followed by the SAT, then followed by the tiles + ; for the ASCII character set. + ; + ; This uses the first 8KBytes of VRAM ($0000-$0FFF). + ; + +BAT_LINE = 64 +BAT_SIZE = 64 * 32 +SAT_ADDR = BAT_SIZE ; SAT takes 16 tiles of VRAM. +CHR_ZERO = BAT_SIZE / 16 ; 1st tile # after the BAT. +CHR_0x10 = CHR_ZERO + 16 ; 1st tile # after the SAT. +CHR_0x20 = CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + + ; + ; Choose a smaller ZX0 window than the default 2KB in order + ; to test the optimized decompressor for a 256-byte window. + ; + +ZX0_PREFER_SIZE = 0 ; Smaller size or 10% faster. +ZX0_WINBUF = ($3F00) ; Choose a 256 byte window in +ZX0_WINMSK = ($0100 - 1) ; RAM, located at $3F00. + + ; + ; Include the library, reading the project's configuration + ; settings from the local "core-config.inc", if it exists. + ; + + include "core.inc" ; Basic includes. + + .list + .mlist + + include "common.asm" ; Common helpers. + include "vdc.asm" ; Useful VDC routines. + include "unpack-zx0.asm" ; Decompressor for ZX0. + + + +; *************************************************************************** +; *************************************************************************** +; +; Put a decompression-buffer at the end of the RAM bank, using the new +; syntax that allows for spcifying a bank number. +; + +PALETTE_BUFFER = $F8:3C00 ; Room for 512 colors. + + + +; *************************************************************************** +; *************************************************************************** +; +; core_main - This is executed after "CORE(not TM)" library initialization. +; +; This is the first code assembled after the library includes, so we're still +; in the CORE_BANK, usually ".bank 0"; and because this is assembled with the +; default configuration from "include/core-config.inc", which sets the option +; "USING_MPR7", then we're running in MPR7 ($E000-$FFFF). +; + +core_main: ; Turn the display off and initialize the screen mode. + + call init_256x224 ; Initialize VDC & VRAM. + + ; Select the overlay containing saz_vdc + ; + ; Write to the SF2 mapper at offset $1FF0-$1FF3 in MRP7. + + stz $FFF0 + overlay( saz_vdc ) + + ; Decompress the graphics data. + ; + ; The ZX0 library defaults to using a 2KB decompression + ; window at $3800. That's perfect for this example. + + stz.l <_di ; VDC destination address. + stz.h <_di + + lda.l #saz_vdc ; Address of VDC graphics. + sta.l <_bp + lda.h #saz_vdc + sta.h <_bp + ldy #^saz_vdc + + call zx0_to_vdc ; Decompress the graphics. + + ; Another way to select an overlay using an equate. + ; + ; Write to the SF2 mapper at offset $1FF0-$1FF3 in MRP7. + + stz $FFF0 + overlay( SAZ_VCE_DATA ) + + ; Decompress the color palette data. + + lda.l #PALETTE_BUFFER ; Destination buffer for the + sta.l <_di ; 256 colors. + lda.h #PALETTE_BUFFER + sta.h <_di + + lda #SAZ_VCE_DATA + sta.h <_bp + ldy #^SAZ_VCE_DATA + + call zx0_to_ram ; Decompress the palettes. + + ; Upload the palette data to the VCE. + + stz <_al ; Start at palette 0 (BG). + lda #32 ; Copy 32 palette of 16 colors. + sta <_ah + lda #PALETTE_BUFFER + sta.h <_bp + cly + call load_palettes ; Add to the palette queue. + + call xfer_palettes ; Transfer queue to VCE now. + + ; Turn on the BG & SPR layers, then wait for a soft-reset. + + call set_dspon ; Enable the background. + +.animate: ldy #30 ; Wait for 30 frames. + call wait_nvsync + + ; Another way to select an overlay using the linear() operator, + ; showing 2 different ways to calculate the overlay number. + ; + ; Write to the SF2 mapper at offset $1FF0-$1FF3 in MRP7. + + stz $FFF0 + ((linear( saz_satb0 ) / (64 * $2000)) - 1) + stz $FFF0 + ((linear( saz_satb0 ) >> 19) - 1) + + lda.l #$0834 ; Upload hand position sprites + sta.l <_di ; to the SATB in VRAM. + lda.h #$0834 + sta.h <_di + call vdc_di_to_mawr + lda #bank( saz_satb0 ) ; Put saz_satb0 in MPR3. + tam3 + tia saz_satb0, VDC_DL, 32 ; Frame 1 of 2. + + ldy #30 ; Wait for 30 frames. + call wait_nvsync + + ; Select the overlay containing saz_satb1 using an equate. + ; + ; Write to the SF2 mapper at offset $1FF0-$1FF3 in MRP7. + + stz $FFF0 + overlay( SAZ_SATB1_DATA ) + + lda.l #$0834 ; Upload hand position sprites + sta.l <_di ; to the SATB in VRAM. + lda.h #$0834 + sta.h <_di + call vdc_di_to_mawr + lda #^SAZ_SATB1_DATA ; Put saz_satb1 in MPR3. + tam3 + tia SAZ_SATB1_DATA, VDC_DL, 32 + + bra .animate ; Wait for user to reboot. + + + +; *************************************************************************** +; *************************************************************************** +; +; The "CORE(not TM)" library initializes .DATA, so we don't do it again! +; +; *************************************************************************** +; *************************************************************************** + + .data + + + +; *************************************************************************** +; *************************************************************************** +; +; The SATB entries for the two different hand positions. +; + + ; Put this in the last bank of a 1MByte ROM. + ; + ; ".bank" must be set to the offset from the beginning of the + ; file that PCEAS outputs. + ; + ; "bank()" returns the actual value that you put into the MPR + ; register on the PC Engine. + ; + ; These are usually the same value for HuCARD ROMs <= 1MByte, + ; but they are different values for CD and SCD programs, also + ; for programs that use the StreetFighterII mapper. + ; + ; Use the "linear()" operator to get a symbol's offset in the + ; file, which can be used like ... + ; + ; .bank (linear( symbol ) / 8192) + + .bank $7F + + ; The earlier code maps this data into MPR3, so set the page. + .page 3 + + ; This is how to set the bank and overlay in an equate. + ; + ; Overlay .... none (banks $00-$7F) + ; Bank ........ $7F (the last bank of $40..$7F) + ; Address ... $6000 (this bank will be mapped into MPR3) + +SAZ_SATB0_DATA = $7F:6000 + +saz_satb0: dw $00A8,$0050,$01A8,$1080 + dw $0088,$0040,$0182,$0080 + dw $00A8,$0030,$0188,$1180 + dw $0098,$0030,$0184,$0180 + + ; The program counter also contains the bank and overlay. + +SAZ_SATB1_DATA = * + +saz_satb1: dw $00A8,$0050,$01B8,$1080 + dw $00A8,$0030,$0198,$1180 + dw $0088,$0030,$0190,$1180 + dw $0000,$0000,$0000,$0000 + + + +; *************************************************************************** +; *************************************************************************** +; +; The compressed graphics for the error screen. +; + + ; Put this at 1MB, larger than normal PCE ROMs. + .bank $80 + + ; Make sure the address >= $6000 so that set_bp_to_mpr + ; will map the data into MPR3. + .page 3 + + ; This is how to set the bank and overlay in an equate. + ; + ; Overlay ...... $1 (banks $80-$BF) + ; Bank ........ $40 (the first bank of $40..$7F) + ; Address ... $6000 (this bank will be mapped into MPR3) + +SAZ_VDC_DATA = $1:40:6000 + +saz_vdc: incbin "saz_vdc.zx0.256" + + + +; *************************************************************************** +; *************************************************************************** +; +; The compressed color palettes for the error screen. +; + + .if CREATE_2MB_ROM + + ; Put this in the last bank of a 2MByte ROM. + .bank $FF + + ; Make sure the address >= $6000 so that set_bp_to_mpr + ; will map the data into MPR3. + .page 3 + + ; The program counter also contains the bank and overlay. + +SAZ_VCE_DATA = * + + ; This is how to set the bank and overlay in an equate. + ; + ; Overlay ...... $2 (banks $C0-$FF) + ; Bank ........ $7F (the last bank of $40..$7F) + ; Address ... $6000 (this bank will be mapped into MPR3) + +ALSO_SAZ_VCE = $2:7F:6000 + +saz_vce: incbin "saz_vce.zx0" + + .else + + ; Put this in the last bank of a 2.5MByte ROM. + .bank $13F + + ; Make sure the address >= $6000 so that set_bp_to_mpr + ; will map the data into MPR3. + .page 3 + + ; The program counter also contains the bank and overlay. + +SAZ_VCE_DATA = * + + ; This is how to set the bank and overlay in an equate. + ; + ; Overlay ...... $3 (banks $100-$13F) + ; Bank ........ $7F (the last bank of $40..$7F) + ; Address ... $6000 (this bank will be mapped into MPR3) + +ALSO_SAZ_VCE = $3:7F:6000 + +saz_vce: incbin "saz_vce.zx0" + + .endif CREATE_2MB_ROM diff --git a/examples/asm/elmer/rom-core-hugerom/hugerom.s2i b/examples/asm/elmer/rom-core-hugerom/hugerom.s2i new file mode 100644 index 00000000..9f7f64ee --- /dev/null +++ b/examples/asm/elmer/rom-core-hugerom/hugerom.s2i @@ -0,0 +1,35 @@ +; *************************************************************************** +; *************************************************************************** +; +; hugerom.s2i +; +; A simple (mostly empty) test of using the Street Fighter 2 mapper. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; Here is the list of symbols for SYM2INC to export into a ".s" file. +; +; A ';' marks a comment, and everything else on the line is ignored. +; +; A symbol with a '?' in front of it is optional, and can be used for +; conditionally-compiled symbols. +; +; *************************************************************************** +; *************************************************************************** +; +; NOTE ... This is not used, it is only here to test that SYM2INC handles the +; recent changes to the format of the .sym file! +; +; *************************************************************************** +; *************************************************************************** + +core_kernel +leave_proc +saz_vce diff --git a/examples/asm/elmer/scd-core-2stage-error/Makefile b/examples/asm/elmer/scd-core-2stage-error/Makefile index b718d3f1..584b020b 100644 --- a/examples/asm/elmer/scd-core-2stage-error/Makefile +++ b/examples/asm/elmer/scd-core-2stage-error/Makefile @@ -7,10 +7,10 @@ AFLAGS ?= -newproc -strip -m -l 2 -S -overlay SRC1_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm SRC1_OVL = core-stage1.asm core-config.inc -SRC2_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm +SRC2_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm unpack-zx0.asm SRC2_OVL = stage2.asm core-config.inc -ERR_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm +ERR_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm unpack-zx0.asm ERR_OVL = error.asm core-config.inc saz_vdc.zx0 saz_vce.zx0 SRC_ISO = core-stage1.bin stage2.ovl @@ -22,7 +22,7 @@ core-stage1.bin core-stage1.sym: $(SRC1_OVL) $(SRC1_INC) $(AS) $(AFLAGS) -scd -trim core-stage1.asm core-stage1.s: core-stage1.s2i core-stage1.sym - $(S2I) ../include/core-stage1.s2i + $(S2I) core-stage1.s2i stage2.ovl: $(SRC2_OVL) $(SRC2_INC) core-stage1.s $(AS) $(AFLAGS) -scd stage2.asm diff --git a/examples/asm/elmer/scd-core-2stage-error/error.asm b/examples/asm/elmer/scd-core-2stage-error/error.asm index c39b899e..fcf0b1df 100644 --- a/examples/asm/elmer/scd-core-2stage-error/error.asm +++ b/examples/asm/elmer/scd-core-2stage-error/error.asm @@ -62,6 +62,15 @@ CHR_0x20 = CHR_ZERO + 32 ; ASCII ' ' CHR tile #. USING_STAGE1 = 1 + ; + ; Choose a smaller ZX0 window than the default 2KB in order + ; to test the optimized decompressor for a 256-byte window. + ; + +ZX0_PREFER_SIZE = 0 ; Smaller size or 10% faster. +ZX0_WINBUF = ($3F00) ; Choose a 256 byte window in +ZX0_WINMSK = ($0100 - 1) ; RAM, located at $3F00. + ; ; Include the library, reading the project's configuration ; settings from the local "core-config.inc", if it exists. @@ -196,7 +205,7 @@ core_main: ; Turn the display off and initialize the screen mode. ; The compressed graphics for the error screen. ; -saz_vdc: incbin "saz_vdc.zx0" +saz_vdc: incbin "saz_vdc.zx0.256" diff --git a/examples/asm/elmer/scd-core-2stage/Makefile b/examples/asm/elmer/scd-core-2stage/Makefile index 3d0b8339..3d792186 100644 --- a/examples/asm/elmer/scd-core-2stage/Makefile +++ b/examples/asm/elmer/scd-core-2stage/Makefile @@ -7,7 +7,7 @@ AFLAGS ?= -newproc -strip -m -l 2 -S -overlay SRC1_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm SRC1_OVL = core-stage1.asm core-config.inc -SRC2_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm +SRC2_INC = pceas.inc pcengine.inc core.inc core-startup.asm core-kernel.asm joypad.asm unpack-zx0.asm SRC2_OVL = stage2.asm core-config.inc SRC_ISO = core-stage1.bin stage2.ovl @@ -19,7 +19,7 @@ core-stage1.bin core-stage1.sym: $(SRC1_OVL) $(SRC1_INC) $(AS) $(AFLAGS) -scd -trim core-stage1.asm core-stage1.s: core-stage1.s2i core-stage1.sym - $(S2I) ../include/core-stage1.s2i + $(S2I) core-stage1.s2i stage2.ovl: $(SRC2_OVL) $(SRC2_INC) core-stage1.s $(AS) $(AFLAGS) -scd stage2.asm diff --git a/examples/asm/elmer/scd-core-fastcd/fastcd.asm b/examples/asm/elmer/scd-core-fastcd/fastcd.asm index 91482f7c..857de09d 100644 --- a/examples/asm/elmer/scd-core-fastcd/fastcd.asm +++ b/examples/asm/elmer/scd-core-fastcd/fastcd.asm @@ -243,19 +243,26 @@ core_main: ; Turn the display off and initialize the screen mode. test_init_disc .proc + ; N.B. The System Card does not check the IO-PORT! + ; + ; N.B. The Turbo Everdrive Pro does not emulate this! + lda IO_PORT bpl !+ - PRINTF "No CD-ROM Interface Unit!\n\n" +; PRINTF "No CD-ROM Interface Unit!\n\n" +; +; ldy #CDERR_NO_CDIFU +; jmp .finished - ldy #CDERR_NO_CDIFU - jmp .finished + PRINTF "CD-ROM IFU not detected\n\n" + bra .reset -!: PRINTF "CD-ROM Interface present\n" +!: PRINTF "CD-ROM IFU present\n" ; Reset the CD-ROM drive. - call cdr_reset +.reset: call cdr_reset ; Wait for the CD-ROM drive to release SCSI_BSY. diff --git a/examples/asm/elmer/ted2-bios-romcd/syscard3-ted2.inc b/examples/asm/elmer/ted2-bios-romcd/syscard3-ted2.inc index c989b274..35fb2f71 100644 --- a/examples/asm/elmer/ted2-bios-romcd/syscard3-ted2.inc +++ b/examples/asm/elmer/ted2-bios-romcd/syscard3-ted2.inc @@ -3,7 +3,7 @@ ; ; TURBO-GRAFX / PC-ENGINE SUPER SYSTEM CARD 3.00 PATCH FOR TURBO EVERDRIVE 2 ; -; Copyright John Brandwood 2015-2019. +; Copyright John Brandwood 2015-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -25,6 +25,8 @@ ; 2015-11-24 - Initial Release 3.01 ; 2019-01-07 - Release 3.02 ; Add patch for Dragon Slayer II crash. +; 2024-01-05 - Release 3.03 +; Add patch to fix System Card's CD_READ-to-MPR bug. ; ; *************************************************************************** ; *************************************************************************** @@ -82,12 +84,18 @@ JPN_SYSCARD = 1 .incbin "syscard3.jpn.pce" -SCRSIZ_PATCH = $e28e +SCRSIZ_OLDPATCH = $e28e ; Patch STA $0002 in TED2 v3.02 patch!!! +SCRSIZ_NEWPATCH = $e288 ; Patch STA $0000 in TED2 v3.03 patch!!! + MEMOPEN_ADR = $fe92 UNLOCK_TEST = $c86b MESSAGE_ADR = $c9d1 RUNBOOT_ADR = $e206 +CDREAD_PATCH = $ed8e +RESTORE_MPRx = $ed91 +RETRY_CDREAD = $ecf1 + SCRSIZ_FUNC = $e267 ; bank 0 ; repair this from TED2 v3.01 patch!!! HACKINIT_ADR = $c887 ; bank 1 ; repair this from TED2 v3.01 patch!!! DISPLAY_SUPER = $c950 @@ -98,12 +106,18 @@ DISPLAY_SUPER = $c950 .incbin "syscard3.usa.pce" -SCRSIZ_PATCH = $e2a7 +SCRSIZ_OLDPATCH = $e2a7 ; Patch STA $0002 in TED2 v3.02 patch!!! +SCRSIZ_NEWPATCH = $e2a1 ; Patch STA $0000 in TED2 v3.03 patch!!! + MEMOPEN_ADR = $feab UNLOCK_TEST = $c86b ; bank 1 MESSAGE_ADR = $c9c4 ; bank 1 RUNBOOT_ADR = $e21f +CDREAD_PATCH = $eda7 +RESTORE_MPRx = $edaa +RETRY_CDREAD = $ed0a + SCRSIZ_FUNC = $e280 ; bank 0 ; repair this from TED2 v3.01 patch!!! HACKINIT_ADR = $c887 ; bank 1 ; repair this from TED2 v3.01 patch!!! DISPLAY_SUPER = $c943 @@ -188,13 +202,14 @@ my_ex_memopen: lda #$68 ; Return that 192KB of external SCD RAM clc ; internal SCD RAM chip. rts -fix_ex_scrsiz: pha ; Repair "Gate of Thunder" damage. - lda #$80 +fix_ex_scrsiz: sta $0000 ; Exec ex_scrsiz instr that was patched. + lda #$80 ; Repair "Gate of Thunder" damage. sta $FFF5 - pla - sta $0002 ; Exec ex_scrsiz instr that was patched. rts +fix_ex_cdread: jsr RESTORE_MPRx ; Fix Hudson's bug by restoring the old + jmp RETRY_CDREAD ; MPRx value before the CD_READ retries. + scd_unlock_test:php ; Disable interrupts for the next bit. sei lda #$A5 ; Unlock TED2 registers. @@ -221,8 +236,11 @@ scd_unlock_test:php ; Disable interrupts for the next bit. .org $e069 jmp SCRSIZ_FUNC - .org SCRSIZ_PATCH - jmp fix_ex_scrsiz + .org SCRSIZ_OLDPATCH + sta $0002 + + .org SCRSIZ_NEWPATCH + jsr fix_ex_scrsiz ; ; If we're building for a TED2 or 1MB-RAM card then patch the @@ -248,9 +266,17 @@ scd_unlock_test:php ; Disable interrupts for the next bit. .bank 0 .org RUNBOOT_ADR - jsr fix_bootload ; Patch System Card's jump to boot loader. + ; + ; Fix Hudson's System Card bug where ex_cdread to an MPR fails + ; to restore the original bank before retrying after an error. + ; + + .bank 0 + .org CDREAD_PATCH + jmp fix_ex_cdread + ; ; Check if the IPL of the CD (loaded at $3000) matches ; any of the games that need to be fixed. @@ -358,4 +384,4 @@ fix_dslayer2: tii .patch,$2CD1,(.done - .patch) .bank 1 .org MESSAGE_ADR - .db "TED2 3.02" + .db "TED2 3.03" diff --git a/examples/asm/elmer/ted2-bios-usbcd/ted2usbcd.asm b/examples/asm/elmer/ted2-bios-usbcd/ted2usbcd.asm index 4f487820..689bed6a 100644 --- a/examples/asm/elmer/ted2-bios-usbcd/ted2usbcd.asm +++ b/examples/asm/elmer/ted2-bios-usbcd/ted2usbcd.asm @@ -35,7 +35,7 @@ ; *************************************************************************** ; *************************************************************************** ; -; Apply some extra patches to run an overlay from ROM instead of loading it +; Apply some extra patches to run an overlay from USB instead of loading it ; from the CD, but try to keep the environment as similar as possible. ; diff --git a/examples/asm/elmer/ted2-core-gulliver/gulliver.asm b/examples/asm/elmer/ted2-core-gulliver/gulliver.asm index d7b1a665..ea898058 100644 --- a/examples/asm/elmer/ted2-core-gulliver/gulliver.asm +++ b/examples/asm/elmer/ted2-core-gulliver/gulliver.asm @@ -95,11 +95,16 @@ BAT_NULL = CHR_0x20 + (0 << 12) ; Default BAT tile & palette. ; .if CDROM -SUPPORT_ACD = 1 ; Support the Arcade Card. +SUPPORT_ACD = 0 ; Support the Arcade Card (does not work yet!). .else SUPPORT_TED2 = 1 ; Support the Turbo Everdrive's use of bank0. .endif + ; Enable a 3rd pass, not because it is needed, but just to + ; test that it works. + + .3pass + ; ; Include the library, reading the project's configuration ; settings from the local "core-config.inc", if it exists. @@ -135,6 +140,9 @@ SUPPORT_TIMING = 1 ; Include the HuVIDEO timing information. ; .zp + +which_video: ds 1 + .bss .code @@ -241,13 +249,14 @@ core_main: ; Turn the display off and initialize the screen mode. .endif .sign_on: PRINTF "\eX3\eY22GulliverBoy HuVIDEO Player" - PRINTF "\eX35\eY22GulliverBoy HuVIDEO Player" PRINTF "\eX2\eY23Buffer used when refill: $xx" PRINTF "\eX2\eY24Buffer used refill done: $xx" PRINTF "\eX2\eY25Buffer refill time 1st: $xx" PRINTF "\eX2\eY26Buffer refill time rest: $xx" + PRINTF "\eX35\eY22GulliverBoy HuVIDEO Player" + PRINTF "\eX34\eY23Buffer used when refill: $xx" PRINTF "\eX34\eY24Buffer used refill done: $xx" PRINTF "\eX34\eY25Buffer refill time 1st: $xx" @@ -262,11 +271,30 @@ core_main: ; Turn the display off and initialize the screen mode. beq !+ ; Are we ready? jmp .main_loop +!: lda #$25 ; Default to NOT Gulliver CD! + + ldx tnomax ; Gulliver CD has 10 BCD tracks. + cpx #$10 + bne !+ + ldx outmin ; Gulliver CD has 73 BCD minutes. + cpx #$73 + bne !+ + ldx outsec ; Gulliver CD has 23 BCD seconds. + cpx #$23 + bne !+ + ldx outfrm ; Gulliver CD has 53 BCD frames. + cpx #$53 + bne !+ + +; lda #$24 ; Star Boy Movie. + lda #$22 ; Title Movie + ; Play the "GulliverBoy" title HuVIDEO. -!: -; lda #$24 ; Star Boy - lda #$22 ; Title Movie +!: sta of=sherlock-boot.bin + + You can confirm the validity of your file by checking its MD5 value. + + sherlock-boot.bin - MD5: 60aebcac752ba7b39d133c5d45a44d85 + + Because you must provide your own file, this project is not built by + default, and you must navigate to this directory and "make". + +***************************************************************************** diff --git a/examples/asm/elmer/ted2-test-sherlock/SHERLOCK.DAT b/examples/asm/elmer/ted2-test-sherlock/SHERLOCK.DAT new file mode 100644 index 00000000..0d619559 Binary files /dev/null and b/examples/asm/elmer/ted2-test-sherlock/SHERLOCK.DAT differ diff --git a/examples/asm/elmer/ted2-test-sherlock/dat2csv.c b/examples/asm/elmer/ted2-test-sherlock/dat2csv.c new file mode 100644 index 00000000..76af3ef1 --- /dev/null +++ b/examples/asm/elmer/ted2-test-sherlock/dat2csv.c @@ -0,0 +1,431 @@ +// ************************************************************************** +// ************************************************************************** +// +// dat2csv.c +// +// Convert the Sherlock logfile from binary to a CSV spreadsheet. +// +// Copyright John Brandwood 2024. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt)y +// +// ************************************************************************** +// ************************************************************************** +// +// This is a simple PC/Linux/MacOS command-line program that takes the 192KB +// SHERLOCK.DAT data file and converts the event log into a .CSV spreadsheet +// so that the data is easier for a human to understand. +// +// Just run the "dat2csv" program in the same directory as the SHERLOCK.DAT +// file and it will output the human-readable SHERLOCK.CSV spreadsheet file. +// +// ************************************************************************** +// ************************************************************************** + +// +// Standard C99 includes, with Visual Studio workarounds. +// + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined (_MSC_VER) + #include + #define SSIZE_MAX UINT_MAX + #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) + #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) + #define strcasecmp _stricmp + #define strncasecmp _strnicmp +#else + #include + #ifndef O_BINARY + #define O_BINARY 0 + #define O_TEXT 0 + #endif +#endif + +#if defined (_MSC_VER) && (_MSC_VER < 1600) // i.e. before VS2010 + #define __STDC_LIMIT_MACROS + #include "msinttypes/stdint.h" +#else + #include +#endif + +#if defined (_MSC_VER) && (_MSC_VER < 1800) // i.e. before VS2013 + #define static_assert( test, message ) + #include "msinttypes/inttypes.h" + #include "msinttypes/stdbool.h" +#else + #include + #include +#endif + + + +// ************************************************************************** +// ************************************************************************** +// +// ReadBinaryFile () +// +// Uses POSIX file functions rather than C file functions. +// +// Google "FIO19-C" for the reason why. +// +// N.B. Will return an error for files larger than 2GB on a 32-bit system. +// + +bool ReadBinaryFile (const char *pName, uint8_t **pBuffer, size_t *pLength) +{ + uint8_t * pData = NULL; + off_t uSize; + struct stat cStat; + + int hFile = open(pName, O_BINARY | O_RDONLY); + + if (hFile == -1) + goto errorExit; + + if ((fstat(hFile, &cStat) != 0) || (!S_ISREG(cStat.st_mode))) + goto errorExit; + + if (cStat.st_size > SSIZE_MAX) + goto errorExit; + + uSize = cStat.st_size; + + pData = (uint8_t *)malloc(uSize); + + if (pData == NULL) + goto errorExit; + + if (read(hFile, pData, uSize) != uSize) + goto errorExit; + + close(hFile); + + *pBuffer = pData; + *pLength = uSize; + + return (true); + + // Handle errors. + +errorExit: + + if (pData != NULL) free(pData); + if (hFile >= 0) close(hFile); + + *pBuffer = NULL; + *pLength = 0; + + return (false); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// main () +// + +// Data offsets for the information in each logged event. + +#define EVENT_TYPE 0 +#define EVENT_TIMER 1 +#define EVENT_BLANK 2 +#define EVENT_FRAME 3 +#define EVENT_TICK 4 +#define EVENT_LEFT 5 +#define EVENT_WRONG 6 +#define EVENT_DELAY 7 + +// Event types. + +#define INFO_VBLANK 1 + +#define INFO_WAITVBL 2 + +#define INFO_SCSIRMV 3 +#define INFO_SCSIIDLE 4 +#define INFO_SCSISEND 5 + +#define INFO_DATAEND 6 +#define INFO_FILLEND 7 + +#define INFO_SEEK_BEGIN 10 +#define INFO_SEEK_ENDED 11 + +#define INFO_NOTBUSY 12 + +#define INFO_SCSI80 0x80u // PHASE_DATA_OUT +#define INFO_SCSI88 0x88u // PHASE_DATA_IN +#define INFO_SCSI98 0x98u // PHASE_STAT_IN + +#define PHASE_COMMAND 0xD0u // (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + ........) +#define PHASE_DATA_OUT 0xC0u // (SCSI_BSY + SCSI_REQ + ........ + ........ + ........) +#define PHASE_DATA_IN 0xC8u // (SCSI_BSY + SCSI_REQ + ........ + ........ + SCSI_IXO) +#define PHASE_STAT_IN 0xD8u // (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + SCSI_IXO) +#define PHASE_MESG_OUT 0xF0u // (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + ........) +#define PHASE_MESG_IN 0xF8u // (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + SCSI_IXO) + +#define REQ_DATA_OUT (0xC0u+1) // (SCSI_BSY + SCSI_REQ + ........ + ........ + ........) +#define REQ_DATA_IN (0xC8u+1) // (SCSI_BSY + SCSI_REQ + ........ + ........ + SCSI_IXO) +#define REQ_STAT_IN (0xD8u+1) // (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + SCSI_IXO) + +#define RMV_COMMAND (0xD0u+2) // (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + ........) +#define RMV_DATA_OUT (0xC0u+2) // (SCSI_BSY + SCSI_REQ + ........ + ........ + ........) +#define RMV_DATA_IN (0xC8u+2) // (SCSI_BSY + SCSI_REQ + ........ + ........ + SCSI_IXO) +#define RMV_STAT_IN (0xD8u+2) // (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + SCSI_IXO) +#define RMV_MESG_OUT (0xF0u+2) // (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + ........) +#define RMV_MESG_IN (0xF8u+2) // (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + SCSI_IXO) + +#define INFO_EXIT 0x7Fu + +// + +int main ( int argc, char **argv ) + +{ + // + + uint8_t * pDatFile; + uint8_t * pDatStop; + size_t uDatSize; + + FILE * pCsvFile; + + uint8_t * pLog; + + unsigned uLastData; + unsigned uThisData; + + unsigned uTimerAdd; + unsigned uBlankAdd; + unsigned uFrameAdd; + + uint8_t uLastTimer; + uint8_t uLastBlank; + uint8_t uLastFrame; + + // Sign on. + + printf("dat2csv - Converting SHERLOCK.DAT to SHERLOCK.CSV\n\n"); + + // Read the Sherlock data file. + + pDatFile = NULL; + uDatSize = 0; + + if (!ReadBinaryFile( "SHERLOCK.DAT", &pDatFile, &uDatSize)) + { + printf("Cannot load SHERLOCK.DAT!\n"); + exit(1); + } + + pDatStop = pDatFile + uDatSize; + + // + + pCsvFile = NULL; + + if ((pCsvFile = fopen( "SHERLOCK.CSV", "w" )) == NULL) + { + printf( "Cannot open SHERLOCK.CSV!\n" ); + exit( 1 ); + } + + fprintf( pCsvFile, "Timer,Vblank,Frame,Tick,Sectors,Wrong,Delay,Reason\n" ); + + // + + uTimerAdd = 0; + uBlankAdd = 0; + uFrameAdd = 0; + + uLastTimer = 0; + uLastBlank = 0; + uLastFrame = 0; + + uLastData = 0; + uThisData = 0; + + pLog = pDatFile; + + for (pLog = pDatFile; pLog <= (pDatStop - 8); pLog += 8) + { + // Put a blank line between each frame of video. + + if (uLastFrame != pLog[EVENT_FRAME]) + { + fprintf( pCsvFile, "\n" ); + } + + // Did any of the byte values just wrap? + + if (uLastTimer > pLog[EVENT_TIMER]) uTimerAdd += 256; + if (uLastBlank > pLog[EVENT_BLANK]) uBlankAdd += 256; + if (uLastFrame > pLog[EVENT_FRAME]) uFrameAdd += 256; + + uLastTimer = pLog[EVENT_TIMER]; + uLastBlank = pLog[EVENT_BLANK]; + uLastFrame = pLog[EVENT_FRAME]; + + // Filter out irrelevent VBLANK events. + + if ((pLog[EVENT_TYPE] == INFO_VBLANK) && (pLog[EVENT_DELAY] == 0)) + { + continue; + } + + // Output the data values. + + fprintf( pCsvFile, "%d," , uTimerAdd + pLog[EVENT_TIMER] ); + fprintf( pCsvFile, "%d," , uBlankAdd + pLog[EVENT_BLANK] ); + fprintf( pCsvFile, "%d," , uFrameAdd + pLog[EVENT_FRAME] ); + fprintf( pCsvFile, "%d," , (unsigned) pLog[EVENT_TICK] ); + fprintf( pCsvFile, "%d," , (unsigned) pLog[EVENT_LEFT] ); + fprintf( pCsvFile, "%d," , (int) *((int8_t *) (pLog + EVENT_WRONG)) ); + fprintf( pCsvFile, "%d," , (unsigned) pLog[EVENT_DELAY] ); + + // Output the event type. + + switch (pLog[EVENT_TYPE]) + { + case INFO_VBLANK: + fprintf( pCsvFile, "VBLANK IRQ\n" ); + break; + + case INFO_WAITVBL: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Wait for VBLANK\n" ); + break; + + case INFO_SCSIRMV: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue\n" ); + break; + + case INFO_SCSIIDLE: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Idle: Awaiting command\n" ); + break; + + case INFO_SCSISEND: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Sending command\n" ); + break; + + case INFO_DATAEND: + fprintf( pCsvFile, "Finished reading Sector\n" ); + break; + + case INFO_FILLEND: + fprintf( pCsvFile, "ADPCM Prefill Completed\n\n" ); + break; + + case INFO_SEEK_BEGIN: + fprintf( pCsvFile, "Movie finished; System Card cd_seek\n" ); + break; + + case INFO_SEEK_ENDED: + fprintf( pCsvFile, "Movie finished; System Card cd_seek completed\n" ); + break; + + case INFO_NOTBUSY: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Idle: Queue flushed\n" ); + break; + + case INFO_SCSI80: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Got SCSI $80 (PHASE_DATA_OUT without REQ)\n" ); + break; + + case INFO_SCSI88: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Got SCSI $88 (PHASE_DATA_IN without REQ)\n" ); + break; + + case INFO_SCSI98: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Got SCSI $98 (PHASE_STAT_IN without REQ)\n" ); + break; + + case REQ_DATA_OUT: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: REQ asserted beginning PHASE_DATA_OUT\n" ); + break; + + case REQ_DATA_IN: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: REQ asserted beginning PHASE_DATA_IN\n" ); + break; + + case REQ_STAT_IN: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: REQ asserted beginning PHASE_STAT_IN\n" ); + break; + + case RMV_COMMAND: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue during PHASE_COMMAND\n" ); + break; + + case RMV_DATA_OUT: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue during PHASE_DATA_OUT\n" ); + break; + + case RMV_DATA_IN: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue during PHASE_DATA_IN\n" ); + break; + + case RMV_STAT_IN: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue during PHASE_STAT_IN\n" ); + break; + + case RMV_MESG_OUT: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue during PHASE_MESG_OUT\n" ); + break; + + case RMV_MESG_IN: + fprintf( pCsvFile, "Send SCSI command; CD-ROM Busy: Flush byte from queue during PHASE_MESG_IN\n" ); + break; + + case PHASE_DATA_IN: + uThisData = uTimerAdd + pLog[EVENT_TIMER]; + if ((uThisData - uLastData) > 18) + { + fprintf( pCsvFile, "Wait for next Sector; Got SCSI PHASE_DATA_IN; %dms since last sector!\n", uThisData - uLastData ); + } + else + { + fprintf( pCsvFile, "Wait for next Sector; Got SCSI PHASE_DATA_IN\n" ); + } + uLastData = uThisData; + break; + + case PHASE_STAT_IN: + fprintf( pCsvFile, "Wait for next Sector; Got SCSI PHASE_STAT_IN\n" ); + break; + + case INFO_EXIT: + fprintf( pCsvFile, "Movie finished!\n" ); + break; + + default: + printf( "Unknown event type 0x%2X in data!\n", pLog[EVENT_TYPE] ); + fprintf( pCsvFile, "Unknown event type 0x%2X in data!\n", pLog[EVENT_TYPE] ); + fclose( pCsvFile ); + exit( 1 ); + } + + if (pLog[EVENT_TYPE] == INFO_EXIT) break; + } + + fclose( pCsvFile ); + + // + + printf( "Finished writing SHERLOCK.CSV\n" ); + + return( 0 ); +} diff --git a/examples/asm/elmer/ted2-test-sherlock/sherlock-hack.asm b/examples/asm/elmer/ted2-test-sherlock/sherlock-hack.asm new file mode 100644 index 00000000..43fd3661 --- /dev/null +++ b/examples/asm/elmer/ted2-test-sherlock/sherlock-hack.asm @@ -0,0 +1,595 @@ +; *************************************************************************** +; *************************************************************************** +; +; sherlock-hack.asm +; +; This patches the "Sherlock Holmes Consulting Detective" executable code to +; add a 1ms timer and a lot of event-logging to unused SuperCD memory banks. +; +; A copy of Sherlock's executable code must exist in this directory with the +; filename "sherlock-boot.bin". (Size = 22,528 bytes with CRC32 = $35AE4D73) +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; If you are using an emulator, then you can run the game normally but put a +; breakpoint at address $2A00. +; +; When the breakpoint is hit, just load "sherlock-hack.ovl" at $2A00 and run +; the code. +; +; Sherlock's introductory movie should immediately play, with a log of event +; information being written to banks $6A..$81. +; +; When the movie has completed, the game will hang on the next screen, which +; allows you to enter your emulator's debugger and save the contents of bank +; $6A..$81 ($0D4000..$103FFF physical) as the SHERLOCK.DAT file. +; +; Then run the "dat2csv" program in the same directory as the SHERLOCK.DAT +; file and it will output the human-readable SHERLOCK.CSV spreadsheet file. +; +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; +; Use the original Sherlock Holmes boot program as a base for testing. +; + + include "pcengine.inc" + + .bank 0 ; Bank $F8 at $2000-$3FFF. + .page 1 + + .bank 1 ; Bank $82 at $4000-$5FFF. + .page 2 + + .bank 2 ; Bank $83 at $6000-$7FFF. + .page 3 + + .bank 3 ; Bank $84 at $8000-$9FFF. + .page 4 + + .org $8000 ; Sherlock loads $2A00-$81FF. + ds $0A00 ; Clear space to $89FF. + + .bank 0 + .org $2A00 + incbin "sherlock-boot.bin" ; Load 11 sector boot code. + + ; + ; Sherlock's internal playback variables. + ; + +which_screen = $F8:2008 ; $00=VRAM $0800, $FF=VRAM $1CA0 +sector_counter = $F8:2009 ; #vram sectors left to read +sectors_remain = $F8:200A ; #sectors left to read in SCSI read command, send new SCSI when 0. + ; +video_wrong = $F8:200D ; cumulative #ticks playback is out +frame_wrong = $F8:200E ; #ticks taken this frame - 6 (nominal playback #ticks taken) +delay_ticks = $F8:200F ; #ticks to delay (if video is running too fast) + +tick_count = $F8:2026 ; reset at the start of every video frame + +frame_num_lo = $F8:2047 ; current movie frame number +frame_num_hi = $F8:2048 ; + +movie_lba_l = $F8:26CA +movie_lba_m = $F8:26CB +movie_lba_h = $F8:26CC + + ; + ; Use previously-unused locations in Sherlock for instrumentation. + ; + +timer_val = $F8:20C0 +info_addr = $F8:20C1 + + ; + ; + ; + +INFO_VBLANK = 1 + +INFO_WAITVBL = 2 + +INFO_SCSIRMV = 3 +INFO_SCSIIDLE = 4 +INFO_SCSISEND = 5 + +INFO_DATAEND = 6 +INFO_FILLEND = 7 + +INFO_SEEK_BEGIN = 10 +INFO_SEEK_ENDED = 11 + +INFO_NOTBUSY = 12 + +INFO_SCSI80 = $80 ; PHASE_DATA_OUT (CD-ROM uses this after a command is received) +INFO_SCSI88 = $88 ; PHASE_DATA_IN +INFO_SCSI98 = $98 ; PHASE_STAT_IN + +;PHASE_COMMAND = $D0 ; (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + ........) +;PHASE_DATA_OUT = $C0 ; (SCSI_BSY + SCSI_REQ + ........ + ........ + ........) +;PHASE_DATA_IN = $C8 ; (SCSI_BSY + SCSI_REQ + ........ + ........ + SCSI_IXO) +;PHASE_STAT_IN = $D8 ; (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + SCSI_IXO) +;PHASE_MESG_OUT = $F0 ; (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + ........) +;PHASE_MESG_IN = $F8 ; (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + SCSI_IXO) + +;REQ_DATA_OUT = ($C0+1) ; (SCSI_BSY + SCSI_REQ + ........ + ........ + ........) +;REQ_DATA_IN = ($C8+1) ; (SCSI_BSY + SCSI_REQ + ........ + ........ + SCSI_IXO) +;REQ_STAT_IN = ($D8+1) ; (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + SCSI_IXO) + +;RMV_COMMAND = ($D0+2) ; (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + ........) +;RMV_DATA_OUT = ($C0+2) ; (SCSI_BSY + SCSI_REQ + ........ + ........ + ........) +;RMV_DATA_IN = ($C8+2) ; (SCSI_BSY + SCSI_REQ + ........ + ........ + SCSI_IXO) +;RMV_STAT_IN = ($D8+2) ; (SCSI_BSY + SCSI_REQ + ........ + SCSI_CXD + SCSI_IXO) +;RMV_MESG_OUT = ($F0+2) ; (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + ........) +;RMV_MESG_IN = ($F8+2) ; (SCSI_BSY + SCSI_REQ + SCSI_MSG + SCSI_CXD + SCSI_IXO) + +INFO_EXIT = $7F + + ; + ; Hack Sherlock's code to add the instrumentation. + ; + + .list + .mlist + + .bank 0 + + .org $2A29 ; Disable System Card joypad. + ora #$30 + + .org $2A54 ; Replace joypad read with tracking. + jsr track_vbl + + .org $2B8B ; Start intro video and recording + jmp hijack_start ; when the game code executes. + + .bank 2 + + .org $7A10 ; Stop recording when the video ends. + jmp hijack_end + + ; + ; play_movie() routine, after movie has completed + ; + + .bank 0 + .org $328D + jsr begin_seek + + .org $3290 + jsr ended_seek + + ; + ; finish_movie() + ; + + .bank 0 + .org $31CE + jsr start_recording + + ; + ; scsi_send_cmd() and scsi_next_cmd() + ; + + .bank 0 + .org $3ECE + jsr delay_next_read + + .org $3EF6 + jsr scsi_flush_byte + + .org $3F07 + jsr scsi_is_idle + + .org $3F1D + jsr scsi_cmd_out + + .org $3F4D + jsr scsi_cmd_end + + .org $3F6F + jsr scsi_got_req + + ; + ; play_movie_loop() + ; + + .bank 0 + .org $3FCE + jsr end_then_wait + + .org $3FF7 + jsr end_then_wait + + .bank 1 + .org $40C9 + jsr end_of_frame + + .org $41BF + jsr end_then_wait + + .org $42A2 + jmp scsi_got_phase + + ; + ; prefill_adpcm() + ; + + .bank 1 + .org $43F9 + jsr end_then_wait + + .org $43FE + jmp prefill_end + + ; + ; There is LOTS of unused space at the end of the Sherlock code. + ; + + .bank 2 + .org $7C80 + + ; + ; 1ms timer interrupt. + ; + +timer_irq: stz IRQ_ACK ; Clear timer interrupt. + inc 7144 cycles -> 1.00124457ms + sta TIMER_DR + + jmp $2DA0 ; Play intro video at boot. + + ; + ; + ; + +start_recording:stz irq_cnt ; Reset IRQ count. + lda.h #$C000 ; Start recording now. + sta.h (CHR_0x10 * 16) + sta <_di + 1 + + lda #$FF ; Put font in colors 4-7, + sta <_al ; so bitplane 2 = $FF and + stz <_ah ; bitplane 3 = $00. + + lda #16 + 96 ; 16 box graphics + 96 ASCII. + sta <_bl + + lda #my_font + sta <_bp + 1 + ldy #^my_font + + call dropfnt8x8_vdc ; Upload font to VRAM. + + ; Upload the palette data to the VCE. + + stz <_al ; Start at palette 0 (BG). + lda #1 ; Copy 1 palette of 16 colors. + sta <_ah + lda #cpc464_colors + sta <_bp + 1 + ldy #^cpc464_colors + call load_palettes ; Add to the palette queue. + + call xfer_palettes ; Transfer queue to VCE now. + + ; Turn on the BG & SPR layers, then wait for a soft-reset. + + call set_dspon ; Enable background. + + call wait_vsync ; Wait for vsync. + + ; Reset the CD-ROM, because Sherlock leaves it in a mess! + + system cd_reset + + ; Save Sherlock's log data to the SDcard. + + jsr save_data ; + + ; Wait for user to reboot. + + lda ted2_unlocked ; If running on a TED2, then + bne .hang_usb ; allow for a USB upload. + +.hang: call wait_vsync ; Wait for vsync, or xfer. + + bra .hang ; Wait for user to reboot. + +.hang_usb: call wait_vsync_usb ; Wait for vsync, or xfer. + + bra .hang_usb ; Wait for user to reboot. + + + +; *************************************************************************** +; *************************************************************************** +; +; save_data - Save the data in memory to /TBED/SHERLOCK.DAT on the SDcard +; + +LOG_BANK = $6A +LOG_SIZE = ($82 - $6A) * $2000 + +save_data: PRINTF "\x1B<\eP0\eXL1\nInitializing Turbo Everdrive v2.\n" + + ; Unlock the TED2 hardware, which takes over bank $00. + + call unlock_ted2 ; Unlock the TED2 hardware. + beq .ted2_ok + +.ted2_fail: PRINTF "Turbo Everdrive v2 not found!\n" + jmp .finished + +.ted2_ok: PRINTF "Turbo Everdrive v2 found and unlocked!\n" + + ; Checksum the log data. + + PRINTF "Calculating CRC32 of data.\n" + + call init_crc32 ; Initialize the CRC32 tables. + + lda.l #LOG_SIZE + sta.l <_ax ; L-byte of #bytes to checksum. + lda.h #LOG_SIZE + sta.h <_ax ; M-byte of #bytes to checksum. + lda #LOG_SIZE >> 16 + sta <_ax + 2 ; H-byte of #bytes to checksum. + stz.l <_bp ; Checksum the log data. + lda #$60 + sta.h <_bp + ldy #LOG_BANK + call calc_crc32 ; Calculate the CRC32. + + tii _cx, crc_value, 4 + + PRINTF "The CRC32 of the data is $%0lx.\n\n", crc_value + + ; Initialize and mount the SDcard. + + PRINTF "Initializing SD card.\n" + + call f32_mount_vol ; Mount the SDcard FAT-32. + beq .fat32_ok + +.fat32_fail: PRINTF "FAT32 parition not found!\n" + jmp .finished + +.fat32_ok: PRINTF "FAT32 parition mounted.\n\n" + + ; Select "/TBED/" directory. + + PRINTF "Selecting SDcard /TBED/ directory.\n" + + call f32_select_root ; Start back at the root. + bne .cd_fail + + lda #<.dirname ; Locate the 'TBED' folder. + sta.l <_bp + lda #>.dirname + sta.h <_bp + ldy #^.dirname + call f32_find_name + bne .cd_fail + + call f32_change_dir ; Select the directory. + beq .cd_ok + +.cd_fail: PRINTF "Directory change failed!\n" + jmp .finished + +.dirname: db "TBED",0 + +.cd_ok: PRINTF "Directory selected.\n" + + ; Open the "SHERLOCK.DAT" file. + + PRINTF "Writing file /TBED/SHERLOCK.DAT from memory.\n" + + lda #<.filename ; Locate the file. + sta.l <_bp + lda #>.filename + sta.h <_bp + ldy #^.filename + call f32_find_name ; Locate the named file in + bne .write_fail ; the current directory. + + call f32_open_file ; Open the file, after which + bne .write_fail ; f32_cache_buf free for use! + + ; Overwrite the "SHERLOCK.DAT" file from memory. + + lda.l #LOG_SIZE / 512 ; Or look at f32_file_length! + sta.l <_ax ; Lo-byte of # blocks in file. + lda.h #LOG_SIZE / 512 + sta.h <_ax ; Hi-byte of # blocks in file. + + lda #LOG_BANK ; First unused bank, reported + tam3 ; by PCEAS! + stz.l <_bx ; Save from MPR3, which will + lda.h #$6000 ; autoincrement the bank# as + sta.h <_bx ; necessary. + + call f32_file_write ; Write the file from memory. + bne .write_fail + + call f32_close_file ; Close the file & set N & Z. + beq .write_ok + +.write_fail: pha ; Preserve error code. + call f32_close_file ; Close the file & set N & Z. + + PRINTF "File write failed!\n" + pla ; Restore error code. + jmp .finished + +.write_ok: PRINTF "File write complete.\n" + + ; Open the "SHERLOCK.DAT" file. + + PRINTF "Reading file /TBED/SHERLOCK.DAT into memory.\n" + + lda #<.filename ; Locate the file. + sta.l <_bp + lda #>.filename + sta.h <_bp + ldy #^.filename + call f32_find_name ; Locate the named file in + bne .read_fail ; the current directory. + + call f32_open_file ; Open the file, after which + bne .read_fail ; f32_cache_buf free for use! + + ; Read the "SHERLOCK.DAT" file into memory. + + lda.l #LOG_SIZE / 512 ; Or look at f32_file_length! + sta.l <_ax ; Lo-byte of # blocks in file. + lda.h #LOG_SIZE / 512 + sta.h <_ax ; Hi-byte of # blocks in file. + + lda #$40 ; Read file into TED2 memory. + tam3 + stz.l <_bx ; Load into MPR3, which will + lda #$60 ; autoincrement the bank# as + sta.h <_bx ; necessary. + + call f32_file_read ; Read the file into memory. + bne .read_fail + + call f32_close_file ; Close the file & set N & Z. + beq .read_ok + +.read_fail: pha ; Preserve error code. + call f32_close_file ; Close the file & set N & Z. + + PRINTF "File read failed!\n" + pla ; Restore error code. + jmp .finished + +.filename: db "SHERLOCK.DAT",0 + +.read_ok: PRINTF "File read complete.\n" + + ; Checksum the log file. + + PRINTF "Calculating CRC32 of file.\n" + + call init_crc32 ; Initialize the CRC32 tables. + + lda.l #LOG_SIZE + sta.l <_ax ; L-byte of #bytes to checksum. + lda.h #LOG_SIZE + sta.h <_ax ; M-byte of #bytes to checksum. + lda #LOG_SIZE >> 16 + sta <_ax + 2 ; H-byte of #bytes to checksum. + stz.l <_bp ; Checksum 32KB from $6000. + lda #$60 + sta.h <_bp + ldy #$40 ; Test file from TED2 memory. + call calc_crc32 ; Calculate the CRC32. + + tii _cx, crc_value, 4 + + PRINTF "The CRC32 of the file is $%0lx.\n\n", crc_value + + ; All Done! + +.finished: rts + + + +; *************************************************************************** +; *************************************************************************** +; +; The "CORE(not TM)" library initializes .DATA, so we don't do it again! +; +; *************************************************************************** +; *************************************************************************** + + .data + + + +; *************************************************************************** +; *************************************************************************** +; +; cpc464_colors - Palette data (a blast-from-the-past!) +; +; Note: DEFPAL palette data is in RGB format, 4-bits per value. +; Note: Packed palette data is in GRB format, 3-bits per value. +; +; $0 = transparent +; $1 = dark blue shadow +; $2 = white font +; +; $4 = dark blue background +; $5 = light blue shadow +; $6 = yellow font +; + +none = $000 + + align 2 + +cpc464_colors: defpal $000,$001,$662,none,$002,$114,$551,none + defpal none,none,none,none,none,none,none,none + + + +; *************************************************************************** +; *************************************************************************** +; +; It's the font data, nothing exciting to see here! +; + +my_font: incbin "font8x8-ascii-bold-short.dat" + + + +; *************************************************************************** +; *************************************************************************** +; +; Finally, include the hacked Sherlock CD boot-program image in the correct +; bank/address so that it can be executed just by paging it in to memory. +; + + .bank $81 - $68 ; Sherlock runs in bank $81. + + .org $2A00 + incbin "sherlock-hack.ovl" + + ds $2000 - (* & $1FFF) ; Clear to end of bank. diff --git a/examples/huc/sgx/Makefile b/examples/huc/sgx/Makefile index 02209496..58fc2e1a 100644 --- a/examples/huc/sgx/Makefile +++ b/examples/huc/sgx/Makefile @@ -7,7 +7,7 @@ SRC = sgx_test.c CFLAGS ?= -sgx -fno-recursive -msmall CDFLAGS = -scd -sgx_test.iso: $(SRC) +sgx_test.iso: $(SRC) sgx_test.sgx $(CC) $(CFLAGS) $(CDFLAGS) $(SRC) $(LIBS) sgx_test.sgx: $(SRC) diff --git a/examples/huc/shmup/Makefile b/examples/huc/shmup/Makefile index 8da6a478..80bb4268 100644 --- a/examples/huc/shmup/Makefile +++ b/examples/huc/shmup/Makefile @@ -8,5 +8,5 @@ LIBS = shmup.pce: shmup.c $(CC) -fsigned-char $(CFLAGS) $(LIBS) $< -shmup.iso: shmup.c +shmup.iso: shmup.c shmup.pce $(CC) -scd -fsigned-char $(CFLAGS) $(LIBS) $< diff --git a/examples/hucc/Make_ex.inc b/examples/hucc/Make_ex.inc new file mode 100644 index 00000000..e3be3817 --- /dev/null +++ b/examples/hucc/Make_ex.inc @@ -0,0 +1,79 @@ +# Set up the PCEDEV library location. +# +# This can be overriden in a user's project. + +# ifeq ($(PCE_INCLUDE),) +INCDIR := ../../../include/hucc +# else +# ifeq ($(OS),Windows_NT) +# INCDIR := $(subst \,/,$(PCE_INCLUDE)) +# else +# INCDIR := $(PCE_INCLUDE) +# endif +# endif + +# Set up the PCEDEV tools location. +# +# This can be overriden in a user's project. + +# ifeq ($(PCE_BINPATH),) +BINDIR := ../../../bin +# else +# ifeq ($(OS),Windows_NT) +# BINDIR := $(subst \,/,$(PCE_BINPATH)) +# else +# BINDIR := $(PCE_BINPATH) +# endif +# endif + +CC = $(BINDIR)/hucc +AS = $(BINDIR)/pceas +IL = $(BINDIR)/isolink +S2I = $(BINDIR)/sym2inc +W2V = $(BINDIR)/wav2vox +CP = cp +MV = mv +RM = rm -f + +# Override "cp" and "rm" if using default Windows CMD. + +ifeq ($(OS),Windows_NT) +ifeq ($(MSYSTEM),) +# Use CMD.EXE and Windows pathing. +CP = copy +MV = ren +RM = del +else +# Use UNIX tools if Windows MSYS2. +endif +endif + +# GNU Make wants UNIX path separators in the makefile. + +VPATH = $(INCDIR) + +# PCE_INCLUDE needs platform-specific path separators. + +ifeq ($(OS),Windows_NT) +export PCE_INCLUDE = $(subst :,;,$(subst /,\,$(VPATH))) +export PCE_PCEAS = $(subst /,\,$(AS)) +else +export PCE_INCLUDE = $(VPATH) +export PCE_PCEAS = $(AS) +endif + +# Default "clean" that works on both Unix shell and Windows_NT CMD. +# +# User projects can just add to the list of TARGETS to clean! +# +# Windows CMD.EXE will fail if the specified file does not exist, +# and so any user-added files *MUST* be in the form of wildcards! + +TARGETS = *.pce *.sgx *.iso *.ovl *.out *.lst *.sym *.s + +clean:: +ifeq ($(RM),del) + for %i in ( $(subst /,\,$(TARGETS)) ) do del "%i" +else + $(RM) $(TARGETS) +endif diff --git a/examples/hucc/Makefile b/examples/hucc/Makefile new file mode 100644 index 00000000..4d6c63c8 --- /dev/null +++ b/examples/hucc/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for examples +# + +SUBDIRS = sgx shmup + +all clean: + @$(MAKE) $(SUBDIRS) "COMMAND=$@" + +.PHONY: $(SUBDIRS) + +$(SUBDIRS): + @echo " " + @echo " -----> make $(COMMAND) in $@" + $(MAKE) --directory=$@ $(COMMAND) diff --git a/examples/hucc/sgx/Makefile b/examples/hucc/sgx/Makefile new file mode 100644 index 00000000..cc32fb98 --- /dev/null +++ b/examples/hucc/sgx/Makefile @@ -0,0 +1,18 @@ +all: sgx_test.iso sgx_test.sgx + +include ../Make_ex.inc + +SRC = sgx_test.c + +CFLAGS ?= -sgx -fno-recursive +CDFLAGS = -scd -over + +sgx_test.sgx: $(SRC) + $(CC) $(CFLAGS) $(SRC) $(LIBS) + $(MV) sgx_test.pce $@ + +sgx_test.ovl: $(SRC) sgx_test.sgx + $(CC) $(CFLAGS) $(CDFLAGS) $(SRC) $(LIBS) + +sgx_test.iso: sgx_test.ovl + $(IL) $@ -ipl="SuperGRAFX Test" $^ diff --git a/examples/hucc/sgx/pce_bat1.bin b/examples/hucc/sgx/pce_bat1.bin new file mode 100644 index 00000000..0e690ae4 Binary files /dev/null and b/examples/hucc/sgx/pce_bat1.bin differ diff --git a/examples/hucc/sgx/pce_pal1.bin b/examples/hucc/sgx/pce_pal1.bin new file mode 100644 index 00000000..cd7857a1 Binary files /dev/null and b/examples/hucc/sgx/pce_pal1.bin differ diff --git a/examples/hucc/sgx/pce_tile1.bin b/examples/hucc/sgx/pce_tile1.bin new file mode 100644 index 00000000..b125f9be Binary files /dev/null and b/examples/hucc/sgx/pce_tile1.bin differ diff --git a/examples/hucc/sgx/sgx_test.c b/examples/hucc/sgx/sgx_test.c new file mode 100644 index 00000000..446c1328 --- /dev/null +++ b/examples/hucc/sgx/sgx_test.c @@ -0,0 +1,95 @@ +#include +#include + +/* HuCC enables and disables *both* the PC Engine and SuperGRAFX VDCs + when disp_on() and disp_off() are called. + Disabling them seperately is not normally done in games, but it is + easy to accomplish with a bit of inline asm! + Note that HuC's scroll(), HuCC's scroll_split() and sgx_scroll_split() + *all* override the current disp_on() or disp_off()! */ +void __fastcall __xsafe __macro pce_disp_on( void ); +void __fastcall __xsafe __macro pce_disp_off( void ); +void __fastcall __xsafe __macro sgx_disp_on( void ); +void __fastcall __xsafe __macro sgx_disp_off( void ); +#asm + .macro _pce_disp_on + lda #$C0 + tsb + +#incspr(bonk,"charwalk.pcx",0,0,2,8) +#incpal(bonkpal,"charwalk.pcx") +#incspr(bullet,"bullet.pcx",0,0,1,1) +#incpal(bulletpal,"bullet.pcx") +#incspr(ship,"ship.pcx",0,0,2,8) +#incpal(shippal,"ship.pcx") +#incspr(explosion,"explosion.pcx",0,0,2,16) +#incpal(explosionpal,"explosion.pcx") + +#incchr(scene_chr,"scene.png") +#incpal(scene_pal,"scene.png") +#incbat(scene_bat,"scene.png",0x1000,32,28) + +#define SPEED_X 2 +#define SPEED_Y 2 + +#define SPEED_BULLET 4 +#define MAX_BULLETS 10 +#define BULLET_SPRITE 1 + +struct bullet { + int x, y; + char active; +}; + +struct bullet bullets[MAX_BULLETS]; + +#define MAX_SHIPS 5 +#define SPEED_SHIP 1 +#define SHIP_SPRITE (BULLET_SPRITE + MAX_BULLETS) +#define SCORE_SHIP 100 + +struct ship { + int x, y; + char active; + char vx, vy; +}; + +struct ship ships[MAX_SHIPS]; + +unsigned int frames; +unsigned int score, hiscore; + +void do_ships(void) +{ + unsigned int i,j; + unsigned char r; + struct ship *sp; + struct bullet *bp; + + r = rand(); + if ((r & 0x7e) == 2) { + for (i = 0, sp = ships; i < MAX_SHIPS; ++i, ++sp) { + if (!sp->active) { + sp->active = 1; + sgx_spr_set(SHIP_SPRITE + i); + if (r & 1) { + sgx_spr_ctrl(FLIP_MAS|SIZE_MAS,FLIP_X|SZ_32x32); + sp->vx = SPEED_SHIP; + sp->vy = 0; + sp->x = -32; + } + else { + sgx_spr_ctrl(FLIP_MAS|SIZE_MAS,NO_FLIP_X|SZ_32x32); + sp->vx = -SPEED_SHIP; + sp->vy = 0; + sp->x = 256; + } + sp->y = rand() % 210; + break; + } + } + } + + for (i = 0, sp = ships; i < MAX_SHIPS; ++i, ++sp) { + if (sp->active) { + sgx_spr_set(SHIP_SPRITE + i); + sgx_spr_x(sp->x); + sgx_spr_y(sp->y); + if (sp->active > 1) { + sgx_spr_pattern(0x5900 + (sp->active >> 3) * 0x100); + sgx_spr_pal(3); + sp->active++; + if (sp->active == 64) { + sp->active = 0; + sgx_spr_x(-32); + sgx_spr_y(16); + sgx_spr_pal(2); + } + } + else { + sgx_spr_pattern(0x5500 + (((frames >> 4) & 3) * 0x100)); + for (j = 0, bp = bullets; j < MAX_BULLETS; ++j, ++bp) { + if (bp->active) { + if (bp->x > sp->x - 4 && + bp->x < sp->x + 20 && + bp->y > sp->y - 3 && + bp->y < sp->y + 16) { + /* explosion */ + sp->active = 2; + sp->vx = 0; + sp->vy = 0; + bp->active = 0; + sgx_spr_set(BULLET_SPRITE + j); + sgx_spr_x(-16); + sgx_spr_y(0); + score += SCORE_SHIP; + } + } + } + } + sp->x += sp->vx; + sp->y += sp->vy; + if (sp->x > 256 || sp->x < -32) { + sp->active = 0; + sgx_spr_x(-32); + sgx_spr_y(16); + } + } + } +#ifdef DEBUG + for (i = 0, sp = ships; i < MAX_SHIPS; ++i, ++sp) { + if (sp->active) { + put_number(sp->x, 4, 1, 4+i); + put_number(sp->y, 4, 5, 4+i); + } + } +#endif +} + +void main(void) +{ + unsigned int j1; + int bonkx, bonky; + unsigned int tic; + unsigned char i, j; + unsigned char bullet_wait; + char bonk_dir; + char r; + unsigned char dead; + struct ship *sp; + struct bullet *bp; + + hiscore = 0; + + /* no goto yet, so we have to use this instead */ + for (;;) { + + tic = 0; + frames = 0; + score = 0; + dead = 0; + bonkx = 104; + bonky = 153; + bullet_wait = 0; + bonk_dir = 1; + + sgx_init_satb(); + sgx_spr_set(0); + sgx_spr_x(bonkx); + sgx_spr_y(bonky); + sgx_spr_pattern(0x5000); + sgx_spr_ctrl(FLIP_MAS|SIZE_MAS,FLIP_X|SZ_32x32); + sgx_spr_pal(0); + sgx_spr_pri(1); + + for (i = 0; i < MAX_BULLETS; i++) { + sgx_spr_set(BULLET_SPRITE + i); + sgx_spr_x(-16); + sgx_spr_y(0); + sgx_spr_pattern(0x5400); + sgx_spr_ctrl(FLIP_MAS|SIZE_MAS,NO_FLIP|SZ_16x16); + sgx_spr_pal(1); + sgx_spr_pri(1); + bullets[i].active = 0; + } + + for (i = 0; i < MAX_SHIPS; i++) { + sgx_spr_set(SHIP_SPRITE + i); + sgx_spr_x(-32); + sgx_spr_y(16); + sgx_spr_pattern(0x5500); + sgx_spr_ctrl(FLIP_MAS|SIZE_MAS,NO_FLIP|SZ_32x32); + sgx_spr_pal(2); + sgx_spr_pri(1); + ships[i].active = 0; + } + load_palette(16,bonkpal,1); + load_palette(17,bulletpal,1); + load_palette(18,shippal,1); + load_palette(19,explosionpal,1); + + sgx_load_vram(0x5000,bonk,0x400); + sgx_load_vram(0x5400,bullet,0x40); + sgx_load_vram(0x5500,ship,0x400); + sgx_load_vram(0x5900,explosion,0x800); + + sgx_satb_update(); + + load_background(scene_chr,scene_pal,scene_bat,32,28); + + set_font_color(15, 6); + load_default_font(); + + while(!dead) + { + vsync(); + j1 = joy(0); + if (joytrg(0) & JOY_RUN) { + vsync(); + while (!(joytrg(0) & JOY_RUN)) + vsync(); + } + if (j1 & JOY_LEFT) + { + sgx_spr_ctrl(FLIP_X_MASK,NO_FLIP_X); + if (bonkx > -8) bonkx -= SPEED_X; + tic++; + bonk_dir = -1; + } + if (j1 & JOY_RIGHT) + { + sgx_spr_ctrl(FLIP_X_MASK,FLIP_X); + if (bonkx < 232) bonkx += SPEED_X; + tic++; + bonk_dir = 1; + } + if (j1 & JOY_UP) + { + if (bonky > -8) bonky -= SPEED_Y; + } + if (j1 & JOY_DOWN) + { + if (bonky < 212) bonky += SPEED_Y; + } + if ((j1 & JOY_II) && !bullet_wait) { + for (bp = bullets, i = 0; i < MAX_BULLETS; ++i, ++bp) { + if (!bp->active) { + bp->active = bonk_dir; + bp->x = bonkx + 8 + bonk_dir * 16; + bp->y = bonky + 10; + bullet_wait = 10; + sgx_spr_set(BULLET_SPRITE + i); + if (bonk_dir > 0) + sgx_spr_ctrl(FLIP_X_MASK, FLIP_X); + else + sgx_spr_ctrl(FLIP_X_MASK, NO_FLIP_X); + break; + } + } + } + + if (bullet_wait) + bullet_wait--; + + bp = bullets; + for (i = 0; i < MAX_BULLETS; i++) { + if (bp->active) { + sgx_spr_set(BULLET_SPRITE + i); + sgx_spr_x(bp->x); + sgx_spr_y(bp->y); + bp->x += bp->active * SPEED_BULLET; + //put_number(bp->x, 4, 0, 0); + if (bp->x > 256 || bp->x < -16) { + bp->active = 0; + sgx_spr_x(-16); + sgx_spr_y(0); + } + } + ++bp; + } + + do_ships(); + + sp = ships; + for (i = 0; i < MAX_SHIPS; i++) { + if (sp->active == 1 && + ((sp->x > bonkx - 24 && + sp->x < bonkx + 24 && + sp->y > bonky - 20 && + sp->y < bonky + 9) || + (sp->x > bonkx - 18 && + sp->x < bonkx + 18 && + sp->y > bonky + 8 && + sp->y < bonky + 25))) { + put_string("GAME OVER", 11, 12); + for (j = 0; j < 100; j++) + vsync(); + dead = 1; + if (score > hiscore) + hiscore = score; + } + sp++; + } + sgx_spr_set(0); + sgx_spr_x(bonkx); + //put_number(bonkx, 4, 0, 1); + sgx_spr_y(bonky); + sgx_spr_pattern(0x5000 + (((tic >> 2) & 3) * 0x100)); + sgx_satb_update(); + put_number(score, 5, 26, 1); + put_string("HI", 1, 1); + put_number(hiscore, 5, 4, 1); + frames++; + } + } +} diff --git a/examples/hucc/shmup/shmup.cue b/examples/hucc/shmup/shmup.cue new file mode 100644 index 00000000..09920902 --- /dev/null +++ b/examples/hucc/shmup/shmup.cue @@ -0,0 +1,3 @@ +FILE "shmup.iso" BINARY + TRACK 1 MODE1/2048 + INDEX 1 00:00:00 diff --git a/include/huc/huc_misc.asm b/include/huc/huc_misc.asm index 8bd067c4..1a6c103c 100644 --- a/include/huc/huc_misc.asm +++ b/include/huc/huc_misc.asm @@ -336,7 +336,7 @@ lib2_farmemget.3: ; ---- ; copy a block ; - clx +.l0: clx cly dec <__ch bmi .l4 @@ -366,16 +366,23 @@ lib2_farmemget.3: ; ---- ; second half ; - tstw <__dx + lda <__dl + sta <__cl + ora <__dh beq .l5 ; -- reload dst and cnt - stw <__dx,<__cx - stw #$6000,<__fptr + stz <__dl + lda <__dh + sta <__ch + stz <__dh + stz <__fptr + lda #$60 + sta <__fptr+1 ; -- inc bank tma #3 inc A tam #3 - bra .l1 + bra .l0 ; ---- ; exit diff --git a/include/huc/macro.inc b/include/huc/macro.inc index 2d9a884b..3f2f6fad 100644 --- a/include/huc/macro.inc +++ b/include/huc/macro.inc @@ -357,3 +357,26 @@ _decw .macro decw \1 pla .endm + +;------------------------------- + +; +; Macro to use for the exit instruction of a ".proc" routine. +; +; In the old HuC method, procedures end with an "rts", with +; the "-newproc" option, they jump to a piece of shared code. +; + +.if USING_NEWPROC + +leave .macro + jmp leave_proc + .endm + +.else + +leave .macro + rts + .endm + +.endif USING_NEWPROC diff --git a/include/huc/startup.asm b/include/huc/startup.asm index d1190188..6a15c97a 100644 --- a/include/huc/startup.asm +++ b/include/huc/startup.asm @@ -1,17 +1,26 @@ ; ; STARTUP.ASM - MagicKit standard startup code ; +; +; Note: lib_exclude.asm is empty and can be overridden with a local version +; which is how compile-time variables should be defined in a HuC program +; +; Example: You may wish to implement your own joyport device driver, in which +; case you will need to disable the automatic Mouse/Joypad reading +; by setting "DISABLEJOYSCAN .equ 1" +; + .list .include "lib_exclude.asm" .ifdef _SGX HAVE_LIB3 = 1 - .endif - + .else .ifdef _AC HAVE_LIB3 = 1 .endif + .endif ; first, set MOUSE to default on: ; @@ -719,9 +728,11 @@ scd_ok: .endif HUC + .ifndef DISABLEJOYSCAN .ifdef SUPPORT_MOUSE jsr mousinit ; check existence of mouse .endif SUPPORT_MOUSE + .endif DISABLEJOYSCAN .if (CDROM) ; Now, install the RAM-based version of the @@ -1012,11 +1023,20 @@ vsync_hndl: .ifdef SUPPORT_MOUSE lda msflag ; if mouse supported, and exists beq .l3 ; then read mouse instead of pad + + .ifndef DISABLEJOYSCAN jsr mousread + .endif DISABLEJOYSCAN + bra .out .endif SUPPORT_MOUSE + + .ifdef DISABLEJOYSCAN +.l3: + .else .l3: jsr read_joypad ; else read joypad + .endif .out: rts diff --git a/examples/asm/elmer/include/common.asm b/include/hucc/common.asm similarity index 80% rename from examples/asm/elmer/include/common.asm rename to include/hucc/common.asm index 37b789ba..a2631ded 100644 --- a/examples/asm/elmer/include/common.asm +++ b/include/hucc/common.asm @@ -7,7 +7,7 @@ ; ; These should be located in permanently-accessible memory! ; -; Copyright John Brandwood 2021-2022. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -16,16 +16,6 @@ ; *************************************************************************** ; *************************************************************************** -; -; Useful variables. -; - - .ifndef _temp - .zp -_temp ds 2 ; For use within a subroutine. - .code - .endif - ; *************************************************************************** @@ -63,6 +53,8 @@ wait_nvsync: bsr wait_vsync ; # of VBLANK IRQs to wait in ; banks, with the 2nd bank having no specific relation to the 1st, there ; is no way to deal with a bank-increment, so do not map that region. ; +; N.B. Library code relies on this preserving X and V! +; set_bp_to_mpr3: lda.h <_bp ; Do not remap a ptr to RAM, cmp #$60 ; which is $2000-$5FFF. @@ -93,6 +85,8 @@ set_bp_to_mpr34:lda.h <_bp ; Do not remap a ptr to RAM, ; ; Increment the hi-byte of _bp and change TMA3 if necessary. ; +; N.B. Library code relies on this preserving A,X,Y and V! +; inc.h_bp_mpr3: inc.h <_bp ; Increment hi-byte of _bp. bpl !+ ; OK if within MPR0-MPR3. @@ -112,8 +106,8 @@ inc.h_bp_mpr3: inc.h <_bp ; Increment hi-byte of _bp. ; ; Increment the hi-byte of _bp and change TMA3 and TMA4 if necessary. ; - - .if 1 ; Save memory, for now. +; N.B. Library code relies on this preserving A,X,Y and V! +; inc.h_bp_mpr34: inc.h <_bp ; Increment hi-byte of _bp. bpl !+ ; OK if within MPR0-MPR3. @@ -127,14 +121,14 @@ inc.h_bp_mpr34: inc.h <_bp ; Increment hi-byte of _bp. pla !: rts - .endif - ; *************************************************************************** ; *************************************************************************** ; ; Put the _di data pointer into the VDC's MARR or MAWR register. +; +; N.B. Library code relies on this preserving Y! ; .if SUPPORT_SGX @@ -206,16 +200,15 @@ inc.h_di_mpr4: inc.h <_di ; Increment hi-byte of _di. ; ; Far-call a function in another bank. ; -; This is compatible with PCEAS's "-newproc" procedure calls, but avoids -; generating a 10-byte procedure trampoline. +; This is a potential alternative procedure call trampoline that uses only 10 +; bytes of common memory per bank of procedures, instead of 10 bytes for each +; individual procedure call, BUT it uses the X register as a procedure-index, +; and it needs a table of addresses at the end of every procedure bank. ; ; To use this ... ; -; jsr far_call -; tst #bank( myfunc ), myfunc - 1 -; -; The "TST" instruction itself is skipped and NOT executed after the call, -; it only exists to make things easier to read in a listing/debugger. +; ldx #procedure-index +; jsr far_call_nn ; ; The called .PROC routine must exit with "jmp leave_proc" and not "rts". ; @@ -224,43 +217,23 @@ inc.h_di_mpr4: inc.h <_di ; Increment hi-byte of _di. ; tya ; rts ; -; N.B. This costs 36 bytes, and takes 82 cycles vs 18 for the trampoline -; code (when you exclude preserving YA in zero-page). +; N.B. This costs 21 cycles vs 18 for the .newproc trampoline code (when you +; exclude preserving YA in zero-page). ; -; N.B. This is NOT re-entrant, and must NOT be used in an IRQ handler if -; _temp is not saved and restored! +; N.B. This was written as an excerise, and definitely not for HuC! ; .if 0 -far_call: sta.l <_bp ; Preserve YA registers as - sty.h <_bp ; an address parameter. +far_call_nn: +; sta.l <_bp ; 4 Preserve YA registers as +; sty.h <_bp ; 4 an address parameter. - pla ; Get return address. - sta.l <_temp - clc ; Skip the far_call() - adc #4 ; address parameter. - tay - pla - sta.h <_temp - adc #0 - pha ; Put return address. - phy + tma6 ; 4 Preserve MPR6. + pha ; 3 - tma6 ; Preserve MPR6. - pha + lda #bank_number ; 2 + tam6 ; 5 + jmp [$DF00, x] ; 7 - ldy #4 ; Push far_call() addr. - lda [_temp], y - pha - dey - lda [_temp], y - pha - - dey ; Read far_call() bank. - lda [_temp], y - tam6 - - rts ; Jump to routine. - - .endif + .endif ; 21 diff --git a/examples/asm/elmer/include/core-config.inc b/include/hucc/core-config.inc similarity index 84% rename from examples/asm/elmer/include/core-config.inc rename to include/hucc/core-config.inc index 2d95d86e..cf575923 100644 --- a/examples/asm/elmer/include/core-config.inc +++ b/include/hucc/core-config.inc @@ -5,7 +5,7 @@ ; ; Configuration settings for the "CORE(not TM)" PC Engine library code. ; -; Copyright John Brandwood 2021-2022. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -57,6 +57,19 @@ USING_MPR7 = 1 ; (0 or 1) USING_STAGE1 = 0 ; (0 or 1) .endif +; +; Are we currently building the CD-ROM Stage1 loader? +; +; If this is set, the library's startup code does not call the __sound_init +; macro because the sound driver code is not usually a part of the kernel. +; +; N.B. The CD-ROM Stage1 loader sets BUILDING_STAGE1=1 so it builds correctly. +; + + .ifndef BUILDING_STAGE1 +BUILDING_STAGE1 = 0 ; (0 or 1) + .endif + ; ; Is the last track of the CD a duplicate of the main ISO data track? ; @@ -107,15 +120,41 @@ SUPPORT_TED2 = 0 ; (0 or 1) .endif ; -; Support development for the SuperGrafx? +; Support development for the SuperGRAFX? ; -; This enables SuperGrafx support in certain library functions. +; This enables SuperGRAFX support in certain library functions. ; .ifndef SUPPORT_SGX SUPPORT_SGX = 0 ; (0 or 1) .endif +; +; Choose SuperGRAFX VPC initialization mode. +; +; SGX_PARALLAX=0 (useful when VDC #1 is a fullscreen HUD) +; +; FRONT +; SP1 = VDC #1 (pce) sprite pixels +; BG1 = VDC #1 (pce) background pixels +; SP2 = VDC #2 (sgx) sprite pixels +; BG2 = VDC #2 (sgx) background pixels +; BACK +; +; SGX_PARALLAX=1 +; +; FRONT +; SP1 = VDC #1 (pce) sprite pixels +; SP2 = VDC #2 (sgx) sprite pixels +; BG1 = VDC #1 (pce) background pixels +; BG2 = VDC #2 (sgx) background pixels +; BACK +; + + .ifndef SGX_PARALLAX +SGX_PARALLAX = 1 ; The most common default. + .endif + ; ; Support development for the ArcadeCard? ; @@ -192,9 +231,9 @@ MAX_PADS = 5 ; (1..5) ; .ifndef RESERVE_BANKS - .ifndef _KICKC -RESERVE_BANKS = 0 - .else + .ifdef _KICKC RESERVE_BANKS = 1 + .else +RESERVE_BANKS = 0 .endif _KICKC .endif RESERVE_BANKS diff --git a/examples/asm/elmer/include/core-kernel.asm b/include/hucc/core-kernel.asm similarity index 67% rename from examples/asm/elmer/include/core-kernel.asm rename to include/hucc/core-kernel.asm index 71d75964..129bf9df 100644 --- a/examples/asm/elmer/include/core-kernel.asm +++ b/include/hucc/core-kernel.asm @@ -5,7 +5,7 @@ ; ; The "CORE(not TM)" PC Engine library kernel code that runs after startup. ; -; Copyright John Brandwood 2021-2022. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -44,6 +44,16 @@ +; *************************************************************************** +; *************************************************************************** +; +; core_kernel - Start of kernel code. +; + +core_kernel = * + + + ; *************************************************************************** ; *************************************************************************** ; @@ -63,10 +73,10 @@ bit_mask: db $01,$02,$04,$08,$10,$20,$40,$80 ; *************************************************************************** ; *************************************************************************** ; -; core_irq2 - Minimal interrupt handler compatible with System Card. -; core_irq1 - Minimal interrupt handler compatible with System Card. -; core_timer_irq - Minimal interrupt handler compatible with System Card. -; core_nmi_irq - Minimal interrupt handler compatible with System Card. +; core_irq2 - Minimal interrupt handler compatible with System Card. +; core_irq1 - Minimal interrupt handler compatible with System Card. +; core_timer - Minimal interrupt handler compatible with System Card. +; core_rti - Minimal interrupt handler compatible with System Card. ; ; Note that it takes 8 cycles to respond to an IRQ. ; @@ -99,7 +109,7 @@ bit_mask: db $01,$02,$04,$08,$10,$20,$40,$80 ; *************************************************************************** ; *************************************************************************** -core_irq2: bbs0 core_sw_reset - sta reset_hook + 1 - - lda #irq1_handler - sta irq1_hook + 1 + .if SUPPORT_SGX - lda #%10100010 ; Disable System Card IRQ1 - sta = $4000) ; If not running in RAM, then - .bss ; put the variables in RAM. + .ifndef USING_RCR_MACROS +.user_hsync_vdc:jmp [hsync_hook] ; 7 + .if SUPPORT_SGX +.user_hsync_sgx:jmp [hsync_hook_sgx] ; 7 .endif + .endif USING_RCR_MACROS -sound_mutex: ds 1 ; NZ when controller port busy. - .if SUPPORT_SGX -sgx_detected: ds 1 ; NZ if SuperGrafx detected. + +; *************************************************************************** +; *************************************************************************** +; +; core_timer - Minimal interrupt handler compatible with System Card. +; +; tirq_handler - Basic "CORE(not TM)" TIRQ handler to use as the "timer_hook". +; +; Doing the TIRQ handler processing in this hook means that things operate +; the same whether the System Card or an Overlay is paged into MPR7. + + .ifndef HUCC + ; Traditional System Card IRQ servicing delay for code that + ; was written to assume the *exact* same timing. + +jump_timer: jmp [timer_hook] ; 7 cycles. + +core_timer: ;;; ; 8 (cycles for the INT) + bbs2 core_sw_reset + sta.h reset_hook + + lda #irq1_handler + sta.h irq1_hook + + lda #tirq_handler + sta.h timer_hook + + lda #%00000110 ; Replace the System Card's + sta = $4000) ; If not running in RAM, then + .bss ; put these variables in RAM. + .endif + +sound_mutex: ds 1 ; NZ when controller port busy. + + .if SUPPORT_SGX +sgx_detected: ds 1 ; NZ if SuperGrafx detected. +hsync_hook_sgx: ds 2 ; SGX version of hsync_hook. + .endif + + .if SUPPORT_ACD +acd_detected: ds 1 ; NZ if ArcadeCard detected. + .endif + + .if (core_kernel >= $4000) + .code + .endif diff --git a/examples/asm/elmer/include/core-stage1.asm b/include/hucc/core-stage1.asm similarity index 93% rename from examples/asm/elmer/include/core-stage1.asm rename to include/hucc/core-stage1.asm index 3ae6a362..2e9e8b18 100644 --- a/examples/asm/elmer/include/core-stage1.asm +++ b/include/hucc/core-stage1.asm @@ -5,7 +5,7 @@ ; ; CD-ROM Stage1 loader using the "CORE(not TM)" PC Engine library code. ; -; Copyright John Brandwood 2021-2022. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -49,6 +49,18 @@ USING_STAGE1 = 0 USING_MPR7 = 0 + ; Yes, we're currently builing the Stage1 loader. + +BUILDING_STAGE1 = 1 + + ; Do NOT allocate HOME_BANK for the Stage1 loader! + +NEED_HOME_BANK = 0 + + ; Do NOT allocate SOUND_BANK for the Stage1 loader! + +NEED_SOUND_BANK = 0 + ; This loader wants to keep DATA_BANK == CORE_BANK, so ... RESERVE_BANKS = -1 @@ -61,21 +73,6 @@ RESERVE_BANKS = -1 .list .mlist - ; Pad the kernel out to the end of the current CD sector. - ; - ; This file is being assembled with the PCEAS "-bin" option, - ; so only the data used is written out, allowing the output - ; file to be sector-aligned rather than bank-aligned. - - .bss - .org core_ramend - - .data - .org core_ramcpy - - .if (* & 2047) - ds 2048 - (* & 2047), 255 ; Pad to end of CD sector. - .endif .code @@ -94,8 +91,6 @@ RESERVE_BANKS = -1 ; either execute the 2nd overlay file, or the CDERR overlay file. ; - .org core_stage1 - .if (CDROM == SUPER_CD) ; If SuperCDROM, then ... core_main: jsr ex_getver ; Get System Card version. @@ -414,10 +409,12 @@ font_data: incbin "font8x8-stage1-exos.dat" ; *************************************************************************** ; *************************************************************************** ; -; Sanity Check to ensure that this loader code fits into the chunk of memory -; between the startup code and the kernel code. +; Pad this loader out to the end of the current CD sector. ; +; This file is being assembled with the PCEAS "-bin" option, +; so only the data used is written out, allowing the output +; file to be sector-aligned rather than bank-aligned. - .if (core_ram1st & $1FFF) < (* & $1FFF) - .fail The Stage1 loader overruns the kernel code! + .if (* & 2047) + ds 2048 - (* & 2047), 255 ; Pad to end of CD sector. .endif diff --git a/examples/asm/elmer/include/core-stage1.s2i b/include/hucc/core-stage1.s2i similarity index 94% rename from examples/asm/elmer/include/core-stage1.s2i rename to include/hucc/core-stage1.s2i index 0757f489..825d3bd2 100644 --- a/examples/asm/elmer/include/core-stage1.s2i +++ b/include/hucc/core-stage1.s2i @@ -5,7 +5,7 @@ ; ; CD-ROM Stage1 loader using the "CORE(not TM)" PC Engine library code. ; -; Copyright John Brandwood 2021. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -30,7 +30,7 @@ ; *************************************************************************** ; *************************************************************************** -core_ram1st +core_kernel const_FFFF const_0000 @@ -38,8 +38,8 @@ bit_mask core_irq2 core_irq1 -core_timer_irq -core_nmi_irq +core_timer +core_rti read_joypads port_mutex @@ -61,9 +61,10 @@ core_sw_reset call_bios get_file_info +get_file_lba exec_overlay -core_ramcpy +core_ramiso iso_count iso_cderr diff --git a/examples/asm/elmer/include/core-startup.asm b/include/hucc/core-startup.asm similarity index 77% rename from examples/asm/elmer/include/core-startup.asm rename to include/hucc/core-startup.asm index b89b75e3..66a26bf7 100644 --- a/examples/asm/elmer/include/core-startup.asm +++ b/include/hucc/core-startup.asm @@ -5,7 +5,7 @@ ; ; The "CORE(not TM)" PC Engine library startup code that runs at boot/reset. ; -; Copyright John Brandwood 2021-2022. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -36,33 +36,33 @@ ; other, and can be written in different programming languages. ; ; -; 1) If we're running on a HuCard, the initialization is simple! +; 1) If we're running on a HuCARD, the initialization is simple! ; ; The PC Engine's memory map is set to ... ; ; MPR0 = bank $FF : PCE hardware ; MPR1 = bank $F8 : PCE RAM with Stack & ZP -; MPR2 = bank $00 : HuCard ROM -; MPR3 = bank $01 : HuCard ROM -; MPR4 = bank $02 : HuCard ROM -; MPR5 = bank $03 : HuCard ROM -; MPR6 = bank $04 : HuCard ROM -; MPR7 = bank $00 : HuCard ROM +; MPR2 = bank $00 : HuCARD ROM +; MPR3 = bank $01 : HuCARD ROM +; MPR4 = bank $02 : HuCARD ROM +; MPR5 = bank $03 : HuCARD ROM +; MPR6 = bank $04 : HuCARD ROM +; MPR7 = bank $00 : HuCARD ROM ; ; -; 2) If we're running on a HuCard that supports the Turbo Everdrive, then the +; 2) If we're running on a HuCARD that supports the Turbo Everdrive, then the ; first 2 banks are reserved for mapping the TED2 hardware and a RAM bank. ; ; The PC Engine's memory map is set to ... ; ; MPR0 = bank $FF : PCE hardware ; MPR1 = bank $F8 : PCE RAM with Stack & ZP -; MPR2 = bank $02 : HuCard ROM -; MPR3 = bank $03 : HuCard ROM -; MPR4 = bank $04 : HuCard ROM -; MPR5 = bank $05 : HuCard ROM -; MPR6 = bank $06 : HuCard ROM -; MPR7 = bank $02 : HuCard ROM +; MPR2 = bank $02 : HuCARD ROM +; MPR3 = bank $03 : HuCARD ROM +; MPR4 = bank $04 : HuCARD ROM +; MPR5 = bank $05 : HuCARD ROM +; MPR6 = bank $06 : HuCARD ROM +; MPR7 = bank $02 : HuCARD ROM ; ; ; 3) If we're running on an old CD System, the overlay is loaded from the ISO @@ -103,16 +103,16 @@ .bank 0 .if SUPPORT_TED2 ; Do we want to use a TED2? - .if !CDROM ; Only applies to a HuCard! + .if !CDROM ; Only applies to a HuCARD! ; *************************************************************************** ; *************************************************************************** ; -; RESET VECTORS (when booted as a HuCard for the Turbo Everdrive 2) +; RESET VECTORS (when booted as a HuCARD for the Turbo Everdrive 2) ; - ; Minimal HuCard startup code that immediately trampoline's - ; to the normal HuCard startup code in bank 2. + ; Minimal HuCARD startup code that immediately trampoline's + ; to the normal HuCARD startup code in bank 2. .org $FF00 @@ -134,7 +134,7 @@ ted2_hw_reset: sei ; Disable interrupts. jmp [$FFFE] ; Call reset, just like boot. ; This string at this location tells both TEOS and Mednafen - ; that this HuCard ROM is TED2-aware, and to run the HuCard + ; that this HuCARD ROM is TED2-aware, and to run the HuCARD ; with 1MB RAM enabled. .org $FFD0 @@ -173,9 +173,6 @@ __trampolinebnk = 2 ; are in MPR7, tell PCEAS to .else !CDROM .fail You cannot currently build for CD-ROM and SUPPORT_TED2! -; .if !USING_MPR7 -; .fail You cannot build for CD-ROM and SUPPORT_TED2 without using MPR7! -; .endif !USING_MPR7 .endif !CDROM .endif SUPPORT_TED2 @@ -186,7 +183,7 @@ __trampolinebnk = 2 ; are in MPR7, tell PCEAS to ; *************************************************************************** ; *************************************************************************** ; -; RESET VECTORS (when running in MPR7, either as a HuCard, or a CD overlay) +; RESET VECTORS (when running in MPR7, either as a HuCARD, or a CD overlay) ; ; Hardware reset and interrupt vectors. @@ -198,8 +195,8 @@ core_version: db CORE_VERSION ; CORE(not TM) Version. dw core_irq2 ; IRQ2 (from CD/ADPCM) dw core_irq1 ; IRQ1 (from VDC) - dw core_timer_irq ; TIMER (from CPU) - dw core_nmi_irq ; NMI (unused) + dw core_timer ; TIMER (from CPU) + dw core_rti ; NMI (unused) .if CDROM dw core_sw_reset ; RESET (CD-ROM) .else @@ -234,7 +231,7 @@ __trampolineptr = $5FFF ; are in MPR2, tell PCEAS to ; Switch to MPR2 for the "CORE(not TM)" library init. ; - ; This is also executed by a HuCard once it has run + ; This is also executed by a HuCARD once it has run ; its initial hardware-reset code. ; ; When run, MPR2-MPR6 are always mapped to the 1st 5 banks of @@ -244,13 +241,49 @@ __trampolineptr = $5FFF ; are in MPR2, tell PCEAS to CORE_BANK = bank(*) - _bank_base ; It isn't always zero! ;-) -core_boot: jmp * + 3 ; Allow someone to patch this. + .if USING_MPR7 +CORE_PAGE = 7 ; User code runs in MPR7. + .else +CORE_PAGE = 2 ; User code runs in MPR2. + .endif USING_MPR7 + +core_boot: jmp * + 6 ; Allow someone to patch this. + + ; Add an ident string so isoLINK can autodetect configuration. + ; + ; This allows isoLINK to decide whether to use the IPL-SCD boot + ; sector hack, and whether to include a SuperGRAFX signature in + ; the boot sector, without the user having to manually use some + ; command line parameters, although they are free to do that if + ; they wish. + + .if SUPPORT_SGX + .if BUILDING_STAGE1 + db "SG1" ; SGX SuperCD Stage1 loader. + .else + db "SGX" ; SGX SuperCD or SGX HuCARD. + .endif BUILDING_STAGE1 + .else + .if CDROM + .if CDROM == 2 + .if BUILDING_STAGE1 + db "SC1" ; PCE SuperCD Stage1 loader. + .else + db "SCD" ; PCE SuperCD. + .endif BUILDING_STAGE1 + .else + db " CD" ; PCE CD. + .endif CDROM == 2 + .else + db "PCE" ; PCE HuCARD. + .endif CDROM + .endif SUPPORT_SGX .if CDROM .if !USING_STAGE1 ; Because the Stage1 does it! - lda core_ram1st ; Did a previous overlay set + lda core_kernel ; Did a previous overlay set bne .not_first ; up the kernel already? ; Is there a duplicate of the main ISO data track? @@ -273,7 +306,7 @@ core_boot: jmp * + 3 ; Allow someone to patch this. ; Copy the kernel code to its destination in MPR1. - tii (core_ram1st + $2000), core_ram1st, (core_ramcpy - core_ram1st) + tii core_rom1st, core_ram1st, (core_ramiso - core_ram1st) ; Copy the ISO's directory into kernel memory in MPR1. @@ -340,16 +373,16 @@ core_boot: jmp * + 3 ; Allow someone to patch this. ; core_ramend - End of code to relocate to MPR1. ; - ; In a HuCard, BSS variables start as low as possible. + ; In a HuCARD, BSS variables start as low as possible. .bss .org core_ram1st core_ramend = * .code - ; Normal HuCard hardware-reset code, executed in MPR7. + ; Normal HuCARD hardware-reset code, executed in MPR7. ; - ; This does the basic PCE startup that every HuCard (including + ; This does the basic PCE startup that every HuCARD (including ; a System Card) needs to do, and then it remaps memory to be ; compatible with the "CORE(not TM)" CD overlay program start. @@ -386,7 +419,7 @@ core_hw_reset: sei ; Disable interrupts. jmp core_boot ; Continue execution in MPR2. - ; In a HuCard, the kernel code is permanently in MPR7. + ; In a HuCARD, the kernel code is permanently in MPR7. include "core-kernel.asm" @@ -399,8 +432,9 @@ core_hw_reset: sei ; Disable interrupts. ; ; CD-ROM Kernel Code ; -; core_ram1st - Start of code to relocate to MPR1. -; core_ramend - End of code to relocate to MPR1. +; core_rom1st - Start of code to relocate from MPR2 to MPR1. +; core_ram1st - Start of code when relocated to MPR1. +; core_ramend - End of code when relocated to MPR1. ; ; @@ -417,25 +451,21 @@ core_hw_reset: sei ; Disable interrupts. include "core-stage1.s" - .else USING_STAGE1 - - ; Remember where the startup code ends in MPR2. - ; - ; There are a few hundred bytes of unused space between the - ; startup code, and the kernel code that gets copied to RAM, - ; and the Stage1 loader code fits nicely into that space! + .if (core_kernel != core_ram1st) + .fail Stage1 kernel has not been built with the same core_ram1st! + .endif -core_stage1 = * + .else USING_STAGE1 - ; Switch to MPR1 to build the kernel code that runs in RAM. + ; Use .PHASE/.DEPHASE to assemble the kernel to run in MPR1. - .org core_ram1st +core_rom1st: .phase core_ram1st ; Assemble the code for RAM. include "core-kernel.asm" ; Remember where the kernel code ends in MPR1. -core_ramcpy = * +core_ramiso: .dephase ; Restore normal assembly. ; ISOlink CD-ROM File Directory : ; @@ -461,7 +491,7 @@ core_ramcpy = * ; sector number, the directory stores the index of the first ; file that starts beyond that boundary. - rsset core_ramcpy + rsset core_ramiso iso_cderr rs 1 ; index # of CDERR file iso_dirlo rs MAX_DIRSIZE ; lo-byte of file's sector # @@ -498,22 +528,16 @@ core_ramend rs 0 ; ; With the availability of so many different configuration options, we've now ; built somewhere between a few hundred bytes, and a couple of KB, of code in -; this first bank of the HuCARD / overlay program. But this is the end of the -; "CORE(not TM)" library code! +; the CORE_BANK of the HuCARD / overlay program. +; +; This is the end of the "CORE(not TM)" library code! ; ; Remember that the ".proc" trampolines are located at the end of this bank, ; so the amount of free space left depends upon the number of ".proc" calls. ; - .if USING_MPR7 - ; Switch to MPR7 to run the developer's game code. - - .page 7 ; User code runs in MPR7. - .else - ; Switch to MPR2 to run the developer's game code. - - .page 2 ; User code runs in MPR2. - .endif USING_MPR7 + ; Switch to CORE_PAGE to run the developer's game code. + .page CORE_PAGE @@ -540,10 +564,43 @@ core_ramend rs 0 ; RESERVE_BANKS is normally defined in each project's "core-config.inc". ; -DATA_BANK = CORE_BANK + 1 + RESERVE_BANKS + .opt d+ ; DATA labels use fixed MPR. + .rsset CORE_BANK + 1 + + .ifdef NEED_HOME_BANK + .if NEED_HOME_BANK +HOME_BANK .rs 1 + .home ; HuCC permanent code and + .bank HOME_BANK, ".home" ; initialized data runs in + .org $A000 ; MPR5 (.section CODE). + .endif + .endif + + .ifdef NEED_SOUND_BANK ; Defined in hucc-sound.inc + .if NEED_SOUND_BANK ; if the driver wants a bank. +SOUND_BANK .rs 1 + .endif + .endif + + .ifdef RESERVE_BANKS ; For CORE projects. +RESERVED_BANK .rs RESERVE_BANKS + .endif + + .ifdef HUCC + .ifdef HUC_RESERVE_BANKS ; For HuCC projects. +HUC_USER_BANK .rs HUC_RESERVE_BANKS + .endif + +CONST_BANK .rs 2 .data - .bank DATA_BANK + .bank CONST_BANK, ".const" .org $6000 - .opt d+ ; Force DATA labels to MPR3. + .endif HUCC + +DATA_BANK .rs 0 + .data + .bank DATA_BANK, ".data" + .org $6000 + .code diff --git a/examples/asm/elmer/include/core.inc b/include/hucc/core.inc similarity index 72% rename from examples/asm/elmer/include/core.inc rename to include/hucc/core.inc index 27b65dca..132fb37d 100644 --- a/examples/asm/elmer/include/core.inc +++ b/include/hucc/core.inc @@ -5,7 +5,7 @@ ; ; Base include for the "CORE(not TM)" PC Engine library code. ; -; Copyright John Brandwood 2021-2022. +; Copyright John Brandwood 2021-2024. ; ; Distributed under the Boost Software License, Version 1.0. ; (See accompanying file LICENSE_1_0.txt or copy at @@ -71,9 +71,9 @@ sound_hook = nmi_hook ; Sound Driver to run in VBL. ; .if USING_PSGDRIVER -core_zpend = $20E6 +core_zpend = $F8:20E6 .else -core_zpend = $20EC +core_zpend = $F8:20EC .endif USING_PSGDRIVER .if SUPPORT_SGX @@ -88,47 +88,43 @@ core_zpend = $20EC ; the X register, and then index into either set of hardware ; registers and the "sgx_reg" or "vdc_reg" shadow-variables. -PCE_VDC_OFFSET = $00 ; Offset to PCE VDC hw & vars. -SGX_VDC_OFFSET = $10 ; Offset to SGX VDC hw & vars. +PCE_VDC_OFFSET = $00 ; Offset to PCE VDC chip & shadow vars. +SGX_VDC_OFFSET = $10 ; Offset to SGX VDC chip & shadow vars. -_temp = $2000 ; Use within any ASM routine. -_bank = $2002 ; Use within any ASM routine. -sgx_crl = $2003 ; SGX shadow (vdc_crl = $20F3). -sgx_crh = $2004 ; SGX shadow (vdc_crh = $20F4). -core_1stbank = $2005 ; 1st bank of library code. -sgx_sr = $2006 ; SGX shadow (vdc_sr = $20F6). -sgx_reg = $2007 ; SGX shadow (vdc_reg = $20F7). + .zp + .org $2000 +__temp ds 2 ; $F8:2000 Use within any ASM routine. +_bp_bank ds 1 ; $F8:2002 Use within any ASM/HuCC routine. +sgx_crl ds 1 ; $F8:2003 SGX shadow (vdc_crl = $20F3). +sgx_crh ds 1 ; $F8:2004 SGX shadow (vdc_crh = $20F4). +core_1stbank ds 1 ; $F8:2005 1st bank of library code. +sgx_sr ds 1 ; $F8:2006 SGX shadow (vdc_sr = $20F6). +sgx_reg ds 1 ; $F8:2007 SGX shadow (vdc_reg = $20F7). -core_zp1st = $2008 ; 1st free user address. +core_zp1st = * ; $F8:2008 1st free user address. .else SUPPORT_SGX -_temp = $2000 ; Use within any ASM routine. -_bank = $2002 ; Use within any ASM routine. -core_1stbank = $2003 ; 1st bank of engine code. + .zp + .org $2000 +__temp ds 2 ; Use within any ASM routine. +_bp_bank ds 1 ; Use within any ASM/HuCC routine. +core_1stbank ds 1 ; 1st bank of engine code. -core_zp1st = $2004 ; 1st free user address. +core_zp1st = * ; 1st free user address. .endif SUPPORT_SGX - .zp - .org core_zp1st - .code - ; ; The kernel code in RAM follows the System Card's RAM variables. ; .if USING_PSGDRIVER -core_ram1st = $2680 +core_ram1st = $F8:2680 .else -core_ram1st = $22D0 +core_ram1st = $F8:22D0 .endif USING_PSGDRIVER - .bss - .org core_ram1st - .code - ; ; Include the "CORE(not TM)" startup code to begin the HuCARD / Overlay. ; diff --git a/include/hucc/data/font8x8-bold-short-ascii.dat b/include/hucc/data/font8x8-bold-short-ascii.dat new file mode 100644 index 00000000..e0fcac04 Binary files /dev/null and b/include/hucc/data/font8x8-bold-short-ascii.dat differ diff --git a/include/hucc/data/font8x8-bold-short-iso646-fr.dat b/include/hucc/data/font8x8-bold-short-iso646-fr.dat new file mode 100644 index 00000000..fe89bf85 Binary files /dev/null and b/include/hucc/data/font8x8-bold-short-iso646-fr.dat differ diff --git a/include/hucc/huc.h b/include/hucc/huc.h new file mode 100644 index 00000000..39baee5a --- /dev/null +++ b/include/hucc/huc.h @@ -0,0 +1,42 @@ +#ifndef _hucc_legacy_h +#define _hucc_legacy_h + +/**************************************************************************** +; *************************************************************************** +; +; huc.h +; +; HuCC wrapper file to include a default set of HuC-compatible functions. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; When the HuCC compiler is invoked with the "--legacy" option to compile old +; projects, then this "huc.h" file is automatically included. +; +; This file includes a set of the individual HuCC headers which correspond to +; HuC's built-in functions and MagicKit library. +; +; New HuCC projects should, preferably, include the specific headers that are +; needed, which will then allow them to replace parts of the standard library +; with newer functions, or they can just manually include this "huc.h" file. +; +; *************************************************************************** +; **************************************************************************/ + +#include "hucc-systemcard.h" +#include "hucc-baselib.h" +#include "hucc-gfx.h" +#include "hucc-string.h" +#include "hucc-old-scroll.h" +#include "hucc-old-spr.h" +#include "hucc-old-map.h" +#include "hucc-old-line.h" + +#endif // _hucc_legacy_h diff --git a/include/hucc/hucc-baselib.asm b/include/hucc/hucc-baselib.asm new file mode 100644 index 00000000..328ed5e8 --- /dev/null +++ b/include/hucc/hucc-baselib.asm @@ -0,0 +1,598 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-baselib.asm +; +; Basic library functions provided as macros. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe dump_screen( void ); +; +; THIS IS AN ILLEGAL INSTRUCTION ONLY IMPLEMENTED BY THE TGEMU EMULATOR! + +_dump_screen: db 0x33 + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe abort( void ); +; +; THIS IS AN ILLEGAL INSTRUCTION ONLY IMPLEMENTED BY THE TGEMU EMULATOR! + +_abort: db 0xE2 + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe exit( int value ); +; +; THIS IS AN ILLEGAL INSTRUCTION ONLY IMPLEMENTED BY THE TGEMU EMULATOR! + +_exit.1: tax ; Put the return code into X. + db 0x63 + +.hang: bra .hang ; Hang if used in normal code. + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro cd_execoverlay( unsigned char ovl_index ); +; +; Execute program overlay from disc +; +; N.B. This does not return, even if there's an error. + + .macro _cd_execoverlay.1 + tax + jmp exec_overlay + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro ac_exists( void ); + +_ac_exists .macro + cla + ldy ACD_FLAG + cpy #ACD_ID + bne !+ + inc a +!: cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro _sgx_detect( void ); + +_sgx_detect .macro + lda sgx_detected + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe __macro peek( unsigned int addr<__ptr> ); + +_peek.1 .macro + lda [__ptr] + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe __macro peekw( unsigned int addr<__ptr> ); + +_peekw.1 .macro + lda [__ptr] + pha + ldy #1 + lda [__ptr], y + tay + pla + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __macro __xsafe poke( unsigned int addr<__poke>, unsigned char with ); +; +; N.B. Because the value can be a complex C calculation, it isn't safe +; to use __ptr as the destination, which can be overwritten in C macros. + +_poke.2 .macro + sta [__poke] + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __macro __xsafe pokew( unsigned int addr<__poke>, unsigned int with ); +; +; N.B. Because the value can be a complex C calculation, it isn't safe +; to use __ptr as the destination, which can be overwritten in C macros. + +_pokew.2 .macro + sta [__poke] + tya + ldy #1 + sta [__poke], y + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro clock_hh( void ); + +_clock_hh .macro + lda clock_hh + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro clock_mm( void ); + +_clock_mm .macro + lda clock_mm + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro clock_ss( void ); + +_clock_ss .macro + lda clock_ss + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro clock_tt( void ); + +_clock_tt .macro + lda clock_tt + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro clock_reset( void ); + +_clock_reset .macro + stz clock_hh + stz clock_mm + stz clock_ss + stz clock_tt + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro vsync( void ); +; void __fastcall __xsafe __macro vsync( unsigned char count ); + +_vsync .macro + jsr wait_vsync + .endm + +_vsync.1 .macro + tay + jsr wait_nvsync + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro joy( unsigned char which ); + +_joy.1 .macro + .if SUPPORT_6BUTTON + tay + lda joy6now, y + pha + lda joynow, y + ply + .else + tay + lda joynow, y + cly + .endif + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro joytrg( unsigned char which ); + +_joytrg.1 .macro + .if SUPPORT_6BUTTON + tay + lda joy6trg, y + pha + lda joytrg, y + ply + .else + tay + lda joytrg, y + cly + .endif + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe _nop set_color( unsigned int index, unsigned int value ); +; void __fastcall __xsafe set_color_rgb( unsigned int index, unsigned char r<_al>, unsigned char g<_ah>, unsigned char b ); +; +; r: red RED: bit 3-5 +; g: green GREEN: bit 6-8 +; b: blue BLUE: bit 0-2 + +_set_color_rgb.4: +; lda <_bl +; and #7 + sta <__temp + lda <_al +; and #7 + asl a + asl a + asl a + ora <__temp + asl a + asl a + sta <__temp + lda <_ah +; and #7 + lsr a + ror <__temp + lsr a + ror <__temp + tay + lda <__temp + sta.l VCE_CTW + sty.h VCE_CTW + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe _macro get_color( unsigned int index ); + +_get_color.1 .macro + lda.l VCE_CTR + ldy.h VCE_CTR + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe srand( unsigned char seed ); +; unsigned int __fastcall __xsafe rand( void ); +; unsigned char __fastcall __xsafe rand8( void ); + + .ifndef HUCC_NO_DEFAULT_RANDOM + .alias _srand.1 = init_random + +_rand: jsr get_random ; Random in A, preserve Y. + tay + jmp get_random ; Random in A, preserve Y. + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe random8( unsigned char limit ); +; +; IN : A = range (0..255) +; OUT : A = random number interval 0 <= x < A + + .ifndef HUCC_NO_DEFAULT_RANDOM + +_random8.1: tay ; Preserve the limit. + jsr get_random ; Random in A, preserve Y. + + jsr __muluchar ; This is __xsafe! + tya ; Do a 8.0 x 0.8 fixed point + cly ; fractional multiply. + rts + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe random( unsigned char limit ); +; +; IN : A = range (0..128), 129..255 is treated as 128 +; OUT : A = random number interval 0 <= x < A + + .ifndef HUCC_NO_DEFAULT_RANDOM + +_random.1: tay ; Preserve the limit. + jsr get_random ; Random in A, preserve Y. + + cpy #128 ; Check the limit. + bcc !+ + + and #$7F ; Just mask the random if + cly ; the limit is >= 128. + rts + +!: jsr __muluchar ; This is __xsafe! + tya ; If the limit is < 128 then + cly ; do a 8.0 x 0.8 fixed point + rts ; fractional multiply. + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __builtin_ffs( unsigned int value<__temp> ); + + .proc ___builtin_ffs.1 + + lda.l <__temp + ldy #-16 + +.search: lsr.h <__temp + ror a + bcs .found + iny + bne .search + bra .finished + +.found: tya ; CS, return 17 + y. + adc #16 + +.finished: tax ; Put return code in X. + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; N.B. Declared in hucc-gfx.h, but defined here because they're macros! +; +; void __fastcall __xsafe _macro set_xres( unsigned int x_pixels<_ax> ); +; void __fastcall __xsafe _macro sgx_set_xres( unsigned int x_pixels<_ax> ); +; +; void __fastcall __xsafe set_xres( unsigned int x_pixels<_ax>, unsigned char blur_flag<_bl> ); +; void __fastcall __xsafe sgx_set_xres( unsigned int x_pixels<_ax>, unsigned char blur_flag<_bl> ); + +_set_xres.1 .macro + lda #XRES_SOFT + sta <_bl + call _set_xres.2 + .endm + + .if SUPPORT_SGX + .macro _sgx_set_xres.1 + lda #XRES_SOFT + sta <_bl + call _sgx_set_xres.2 + .endm + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; N.B. Declared in hucc-gfx.h, but defined here because they're macros! +; +; unsigned int __fastcall __xsafe __macro vram_addr( unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +; unsigned int __fastcall __xsafe __macro sgx_vram_addr( unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + + .macro _vram_addr.2 + cla + bit vdc_bat_width + bmi !w128+ + bvs !w64+ +!w32: lsr <_ah + ror a +!w64: lsr <_ah + ror a +!w128: lsr <_ah + ror a + ora <_al + ldy <_ah + .endm + + .if SUPPORT_SGX + .macro _sgx_vram_addr.2 + cla + bit sgx_bat_width + bmi !w128+ + bvs !w64+ +!w32: lsr <_ah + ror a +!w64: lsr <_ah + ror a +!w128: lsr <_ah + ror a + ora <_al + ldy <_ah + .endm + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; N.B. Declared in hucc-gfx.h, but defined here because they're macros! +; +; unsigned int __fastcall __xsafe __macro get_vram( unsigned int address<_di> ); +; void __fastcall __xsafe __macro put_vram( unsigned int address<_di>, unsigned int data ); +; +; unsigned int __fastcall __xsafe __macro sgx_get_vram( unsigned int address<_di> ); +; void __fastcall __xsafe __macro sgx_put_vram( unsigned int address<_di>, unsigned int data ); + + .macro _get_vram.1 + phx + jsr vdc_di_to_marr + plx + lda VDC_DL + ldy VDC_DH + .endm + + .macro _put_vram.2 + pha + phx + jsr vdc_di_to_mawr + plx + pla + sta VDC_DL + sty VDC_DH + .endm + + .if SUPPORT_SGX + .macro _sgx_get_vram.1 + phx + jsr sgx_di_to_marr + plx + lda SGX_DL + ldy SGX_DH + .endm + + .macro _sgx_put_vram.2 + pha + phx + jsr sgx_di_to_mawr + plx + pla + sta SGX_DL + sty SGX_DH + .endm + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; N.B. Declared in hucc-gfx.h, but defined here because they're macros! +; +; void __fastcall __xsafe __macro set_bgpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp> ); +; void __fastcall __xsafe __macro set_bgpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_palettes<_ah> ); +; void __fastcall __xsafe __macro set_sprpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp> ); +; void __fastcall __xsafe __macro set_sprpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_palettes<_ah> ); + +_set_bgpal.2 .macro + lda #1 + sta <_ah + call _load_palette.3 + .endm + +_set_bgpal.3 .macro + call _load_palette.3 + .endm + +_set_sprpal.2 .macro + lda #1 + sta <_ah + smb4 <_al + call _load_palette.3 + .endm + +_set_sprpal.3 .macro + smb4 <_al + call _load_palette.3 + .endm + + + +; *************************************************************************** +; *************************************************************************** + + .if 0 +__lbltsbi .macro + sec ; Subtract memory from A. + sbc.l #\1 ; "cmp" does not set V flag! + bvc !+ + eor #$80 ; +ve if A >= memory (signed). +!: bmi \2 ; -ve if A < memory (signed). + .endm + + +__lbltswi .macro + cmp.l #\1 ; Subtract memory from Y:A. + tya + sbc.h #\1 + bvc !+ + eor #$80 ; +ve if Y:A >= memory (signed). +!: bmi \2 ; -ve if Y:A < memory (signed). + .endm + .endif diff --git a/include/hucc/hucc-baselib.h b/include/hucc/hucc-baselib.h new file mode 100644 index 00000000..822508a7 --- /dev/null +++ b/include/hucc/hucc-baselib.h @@ -0,0 +1,143 @@ +#ifndef _hucc_baselib_h +#define _hucc_baselib_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-baselib.h +; +; Basic library functions provided as macros. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Joypad defines ... +// ************* + +#define JOY_A 0x01 +#define JOY_I 0x01 +#define JOY_B 0x02 +#define JOY_II 0x02 +#define JOY_SLCT 0x04 +#define JOY_SEL 0x04 +#define JOY_STRT 0x08 +#define JOY_RUN 0x08 +#define JOY_UP 0x10 +#define JOY_RGHT 0x20 +#define JOY_RIGHT 0x20 +#define JOY_DOWN 0x40 +#define JOY_LEFT 0x80 + +#define JOY_C 0x0100 +#define JOY_III 0x0100 +#define JOY_D 0x0200 +#define JOY_IV 0x0200 +#define JOY_E 0x0400 +#define JOY_V 0x0400 +#define JOY_F 0x0800 +#define JOY_VI 0x0800 + +#define JOY_SIXBUT 0x8000 +#define JOY_TYPE6 0x8000 + +// ************* +// SuperGRAFX VPC settings for set_vpc_ctl() ... +// ************* + +#define VPC_SPR1_BKG1_SPR2_BKG2 0x3000 // same as SGX_PARALLAX=0 +#define VPC_SPR1_SPR2_BKG1_BKG2 0x7000 // same as SGX_PARALLAX=1 +#define VPC_BKG1_BKG2_SPR1_SPR2 0xB000 + +// ************* +// System Card variables ... +// ************* + +extern unsigned int si; +extern unsigned int di; +extern unsigned int bp; + +extern unsigned int ax; +extern unsigned int bx; +extern unsigned int cx; +extern unsigned int dx; + +extern unsigned char al; +extern unsigned char ah; +extern unsigned char bl; +extern unsigned char bh; +extern unsigned char cl; +extern unsigned char ch; +extern unsigned char dl; +extern unsigned char dh; + +// ************* +// Functions in hucc-baselib.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_BASELIB 1 + +extern unsigned char __fastcall __xsafe __macro sgx_detect( void ); +extern unsigned char __fastcall __xsafe __macro ac_exists( void ); + +extern void __fastcall __xsafe __nop vpc_set_ctl( unsigned int bits ); +extern void __fastcall __xsafe __nop vpc_set_win1( unsigned int width ); +extern void __fastcall __xsafe __nop vpc_set_win2( unsigned int width ); + +extern unsigned int __fastcall __xsafe __macro peek( unsigned int addr<__ptr> ); +extern unsigned int __fastcall __xsafe __macro peekw( unsigned int addr<__ptr> ); +extern void __fastcall __xsafe __macro poke( unsigned int addr<__poke>, unsigned char with ); +extern void __fastcall __xsafe __macro pokew( unsigned int addr<__poke>, unsigned int with ); + +extern unsigned int __fastcall __xsafe __farpeekw( void __far *addr<__fbank:__fptr> ); + +extern void __fastcall __xsafe __macro vsync( void ); +extern void __fastcall __xsafe __macro vsync( unsigned char count ); + +extern unsigned int __fastcall __xsafe __macro joy( unsigned char which ); +extern unsigned int __fastcall __xsafe __macro joytrg( unsigned char which ); + +extern void __fastcall __xsafe __nop set_color( unsigned int index, unsigned int value ); +extern void __fastcall __xsafe set_color_rgb( unsigned int index, unsigned char r<_al>, unsigned char g<_ah>, unsigned char b ); +extern unsigned int __fastcall __xsafe __macro get_color( unsigned int index ); + +extern unsigned char __fastcall __xsafe __macro clock_hh( void ); +extern unsigned char __fastcall __xsafe __macro clock_mm( void ); +extern unsigned char __fastcall __xsafe __macro clock_ss( void ); +extern unsigned char __fastcall __xsafe __macro clock_tt( void ); +extern void __fastcall __xsafe __macro clock_reset( void ); + +extern unsigned char __fastcall __xsafe __macro cd_execoverlay( unsigned char ovl_index ); + +extern int __fastcall __xsafe abs( int value ); + +extern void __fastcall __xsafe srand( unsigned char seed ); +extern unsigned int __fastcall __xsafe rand( void ); +extern unsigned char __fastcall __xsafe rand8( void ); + +// Note: "limit" is 0..255. +extern unsigned char __fastcall __xsafe random8( unsigned char limit ); + +// Note: "limit" is 0..128, 129..255 is treated as 128! +extern unsigned char __fastcall __xsafe random( unsigned char limit ); + +// Functions that are only implemented in the TGEMU emulator for unit-testing +// the compiler and which should never be used in normal HuCC projects ... + +extern void __fastcall __xsafe dump_screen( void ); +extern void __fastcall __xsafe abort( void ); +extern void __fastcall __xsafe exit( int value ); + +extern unsigned char __fastcall __builtin_ffs( unsigned int value<__temp> ); + +#endif // __HUCC__ + +#endif // _hucc_baselib_h diff --git a/include/hucc/hucc-codegen.asm b/include/hucc/hucc-codegen.asm new file mode 100644 index 00000000..1b7778a6 --- /dev/null +++ b/include/hucc/hucc-codegen.asm @@ -0,0 +1,4299 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-codegen.asm +; +; The HuCC compiler translates C code into these macros, it does not directly +; generate HuC6280 instructions. +; +; Based on the original HuC macros created by David Michel and the other HuC +; developers, later modified and improved by Ulrich Hecht. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; NAMING SCHEME FOR HuCC MACROS ... +; +; __function.parameters +; +; {parameters} is a list of alphanumeric specifiers, starting with {size} and +; followed by {where}, followed by {index} if an array, then optional {value} +; and finally ending with optional {suffix} +; +; {size} +; w : 16-bit signed int (default "int" in HuCC) +; c : 16-bit unsigned int (a "cardinal" in Pascal terms) +; b : 8-bit signed char +; u : 8-bit unsigned char (default "char" in HuCC) +; +; {where} or {index} +; r : HuCC primary register, made up of the Y:A cpu registers +; t : top of arithmetic stack +; p : indirect pointer, usually [__ptr] +; i : immediate value, i.e. a decimal number +; m : memory, i.e. C global, static, and "-fno-recursive" variables +; s : stack, i.e. C function parameters and locals (not "-fno-recursive") +; a : array, i.e. C global, static, "-fno-recursive" arrays <= 256 bytes +; x : array index already in the X register +; y : array index already in the Y register +; +; {value} OPTIONAL +; i : immediate value, i.e. a decimal number +; z : zero value +; +; {suffix} OPTIONAL +; q : quick, used for optimized math on only 8-bit values, because all math +; is normally promoted to "int" size in C; and when optimized stores do +; not need to preserve the primary register contents +; +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; i-code that retires the primary register contents +; *************************************************************************** +; *************************************************************************** + +; ************** +; this only exists to mark the end of a C statement when the primary register +; contents are no longer needed + +__fence .macro + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-code that declares a byte sized primary register +; *************************************************************************** +; *************************************************************************** + +; ************** +; this exists to mark that the primary register only needs byte accuracy + +__short .macro + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for handling farptr +; *************************************************************************** +; *************************************************************************** + +; /* 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 */ + +; case I_FARPTR_I: +; ot("__farptr_i\t"); +; outsymbol((char *)data); +; outstr(","); +; outstr(tmp->arg[0]); +; outstr(","); +; outstr(tmp->arg[1]); +; nl(); +; break; + +; case I_FARPTR_GET: +; ot("__farptr_get\t"); +; outstr(tmp->arg[0]); +; outstr(","); +; outstr(tmp->arg[1]); +; nl(); +; break; + +; case I_FGETB: +; ot("__farptr_i\t"); +; outsymbol((char *)data); +; nl(); +; ol("__fgetb"); +; break; + +; case I_FGETUB: +; ot("__farptr_i\t"); +; outsymbol((char *)data); +; nl(); +; ol("__fgetub"); +; break; + +; case I_FGETW: +; ot("__farptr_i\t"); +; outsymbol((char *)data); +; nl(); +; ol(" jsr\t_farpeekw.fast"); +; break; + +; ************** +; __farptr +; this is used for __far parameters to a __fastcall + +__farptr .macro + lda.l #$6000 + ($1FFF & (\1)) + sta.l \3 + lda.h #$6000 + ($1FFF & (\1)) + sta.h \3 + lda #bank(\1) + sta \2 + .endm + +; ************** +; adds 16-bit unsigned offset in Y:A to data address in \1 +; if 1-param then Y=bank, __fptr=addr, used for farpeekb() and farpeekw() +; if 3-param then \2=bank, \3=addr + +__farptr_i .macro + .if (\# = 3) + clc + adc.l #(\1) & $1FFF + sta.l \3 + tya + adc.h #(\1) & $1FFF + tay + and #$1F + ora #$60 + sta.h \3 + tya + ror a + lsr a + lsr a + lsr a + lsr a + clc + adc #bank(\1) + sta \2 + .else + clc + adc.l #(\1) & $1FFF + sta.l <__fptr + tya + adc.h #(\1) & $1FFF + tay + and #$1F + ora #$60 + sta.h <__fptr + tya + ror a + lsr a + lsr a + lsr a + lsr a + clc + adc #bank(\1) + tay + .endif + .endm + +; ************** +; JCB: I don't know what this is supposed to do! + + .if 0 +__farptr_get .macro + sta <\1 + ldy #2 + lda [__ptr], y + sta.l <\2 + iny + lda [__ptr], y + sta.h <\2 + .endm + .endif + +; ************** +; only executed immediately after a 1-parameter __farptr_i! +; expects Y=bank, __fptr=addr +; N.B. Preserves MPR3 unlike original HuC code. +; ************** +; unsigned int __fastcall __xsafe farpeekw( void far *base<__fbank:__fptr> ); +; ************** +; _farpeekw.fast is called by HuCC after executing __farptr_i macro. + +_farpeekw.1: ldy <__fbank +_farpeekw.fast: tma3 + pha + tya + tam3 + lda [__fptr] + say + inc.l <__fptr + bne !+ + inc.h <__fptr + bpl !+ + inc a + tam3 + lda #$60 + sta.h <__fptr +!: lda [__fptr] + sta <__temp + pla + tam3 + tya + ldy <__temp + rts + +; ************** +; only executed immediately after a 1-parameter __farptr_i! +; expects Y=bank, __fptr=addr +; N.B. Preserves MPR3 unlike original HuC code. + +__fgetb .macro + tma3 + pha + tya + tam3 + lda [__fptr] + tay + pla + tam3 + tya + cly + bpl !+ + dey +!: + .endm + +; ************** +; only executed immediately after a 1-parameter __farptr_i! +; expects Y=bank, __fptr=addr +; N.B. Preserves MPR3 unlike original HuC code. + +__fgetub .macro + tma3 + pha + tya + tam3 + lda [__fptr] + tay + pla + tam3 + tya + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for calling functions +; *************************************************************************** +; *************************************************************************** + +; ************** +; the compiler can generate this to aid debugging C data-stack +; balance problems before/after a function call + +__calling .macro + phx + .endm + +; ************** +; the compiler can generate this to aid debugging C data-stack +; balance problems before/after a function call + +__called .macro + stx <__sp + plx + cpx <__sp +!hang: bne !hang- + .endm + +; ************** + +__call .macro + call \1 + .endm + +; ************** + +__funcp.wr .macro + sta.l __func + sty.h __func + .endm + +; ************** + +__callp .macro + jsr call_indirect + .endm + +call_indirect: jmp [__func] + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for C functions and the C parameter stack +; *************************************************************************** +; *************************************************************************** + +; ************** +; function prolog + +__enter .macro + .endm + +; ************** +; function epilog +; \1 == 0 if no return value + +__return .macro + .if (\1 != 0) + sta <__hucc_ret + .endif + jmp leave_proc + .endm + +; ************** +; get the acc lo-byte after returning from a function + +__getacc .macro + lda <__hucc_ret + .endm + +; ************** +; main C data-stack for arguments/locals/expressions +; used when entering a #asm section that is not __xsafe + +__savesp .macro ; __STACK + phx + .endm + +; ************** +; main C data-stack for arguments/locals/expressions +; used when leaving a #asm section that is not __xsafe + +__loadsp .macro ; __STACK + plx + .endm + +; ************** +; main C data-stack for arguments/locals/expressions + +__modsp .macro + .if (\1 < 0) + + .if (\1 == -2) + dex + dex + .else + .if (\1 == -4) + dex + dex + dex + dex + .else + sax + clc + adc.l #\1 + sax + .endif + .endif + .if HUCC_DEBUG_SP +!overflow: bmi !overflow- + .endif + + .else + + .if (\1 == 2) + inx + inx + .else + .if (\1 == 4) + inx + inx + inx + inx + .else + sax + clc + adc.l #\1 + sax + .endif + .endif + + .endif + .endm + +; ************** +; main C data-stack for arguments/locals/expressions +; this is used to adjust the stack in a C "goto" + +__modsp_sym .macro + sax + clc + adc.l #\1 + sax + .endm + +; ************** +; main C data-stack for arguments/locals/expressions + +__push.wr .macro ; __STACK + dex + dex + .if HUCC_DEBUG_SP +!overflow: bmi !overflow- + .endif + sta.l <__stack, x + sty.h <__stack, x + .endm + +; ************** +; main C data-stack for arguments/locals/expressions + +__pop.wr .macro ; __STACK + lda.l <__stack, x + ldy.h <__stack, x + inx + inx + .endm + +; ************** +; hardware-stack used for *temporary* storage of spilled arguments + +__spush.wr .macro + phy + pha + .endm + +; ************** +; hardware-stack used for *temporary* storage of spilled arguments + +__spop.wr .macro + pla + ply + .endm + +; ************** +; hardware-stack used for *temporary* storage of spilled arguments + +__spush.ur .macro + pha + .endm + +; ************** +; hardware-stack used for *temporary* storage of spilled arguments + +__spop.ur .macro + pla + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for handling boolean tests and branching +; *************************************************************************** +; *************************************************************************** + +; ************** +; Y:A is the value to check for. + +__switch.wr .macro + sty.h __temp + ldy.l #\1 + sty.l __ptr + ldy.h #\1 + jmp do_switchw + .endm + +; ************** +; Y:A is the value to check for. + +__switch.ur .macro + ldy.l #\1 + sty.l __ptr + ldy.h #\1 + jmp do_switchb + .endm + +; ************** +; the start of a "case" statement + +__case .macro + .endm + +; ************** +; the end of the previous "case" statement if it drops through + +__endcase .macro + .endm + +; ************** +; branch to the end of a statement or to a C label + +__bra .macro + bra \1 + .endm + +; ************** +; always preceeded by a __tst.wr before peephole optimization + +__bfalse .macro + bcc \1 + .endm + +; ************** +; always preceeded by a __tst.wr before peephole optimization + +__btrue .macro + bcs \1 + .endm + +; ************** +; boolean test, always followed by a __tst.wr or __not.wr before peephole optimization +; this MUST set the Z flag for the subsequent branches! + +__cmp.wt .macro + jsr \1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if Y:A == integer-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__equ_w.wi .macro + cmp.l #\1 + bne !false+ + cpy.h #\1 + beq !+ +!false: clc +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if Y:A != integer-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__neq_w.wi .macro + sec + eor.l #\1 + bne !+ + tya + eor.h #\1 + bne !+ + clc +!: + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A < integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__slt_w.wi .macro + cmp.l #\1 ; Subtract integer from Y:A. + tya + sbc.h #\1 + bvc !+ + eor #$80 ; -ve if Y:A < integer (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A <= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sle_w.wi .macro + clc ; Subtract integer+1 from Y:A. + sbc.l #\1 + tya + sbc.h #\1 + bvc !+ + eor #$80 ; -ve if Y:A <= integer (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A > integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sgt_w.wi .macro + clc ; Subtract integer+1 from Y:A. + sbc.l #\1 + tya + sbc.h #\1 + bvc !+ + eor #$80 ; +ve if Y:A > integer (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A >= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sge_w.wi .macro + cmp.l #\1 ; Subtract integer from Y:A. + tya + sbc.h #\1 + bvc !+ + eor #$80 ; +ve if Y:A >= integer (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A < integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ult_w.wi .macro + cmp.l #\1 ; Subtract integer from Y:A. + tya + sbc.h #\1 ; CC if Y:A < integer. + ror a + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A <= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ule_w.wi .macro + clc ; Subtract integer+1 from Y:A. + sbc.l #\1 + tya + sbc.h #\1 ; CC if Y:A <= integer. + ror a + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A > integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ugt_w.wi .macro + clc ; Subtract integer+1 from Y:A. + sbc.l #\1 + tya + sbc.h #\1 ; CS if Y:A > integer. + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A >= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__uge_w.wi .macro + cmp.l #\1 ; Subtract integer from Y:A. + tya + sbc.h #\1 ; CS if Y:A >= integer. + .endm + +; ************** +; optimized boolean test +; C is true (1) if A == integer-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__equ_b.uiq .macro + cmp #\1 + beq !+ + clc +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if A != integer-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__neq_b.uiq .macro + sec + eor #\1 + bne !+ + clc +!: + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A < integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__slt_b.biq .macro + sec ; Subtract integer from A. + sbc #\1 + bvc !+ + eor #$80 ; -ve if A < integer (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A <= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sle_b.biq .macro + clc ; Subtract integer+1 from A. + sbc #\1 + bvc !+ + eor #$80 ; -ve if A <= integer (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A > integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sgt_b.biq .macro + clc ; Subtract integer+1 from A. + sbc.l #\1 + bvc !+ + eor #$80 ; +ve if A > integer (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A >= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sge_b.biq .macro + sec ; Subtract integer from A. + sbc #\1 + bvc !+ + eor #$80 ; +ve if A >= integer (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A < integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ult_b.uiq .macro + cmp #\1 ; Subtract integer from A. + ror a ; CC if A < integer. + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A <= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ule_b.uiq .macro + clc ; Subtract integer+1 from A. + sbc #\1 + ror a ; CC if A <= integer. + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A > integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ugt_b.uiq .macro + clc ; Subtract integer+1 from A. + sbc #\1 ; CS if A > integer. + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A >= integer-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__uge_b.uiq .macro + cmp #\1 ; Subtract integer from A. + ; CS if A >= integer. + .endm + +; ************** +; optimized boolean test +; C is true (1) if Y:A == memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__equ_w.wm .macro + cmp.l \1 + bne !false+ + cpy.h \1 + beq !+ +!false: clc +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if Y:A != memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__neq_w.wm .macro + sec + eor.l \1 + bne !+ + tya + eor.h \1 + bne !+ + clc +!: + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__slt_w.wm .macro + cmp.l \1 ; Subtract memory from Y:A. + tya + sbc.h \1 + bvc !+ + eor #$80 ; -ve if Y:A < memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sle_w.wm .macro + clc ; Subtract memory+1 from Y:A. + sbc.l \1 + tya + sbc.h \1 + bvc !+ + eor #$80 ; -ve if Y:A <= memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sgt_w.wm .macro + clc ; Subtract memory+1 from Y:A. + sbc.l \1 + tya + sbc.h \1 + bvc !+ + eor #$80 ; +ve if Y:A > memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sge_w.wm .macro + cmp.l \1 ; Subtract memory from Y:A. + tya + sbc.h \1 + bvc !+ + eor #$80 ; +ve if Y:A >= memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ult_w.wm .macro + cmp.l \1 ; Subtract memory from Y:A. + tya + sbc.h \1 ; CC if Y:A < memory. + ror a + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ule_w.wm .macro + clc ; Subtract memory+1 from Y:A. + sbc.l \1 + tya + sbc.h \1 ; CC if Y:A <= memory. + ror a + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ugt_w.wm .macro + clc ; Subtract memory+1 from Y:A. + sbc.l \1 + tya + sbc.h \1 ; CS if Y:A > memory. + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__uge_w.wm .macro + cmp.l \1 ; Subtract memory from Y:A. + tya + sbc.h \1 ; CS if Y:A >= memory. + .endm + +; ************** +; optimized boolean test +; C is true (1) if A == memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__equ_b.umq .macro + cmp \1 + beq !+ + clc +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if A != memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__neq_b.umq .macro + sec + eor \1 + bne !+ + clc +!: + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__slt_b.bmq .macro + sec ; Subtract memory from A. + sbc \1 + bvc !+ + eor #$80 ; -ve if A < memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sle_b.bmq .macro + clc ; Subtract memory+1 from A. + sbc \1 + bvc !+ + eor #$80 ; -ve if A <= memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sgt_b.bmq .macro + clc ; Subtract memory+1 from A. + sbc.l \1 + bvc !+ + eor #$80 ; +ve if A > memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sge_b.bmq .macro + sec ; Subtract memory from A. + sbc \1 + bvc !+ + eor #$80 ; +ve if A >= memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ult_b.umq .macro + cmp \1 ; Subtract memory from A. + ror a ; CC if A < memory. + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ule_b.umq .macro + clc ; Subtract memory+1 from A. + sbc \1 + ror a ; CC if A <= memory. + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ugt_b.umq .macro + clc ; Subtract memory+1 from A. + sbc \1 ; CS if A > memory. + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__uge_b.umq .macro + cmp \1 ; Subtract memory from A. + ; CS if A >= memory. + .endm + +; ************** +; optimized boolean test +; C is true (1) if Y:A == memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__equ_w.ws .macro + cmp.l <__stack + \1, x + bne !false+ + tya + cmp.h <__stack + \1, x + beq !+ +!false: clc +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if Y:A != memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__neq_w.ws .macro + sec + eor.l <__stack + \1, x + bne !+ + tya + eor.h <__stack + \1, x + bne !+ + clc +!: + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__slt_w.ws .macro + cmp.l <__stack + \1, x; Subtract memory from Y:A. + tya + sbc.h <__stack + \1, x + bvc !+ + eor #$80 ; -ve if Y:A < memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sle_w.ws .macro + clc ; Subtract memory+1 from Y:A. + sbc.l <__stack + \1, x + tya + sbc.h <__stack + \1, x + bvc !+ + eor #$80 ; -ve if Y:A <= memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sgt_w.ws .macro + clc ; Subtract memory+1 from Y:A. + sbc.l <__stack + \1, x + tya + sbc.h <__stack + \1, x + bvc !+ + eor #$80 ; +ve if Y:A > memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (signed word) +; C is true (1) if Y:A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sge_w.ws .macro + cmp.l <__stack + \1, x; Subtract memory from Y:A. + tya + sbc.h <__stack + \1, x + bvc !+ + eor #$80 ; +ve if Y:A >= memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ult_w.ws .macro + cmp.l <__stack + \1, x; Subtract memory from Y:A. + tya + sbc.h <__stack + \1, x; CC if Y:A < memory. + ror a + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ule_w.ws .macro + clc ; Subtract memory+1 from Y:A. + sbc.l <__stack + \1, x + tya + sbc.h <__stack + \1, x; CC if Y:A <= memory. + ror a + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ugt_w.ws .macro + clc ; Subtract memory+1 from Y:A. + sbc.l <__stack + \1, x + tya + sbc.h <__stack + \1, x; CS if Y:A > memory. + .endm + +; ************** +; optimized boolean test (unsigned word) +; C is true (1) if Y:A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__uge_w.ws .macro + cmp.l <__stack + \1, x; Subtract memory from Y:A. + tya + sbc.h <__stack + \1, x; CS if Y:A >= memory. + .endm + +; ************** +; optimized boolean test +; C is true (1) if A == memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__equ_b.usq .macro + cmp <__stack + \1, x + beq !+ + clc +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if A != memory-value, else false (0) +; this MUST set the C flag for the subsequent branches! + +__neq_b.usq .macro + sec + eor <__stack + \1, x + bne !+ + clc +!: + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__slt_b.bsq .macro + sec ; Subtract memory from A. + sbc <__stack + \1, x + bvc !+ + eor #$80 ; -ve if A < memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sle_b.bsq .macro + clc ; Subtract memory+1 from A. + sbc <__stack + \1, x + bvc !+ + eor #$80 ; -ve if A <= memory (signed). +!: asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sgt_b.bsq .macro + clc ; Subtract memory+1 from A. + sbc.l <__stack + \1, x + bvc !+ + eor #$80 ; +ve if A > memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (signed byte) +; C is true (1) if A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__sge_b.bsq .macro + sec ; Subtract memory from A. + sbc <__stack + \1, x + bvc !+ + eor #$80 ; +ve if A >= memory (signed). +!: eor #$80 + asl a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A < memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ult_b.usq .macro + cmp <__stack + \1, x; Subtract memory from A. + ror a ; CC if A < memory. + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A <= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ule_b.usq .macro + clc ; Subtract memory+1 from A. + sbc <__stack + \1, x + ror a ; CC if A <= memory. + eor #$80 + rol a + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A > memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__ugt_b.usq .macro + clc ; Subtract memory+1 from A. + sbc <__stack + \1, x; CS if A > memory. + .endm + +; ************** +; optimized boolean test (unsigned byte) +; C is true (1) if A >= memory-value, else false (0) +; this MUST set the C flag for the susequent branches! + +__uge_b.usq .macro + cmp <__stack + \1, x; Subtract memory from A. + ; CS if A >= memory. + .endm + +; ************** +; boolean test, optimized into __not.wr if used before a __tst.wr +; C is true (1) if Y:A == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.wr .macro + sty __temp + ora __temp + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.wp .macro + ldy #1 + lda [\1], y + ora [\1] + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.wm .macro + lda.l \1 + ora.h \1 + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.ws .macro ; __STACK + lda.l <__stack + \1, x + ora.h <__stack + \1, x + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.war .macro + asl a + tay + lda.l \1, y + ora.h \1, y + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.up .macro + lda [\1] + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.um .macro + lda \1 + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.us .macro ; __STACK + lda.l <__stack + \1, x + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.uar .macro + tay + lda \1, y + clc + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__not.uay .macro + lda \1, y + clc + bne !+ + sec +!: + .endm + +; ************** +; boolean test, always output immediately before a __bfalse or __btrue +; C is true (1) if Y:A != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.wr .macro + sty __temp + ora __temp + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.wp .macro + ldy #1 + lda [\1], y + ora [\1] + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.wm .macro + lda.l \1 + ora.h \1 + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.ws .macro ; __STACK + lda.l <__stack + \1, x + ora.h <__stack + \1, x + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.war .macro + asl a + tay + lda.l \1, y + ora.h \1, y + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.up .macro + lda [\1] + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.um .macro + lda \1 + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.us .macro ; __STACK + lda.l <__stack + \1, x + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.uar .macro + tay + lda \1, y + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if memory-value != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tst.uay .macro + lda \1, y + cmp #1 + .endm + +; ************** +; optimized boolean test +; C is true (1) if (Y:A & integer) == 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__nand.wi .macro + clc + .if ((\1 & $FF00) == 0) + and #\1 + .else + .if ((\1 & $00FF) == 0) + tya + and.h #\1 + .else + and.l #\1 + bne !+ + tya + and.h #\1 + .endif + .endif + bne !+ + sec +!: + .endm + +; ************** +; optimized boolean test +; C is true (1) if (Y:A & integer) != 0, else false (0) +; this MUST set the C flag for the subsequent branches! + +__tand.wi .macro + .if ((\1 & $FF00) == 0) + and #\1 + .else + .if ((\1 & $00FF) == 0) + tya + and.h #\1 + .else + and.l #\1 + bne !+ + tya + and.h #\1 + .endif + .endif +!: cmp #1 + .endm + +; ************** +; optimized boolean test +; invert C flag + +__not.cf .macro + ror a + eor #$80 + rol a + .endm + +; ************** +; convert comparison result C flag into a 16-bit Y:A boolean integer + +__bool .macro + cla + rol a + cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if Y:A == 0, else false (0) + +__boolnot.wr .macro + sty __temp + ora __temp + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.wp .macro + ldy #1 + lda [\1], y + ora [\1] + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.wm .macro + lda.l \1 + ora.h \1 + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.ws .macro ; __STACK + lda.l <__stack + \1, x + ora.h <__stack + \1, x + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.war .macro + asl a + tay + lda.l \1, y + ora.h \1, y + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.up .macro + lda [\1] + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.um .macro + lda \1 + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.us .macro ; __STACK + lda.l <__stack + \1, x + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.uar .macro + tay + lda \1, y + cla + bne !+ + inc a +!: cly + .endm + +; ************** +; optimized boolean test used before a store, not a branch +; Y:A is true (1) if memory-value == 0, else false (0) + +__boolnot.uay .macro + lda \1, y + cla + bne !+ + inc a +!: cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for loading the primary register +; *************************************************************************** +; *************************************************************************** + +; ************** + +__ld.wi .macro + .if (\?1 != ARG_ABS) + lda.l #\1 + ldy.h #\1 + .else + .if (\1 & $00FF) + lda.l #\1 + .else + cla + .endif + .if (\1 & $FF00) + ldy.h #\1 + .else + cly + .endif + .endif + .endm + +; ************** + +__ld.uiq .macro + .if (\?1 != ARG_ABS) + lda.l #\1 + .else + .if (\1 & $00FF) + lda #\1 + .else + cla + .endif + .endif + .endm + +; ************** + +__lea.s .macro ; __STACK + txa + clc + adc.l #__stack + (\1) + ldy.h #__stack + .endm + +; ************** + +__ld.wm .macro + lda.l \1 + ldy.h \1 + .endm + +; ************** + +__ld.bm .macro + lda \1 + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ld.um .macro + lda \1 + cly + .endm + +; ************** + +__ld.wmq .macro + lda.l \1 + .endm + +; ************** + +__ld.bmq .macro + lda \1 + .endm + +; ************** + +__ld.umq .macro + lda \1 + .endm + +; ************** + +__ldy.wmq .macro + ldy.l \1 + .endm + +; ************** + +__ldy.bmq .macro + ldy \1 + .endm + +; ************** + +__ldy.umq .macro + ldy \1 + .endm + +; ************** + +__ld.wp .macro + ldy #1 + lda [\1], y + tay + lda [\1] + .endm + +; ************** + +__ld.bp .macro + lda [\1] + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ld.up .macro + lda [\1] + cly + .endm + +; ************** + +__ld.war .macro + asl a + tay + lda.h \1, y + pha + lda.l \1, y + ply + .endm + +; ************** + +__ld.bar .macro + tay + lda \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ld.uar .macro + tay + lda \1, y + cly + .endm + +; ************** + +__ld.bay .macro + lda \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ld.uay .macro + lda \1, y + cly + .endm + +; ************** + +__ld.wam .macro + lda \2 + asl a + tay + lda.h \1, y + pha + lda.l \1, y + ply + .endm + +; ************** + +__ld.bam .macro + ldy \2 + lda \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ld.uam .macro + ldy \2 + lda \1, y + cly + .endm + +; ************** +; special load for when array writes are optimized +; the cpu stack is balanced with an __st.wat + +__ldp.war .macro + phx + asl a + tay + phy + lda.h \1, y + pha + lda.l \1, y + ply + .endm + +; ************** +; special load for when array writes are optimized +; the cpu stack is balanced with an __st.uat + +__ldp.bar .macro + phx + tay + phy + lda \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** +; special load for when array writes are optimized +; the cpu stack is balanced with an __st.uat + +__ldp.uar .macro + phx + tay + phy + lda \1, y + cly + .endm + +; ************** +; special load for when array writes are optimized +; the cpu stack is balanced with an __st.uat + +__ldp.bay .macro + phx + phy + lda \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** +; special load for when array writes are optimized +; the cpu stack is balanced with an __st.uat + +__ldp.uay .macro + phx + phy + lda \1, y + cly + .endm + +; ************** + +__ld.ws .macro ; __STACK + lda.l <__stack + \1, x + ldy.h <__stack + \1, x + .endm + +; ************** + +__ld.bs .macro ; __STACK + lda <__stack + \1, x + cly + bpl !+ ; signed + dey +!: + .endm + +; ************** + +__ld.us .macro ; __STACK + lda <__stack + \1, x + cly + .endm + +; ************** + +__ld.wsq .macro ; __STACK + lda.l <__stack + \1, x + .endm + +; ************** + +__ld.bsq .macro ; __STACK + lda <__stack + \1, x + .endm + +; ************** + +__ld.usq .macro ; __STACK + lda <__stack + \1, x + .endm + +; ************** + +__ldy.wsq .macro ; __STACK + ldy.l <__stack + \1, x + .endm + +; ************** + +__ldy.bsq .macro ; __STACK + ldy <__stack + \1, x + .endm + +; ************** + +__ldy.usq .macro ; __STACK + ldy <__stack + \1, x + .endm + + .if 0 + +; ************** + +__ldwa_s .macro ; __STACK + lda <__stack + \2, x + asl a + tay + lda.h \1, y + pha + lda.l \1, y + ply + .endm + +; ************** + +__ldba_s .macro ; __STACK + ldy <__stack + \2, x + lda \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__lduba_s .macro ; __STACK + ldy <__stack + \2, x + lda \1, y + cly + .endm + + .endif + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for pre- and post- increment and decrement +; *************************************************************************** +; *************************************************************************** + +; ************** + +__incld.wm .macro + inc.l \1 + bne !+ + inc.h \1 +!: lda.l \1 + ldy.h \1 + .endm + +; ************** + +__incld.bm .macro + inc \1 + lda \1 + cly + bpl !+ + dey +!: + .endm + +; ************** + +__incld.um .macro + inc \1 + lda \1 + cly + .endm + +; ************** + +__decld.wm .macro + lda.l \1 + bne !+ + dec.h \1 +!: dec a + sta.l \1 + ldy.h \1 + .endm + +; ************** + +__decld.bm .macro + dec \1 + lda \1 + cly + bpl !+ + dey +!: + .endm + +; ************** + +__decld.um .macro + dec \1 + lda \1 + cly + .endm + +; ************** + +__ldinc.wm .macro + lda.l \1 + ldy.h \1 + inc.l \1 + bne !+ + inc.h \1 +!: + .endm + +; ************** + +__ldinc.bm .macro + lda \1 + cly + bpl !+ + dey +!: inc \1 + .endm + +; ************** + +__ldinc.um .macro + lda \1 + cly + inc \1 + .endm + +; ************** + +__lddec.wm .macro + ldy.h \1 + lda.l \1 + bne !+ + dec.h \1 +!: dec.l \1 + .endm + +; ************** + +__lddec.bm .macro + lda \1 + cly + bpl !+ + dey +!: dec \1 + .endm + +; ************** + +__lddec.um .macro + lda \1 + cly + dec \1 + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.wmq .macro + inc.l \1 + bne !+ + inc.h \1 +!: + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.umq .macro + inc \1 + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.wmq .macro + lda.l \1 + bne !+ + dec.h \1 +!: dec.l \1 + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.umq .macro + dec \1 + .endm + +; ************** + +__incld.ws .macro + inc.l <__stack + \1, x + bne !+ + inc.h <__stack + \1, x +!: lda.l <__stack + \1, x + ldy.h <__stack + \1, x + .endm + +; ************** + +__incld.bs .macro + inc <__stack + \1, x + lda <__stack + \1, x + cly + bpl !+ + dey +!: + .endm + +; ************** + +__incld.us .macro + inc <__stack + \1, x + lda <__stack + \1, x + cly + .endm + +; ************** + +__decld.ws .macro + lda.l <__stack + \1, x + bne !+ + dec.h <__stack + \1, x +!: dec a + sta.l <__stack + \1, x + ldy.h <__stack + \1, x + .endm + +; ************** + +__decld.bs .macro + dec <__stack + \1, x + lda <__stack + \1, x + cly + bpl !+ + dey +!: + .endm + +; ************** + +__decld.us .macro + dec <__stack + \1, x + lda <__stack + \1, x + cly + .endm + +; ************** + +__ldinc.ws .macro + lda.l <__stack + \1, x + ldy.h <__stack + \1, x + inc.l <__stack + \1, x + bne !+ + inc.h <__stack + \1, x +!: + .endm + +; ************** + +__ldinc.bs .macro + lda <__stack + \1, x + cly + bpl !+ + dey +!: inc <__stack + \1, x + .endm + +; ************** + +__ldinc.us .macro + lda <__stack + \1, x + cly + inc <__stack + \1, x + .endm + +; ************** + +__lddec.ws .macro + ldy.h <__stack + \1, x + lda.l <__stack + \1, x + bne !+ + dec.h <__stack + \1, x +!: dec.l <__stack + \1, x + .endm + +; ************** + +__lddec.bs .macro + lda <__stack + \1, x + cly + bpl !+ + dey +!: dec <__stack + \1, x + .endm + +; ************** + +__lddec.us .macro + lda <__stack + \1, x + cly + dec <__stack + \1, x + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.wsq .macro + inc.l <__stack + \1, x + bne !+ + inc.h <__stack + \1, x +!: + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.usq .macro + inc <__stack + \1, x + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.wsq .macro + lda.l <__stack + \1, x + bne !+ + dec.h <__stack + \1, x +!: dec.l <__stack + \1, x + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.usq .macro + dec <__stack + \1, x + .endm + +; ************** + +__incld.war .macro + phx + asl a + tax + inc.l \1, x + bne !+ + inc.h \1, x +!: lda.l \1, x + ldy.h \1, x + plx + .endm + +; ************** + +__ldinc.war .macro + phx + asl a + tax + lda.l \1, x + ldy.h \1, x + inc.l \1, x + bne !+ + inc.h \1, x +!: plx + .endm + +; ************** + +__decld.war .macro + phx + asl a + tax + lda.l \1, x + bne !+ + dec.h \1, x +!: dec a + sta.l \1, x + ldy.h \1, x + plx + .endm + +; ************** + +__lddec.war .macro + phx + asl a + tax + ldy.h \1, x + lda.l \1, x + bne !+ + dec.h \1, x +!: dec.l \1, x + plx + .endm + +; ************** + +__incld.bar .macro + tay + lda \1, y + inc a + sta \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__incld.uar .macro + tay + lda \1, y + inc a + sta \1, y + cly + .endm + +; ************** + +__ldinc.bar .macro + tay + lda.l \1, y + inc a + sta.l \1, y + dec a + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ldinc.uar .macro + tay + lda.l \1, y + inc a + sta.l \1, y + dec a + cly + .endm + +; ************** + +__decld.bar .macro + tay + lda \1, y + dec a + sta \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__decld.uar .macro + tay + lda \1, y + dec a + sta \1, y + cly + .endm + +; ************** + +__lddec.bar .macro + tay + lda.l \1, y + dec a + sta.l \1, y + inc a + cly + bpl !+ + dey +!: + .endm + +; ************** + +__lddec.uar .macro + tay + lda.l \1, y + dec a + sta.l \1, y + inc a + cly + .endm + +; ************** + +__incld.bay .macro + lda \1, y + inc a + sta \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__incld.uay .macro + lda \1, y + inc a + sta \1, y + cly + .endm + +; ************** + +__ldinc.bay .macro + lda.l \1, y + inc a + sta.l \1, y + dec a + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ldinc.uay .macro + lda.l \1, y + inc a + sta.l \1, y + dec a + cly + .endm + +; ************** + +__decld.bay .macro + lda \1, y + dec a + sta \1, y + cly + bpl !+ + dey +!: + .endm + +; ************** + +__decld.uay .macro + lda \1, y + dec a + sta \1, y + cly + .endm + +; ************** + +__lddec.bay .macro + lda.l \1, y + dec a + sta.l \1, y + inc a + cly + bpl !+ + dey +!: + .endm + +; ************** + +__lddec.uay .macro + lda.l \1, y + dec a + sta.l \1, y + inc a + cly + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.warq .macro + asl a + sax + inc.l \1, x + bne !+ + inc.h \1, x +!: tax + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.uarq .macro + sax + inc \1, x + tax + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__inc.uayq .macro + sxy + inc \1, x + sxy + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.warq .macro + asl a + sax + ldy.l \1, x + bne !+ + dec.h \1, x +!: dec.l \1, x + tax + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.uarq .macro + sax + dec \1, x + tax + .endm + +; ************** +; optimized macro used when the value isn't needed in the primary register + +__dec.uayq .macro + sxy + dec \1, x + sxy + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for saving the primary register +; *************************************************************************** +; *************************************************************************** + +; ************** + +__st.wmiq .macro + .if (\?1 != ARG_ABS) + lda.l #\1 + sta.l \2 + lda.h #\1 + sta.h \2 + .else + .if (\1 & $00FF) + lda.l #\1 + sta.l \2 + .else + stz.l \2 + .endif + .if (\1 & $FF00) + lda.h #\1 + sta.h \2 + .else + stz.h \2 + .endif + .endif + .endm + +; ************** + +__st.umiq .macro + .if (\1 != 0) + lda.l #\1 + sta \2 + .else + stz \2 + .endif + .endm + +; ************** + +__st.wpi .macro + sta.l __ptr + sty.h __ptr + ldy #1 + lda.h #\1 + sta [__ptr], y + tay + lda.l #\1 + sta [__ptr] + .endm + +; ************** + +__st.upi .macro + sta.l __ptr + sty.h __ptr + lda.l #\1 + ldy.h #\1 + sta [__ptr] + .endm + +; ************** + +__st.wm .macro + sta.l \1 + sty.h \1 + .endm + +; ************** + +__st.um .macro + sta \1 + .endm + +; ************** + +__st.wp .macro + sta [\1] + pha + tya + ldy #1 + sta [\1], y + tay + pla + .endm + +; ************** + +__st.up .macro + sta [\1] + .endm + +; ************** + +__st.wpt .macro ; __STACK + sta [__stack, x] + inc.l <__stack, x + bne !+ + inc.h <__stack, x +!: say + sta [__stack, x] + say + inx + inx + .endm + +; ************** + +__st.upt .macro ; __STACK + sta [__stack, x] + inx + inx + .endm + +; ************** +; special store for when array writes are optimized +; the cpu stack is balanced with an __st.wat + +__index.wr .macro + phx + asl a + pha + .endm + +; ************** +; special store for when array writes are optimized +; the cpu stack is balanced with an __st.uat + +__index.ur .macro + phx + pha + .endm + +; ************** +; special store for when array writes are optimized +; this balances the cpu stack after an __index.wr or __ldp.war + +__st.wat .macro + plx + sta.l \1, x + say + sta.h \1, x + say + plx + .endm + +; ************** +; special store for when array writes are optimized +; this balances the cpu stack after an __index.ur or __ldp.uar + +__st.uat .macro + plx + sta \1, x + plx + .endm + +; ************** + +__st.wsiq .macro + .if (\?1 != ARG_ABS) + lda.l #\1 + sta.l <__stack + \2, x + lda.h #\1 + sta.h <__stack + \2, x + .else + .if (\1 & $00FF) + lda.l #\1 + sta.l <__stack + \2, x + .else + stz.l <__stack + \2, x + .endif + .if (\1 & $FF00) + lda.h #\1 + sta.h <__stack + \2, x + .else + stz.h <__stack + \2, x + .endif + .endif + .endm + +; ************** + +__st.usiq .macro + .if (\1 != 0) + lda.l #\1 + sta <__stack + \2, x + .else + stz <__stack + \2, x + .endif + .endm + +; ************** + +__st.ws .macro ; __STACK + sta.l <__stack + \1, x + sty.h <__stack + \1, x + .endm + +; ************** + +__st.us .macro ; __STACK + sta <__stack + \1, x + .endm + +; ************** + +__st.was .macro ; __STACK + phy + pha + lda <__stack + \2, x + asl a + say + sta.h \1, y + pla + sta.l \1, y + ply + .endm + +; ************** + +__st.uas .macro ; __STACK + phy + ldy <__stack + \2, x + sta \1, y + ply + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for extending the primary register +; *************************************************************************** +; *************************************************************************** + +; ************** + +__ext.br .macro + tay + cly + bpl !+ + dey +!: + .endm + +; ************** + +__ext.ur .macro + cly + .endm + + + +; *************************************************************************** +; *************************************************************************** +; i-codes for math with the primary register +; *************************************************************************** +; *************************************************************************** + +; ************** + +__com.wr .macro + eor #$FF + say + eor #$FF + say + .endm + +; ************** + +__neg.wr .macro + sec + eor #$FF + adc #0 + say + eor #$FF + adc #0 + say + .endm + +; ************** + +__add.wt .macro ; __STACK + clc + adc.l <__stack, x + say + adc.h <__stack, x + say + inx + inx + .endm + +; ************** + +__add.wi .macro + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc a + bne !+ + iny +!: + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + clc + adc.l #\1 + bcc !+ + iny +!: + .else + clc + adc.l #\1 + say + adc.h #\1 + say + .endif + .endif + .endm + +; ************** + +__add.wm .macro + clc + adc.l \1 + say + adc.h \1 + say + .endm + +; ************** + +__add.um .macro + clc + adc \1 + bcc !+ + iny +!: + .endm + +; ************** + +__add.ws .macro ; __STACK + clc + adc.l <__stack + \1, x + say + adc.h <__stack + \1, x + say + .endm + +; ************** + +__add.us .macro ; __STACK + clc + adc <__stack + \1, x + bcc !+ + iny +!: + .endm + +; ************** + +__sub.wt .macro ; __STACK + sec + eor #$FF + adc.l <__stack, x + say + eor #$FF + adc.h <__stack, x + say + inx + inx + .endm + +; ************** + +__sub.wi .macro + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + sec + sbc.l #\1 + bcs !+ + dey +!: + .else + sec + sbc.l #\1 + say + sbc.h #\1 + say + .endif + .endm + +; ************** + +__sub.wm .macro + sec + sbc.l \1 + say + sbc.h \1 + say + .endm + +; ************** + +__sub.um .macro + sec + sbc \1 + bcs !+ + dey +!: + .endm + +; ************** + +__isub.wi .macro ; __STACK + sec + eor #$FF + adc.l #\1 + say + eor #$FF + adc.h #\1 + say + .endm + +; ************** + +__and.wt .macro ; __STACK + and.l <__stack, x + say + and.h <__stack, x + say + inx + inx + .endm + +; ************** + +__and.wi .macro + .if (\?1 != ARG_ABS) + and.l #\1 + say + and.h #\1 + say + .else + .if ((\1 >= 0) && (\1 < 256)) + and #\1 + cly + .else + .if (\1 & 255) + and.l #\1 + say + and.h #\1 + say + .else + tya + and.h #\1 + tay + cla + .endif + .endif + .endif + .endm + +; ************** + +__and.uiq .macro + and #\1 + .endm + +; ************** + +__and.wm .macro + and.l \1 + say + and.h \1 + say + .endm + +; ************** + +__and.um .macro + and \1 + cly + .endm + +; ************** + +__eor.wt .macro ; __STACK + eor.l <__stack, x + say + eor.h <__stack, x + say + inx + inx + .endm + +; ************** + +__eor.wi .macro + .if ((\1 >= 0) && (\1 < 256)) + eor #\1 + .else + .if (\1 & 255) + eor.l #\1 + say + eor.h #\1 + say + .else + say + eor.h #\1 + say + .endif + .endif + .endm + +; ************** + +__eor.wm .macro + eor.l \1 + say + eor.h \1 + say + .endm + +; ************** + +__eor.um .macro + eor \1 + .endm + +; ************** + +__or.wt .macro ; __STACK + ora.l <__stack, x + say + ora.h <__stack, x + say + inx + inx + .endm + +; ************** + +__or.wi .macro + .if ((\1 >= 0) && (\1 < 256)) + ora #\1 + .else + .if (\1 & 255) + ora.l #\1 + say + ora.h #\1 + say + .else + say + ora.h #\1 + say + .endif + .endif + .endm + +; ************** + +__or.wm .macro + ora.l \1 + say + ora.h \1 + say + .endm + +; ************** + +__or.um .macro + ora \1 + .endm + +; ************** +; N.B. Used when calculating a pointer into a word array. + +__double .macro + asl.l <__stack, x + rol.h <__stack, x + .endm + +; ************** + +__asl.wt .macro + jsr aslw + .endm + +; ************** + +__asl.wi .macro + .if (\1 = 1) + asl a + say + rol a + say + .else + .if (\1 = 2) + asl a + say + rol a + say + asl a + say + rol a + say + .else + .if (\1 < 5) + sty __temp + jsr aslw\1 + .else + .if (\1 < 7) + sta __temp + tya + lsr a + jsr aslw\1 + and.l #$FF << \1 + .else + .if (\1 = 7) + say + lsr a + say + ror a + say + ror a + and #$80 + .else + .if (\1 = 8) + tay + cla + .else + .if (\1 < 16) + jsr aslw\1 + .else + cla + cly + .endif + .endif + .endif + .endif + .endif + .endif + .endif + .endm + +; ************** + +__asl.wr .macro + asl a + say + rol a + say + .endm + +; ************** + +__asr.wt .macro + jsr asrw + .endm + +; ************** + +__asr.wi .macro + .if (\1 = 1) + cpy #$80 + say + ror a + say + ror a + .else + .if (\1 = 2) + cpy #$80 + say + ror a + say + ror a + cpy #$80 + say + ror a + say + ror a + .else + .if (\1 < 8) + sty __temp + jsr asrw\1 + .else + .if (\1 = 8) + tya + cly + bpl !+ + dey +!: + .else + .if (\1 < 16) + tya + jsr asrw\1 + .else + cpy #$80 + cly + bcc !+ + dey +!: tya + .endif + .endif + .endif + .endif + .endif + .endm + +; ************** + +__lsr.wt .macro + jsr lsrw + .endm + +; ************** + +__lsr.wi .macro + .if (\1 = 1) + say + lsr a + say + ror a + .else + .if (\1 = 2) + say + lsr a + say + ror a + say + lsr a + say + ror a + .else + .if (\1 < 8) + sty __temp + jsr lsrw\1 + .else + .if (\1 = 8) + tya + cly + bmi !+ + dey +!: + .else + .if (\1 < 16) + tya + jsr lsrw\1 + .else + cly + bcc !+ + dey +!: tya + .endif + .endif + .endif + .endif + .endif + .endm + +; ************** + +__lsr.uiq .macro + .if (\1 < 8) + .if (\1 >= 1) + lsr a + .endif + .if (\1 >= 2) + lsr a + .endif + .if (\1 >= 3) + lsr a + .endif + .if (\1 >= 4) + lsr a + .endif + .if (\1 >= 5) + lsr a + .endif + .if (\1 >= 6) + lsr a + .endif + .if (\1 >= 7) + lsr a + .endif + .else + cla + .endif + .endm + +; ************** + +__mul.wt .macro + jsr mulw + .endm + +; ************** + +__mul.wi .macro + .if (\1 = 2) + __asl.wr + .else + .if (\1 = 3) + sta.l __temp + sty.h __temp + __asl.wr + __add.wm __temp + .else + .if (\1 = 4) + __asl.wr + __asl.wr + .else + .if (\1 = 5) + sta.l __temp + sty.h __temp + __asl.wr + __asl.wr + __add.wm __temp + .else + .if (\1 = 6) + __asl.wr + sta.l __temp + sty.h __temp + __asl.wr + __add.wm __temp + .else + .if (\1 = 7) + sta.l __temp + sty.h __temp + __asl.wr + __asl.wr + __asl.wr + __sub.wm __temp + .else + .if (\1 = 8) + __asl.wr + __asl.wr + __asl.wr + .else + .if (\1 = 9) + sta.l __temp + sty.h __temp + __asl.wr + __asl.wr + __asl.wr + __add.wm __temp + .else + .if (\1 = 10) + __asl.wr + sta.l __temp + sty.h __temp + __asl.wr + __asl.wr + __add.wm __temp + .else + __push.wr + __ld.wi \1 + jsr mulw + .endif + .endif + .endif + .endif + .endif + .endif + .endif + .endif + .endif + .endm + +; ************** + +__sdiv.wt .macro + jsr sdivw + .endm + +; ************** + +__sdiv.wi .macro + phx + ldx.l #\1 + stx.l > 16 + sta.l <\3 + lda.h #(\1) >> 16 + sta.h <\3 + lda.l #\1 + sta.l <\2 + ldy.h #\1 + sty.h <\2 + .endm + +; ************** + +__ldd_w .macro + lda.l \1 + ldy.h \1 + sta.l <\2 + sty.h <\2 + stz.l <\3 + stz.h <\3 + .endm + +; ************** + +__ldd_b .macro + lda \1 + cly + sta.l <\2 + stz.h <\2 + stz.l <\3 + stz.h <\3 + .endm + +; ************** + +__ldd_s_w .macro ; __STACK + lda.l <__stack + \1, x + ldy.h <__stack + \1, x + sta.l <\2 + sty.h <\2 + stz.l <\3 + stz.h <\3 + .endm +; ************** + +__ldd_s_b .macro ; __STACK + lda.l <__stack + \1, x + cly + bpl !+ + dey +!: sta.l <\2 + sty.h <\2 + stz.l <\3 + stz.h <\3 + .endm + + + +; *************************************************************************** +; *************************************************************************** +; subroutines for comparison tests with signed and unsigned words +; *************************************************************************** +; *************************************************************************** + +; ************** +; C is true (1) if stacked-value == Y:A, else false (0) + +equ_w: cmp.l <__stack, x + bne return_false + tya + cmp.h <__stack, x + bne return_false +; bra return_true + +; ************** +; boolean result, this MUST set the C flag for the subsequent branches! + +return_true: inx + inx + sec + rts + +; ************** +; C is true (1) if stacked-value != Y:A, else false (0) + +neq_w: cmp.l <__stack, x + bne return_true + tya + cmp.h <__stack, x + bne return_true +; bra return_false + +; ************** +; boolean result, this MUST set the C flagy for the subsequent branches! + +return_false: inx + inx + clc + rts + +; ************** +; C is true (1) if stacked-value < Y:A, else false (0) + +slt_w: clc ; Subtract memory+1 from Y:A. + sbc.l <__stack, x + tya + sbc.h <__stack, x + bvc !+ + eor #$80 +!: bpl return_true ; +ve if Y:A > memory (signed). + bra return_false ; -ve if Y:A <= memory (signed). + +; ************** +; C is true (1) if stacked-value <= Y:A, else false (0) + +sle_w: cmp.l <__stack, x ; Subtract memory from Y:A. + tya + sbc.h <__stack, x + bvc !+ + eor #$80 +!: bpl return_true ; +ve if Y:A >= memory (signed). + bra return_false ; -ve if Y:A < memory (signed). + +; ************** +; C is true (1) if stacked-value > Y:A, else false (0) + +sgt_w: cmp.l <__stack, x ; Subtract memory from Y:A. + tya + sbc.h <__stack, x + bvc !+ + eor #$80 +!: bmi return_true ; -ve if Y:A < memory (signed). + bra return_false ; +ve if Y:A >= memory (signed). + +; ************** +; C is true (1) if stacked-value >= Y:A, else false (0) + +sge_w: clc ; Subtract memory+1 from Y:A. + sbc.l <__stack, x + tya + sbc.h <__stack, x + bvc !+ + eor #$80 +!: bmi return_true ; -ve if Y:A <= memory (signed). + bra return_false ; +ve if Y:A > memory (signed). + +; ************** +; C is true (1) if stacked-value < Y:A, else false (0) + +ult_w: clc ; Subtract memory+1 from Y:A. + sbc.l <__stack, x + tya + sbc.h <__stack, x + bcs return_true ; CS if Y:A > memory. + bra return_false + +; ************** +; C is true (1) if stacked-value <= Y:A, else false (0) + +ule_w: cmp.l <__stack, x ; Subtract memory from Y:A. + tya + sbc.h <__stack, x + bcs return_true ; CS if Y:A >= memory. + bra return_false + +; ************** +; C is true (1) if stacked-value > Y:A, else false (0) + +ugt_w: cmp.l <__stack, x ; Subtract memory from Y:A. + tya + sbc.h <__stack, x + bcc return_true ; CC if Y:A < memory. + bra return_false + +; ************** +; C is true (1) if stacked-value >= Y:A, else false (0) + +uge_w: clc ; Subtract memory+1 from Y:A. + sbc.l <__stack, x + tya + sbc.h <__stack, x + bcc return_true ; CC if Y:A <= memory. + bra return_false + + + +; *************************************************************************** +; *************************************************************************** +; subroutines for logical and arithmetic shifts by a constant amount +; *************************************************************************** +; *************************************************************************** + +; ************** +; Y:A = Y:A << const + +aslw15: asl a +aslw14: asl a +aslw13: asl a +aslw12: asl a +aslw11: asl a +aslw10: asl a +aslw9: asl a +aslw8: tay + cla + rts + + .if 1 +aslw5: ror <__temp + ror a +aslw6: ror <__temp + ror a +aslw7: ror <__temp + ror a + ldy <__temp + rts + .else +aslw7: asl a + rol <__temp +aslw6: asl a + rol <__temp +aslw5: asl a + rol <__temp + .endif +aslw4: asl a + rol <__temp +aslw3: asl a + rol <__temp +aslw2: asl a + rol <__temp +aslw1: asl a + rol <__temp +aslw0: ldy <__temp + rts + +; ************** +; Y:A = Y:A >> const + +asrw15: cmp #$80 + ror a +asrw14: cmp #$80 + ror a +asrw13: cmp #$80 + ror a +asrw12: cmp #$80 + ror a +asrw11: cmp #$80 + ror a +asrw10: cmp #$80 + ror a +asrw9: cmp #$80 + ror a +asrw8: cmp #$80 + cly + bcc !+ + dey +!: rts + +asrw7: cpy #$80 + ror <__temp + ror a +asrw6: cpy #$80 + ror <__temp + ror a +asrw5: cpy #$80 + ror <__temp + ror a +asrw4: cpy #$80 + ror <__temp + ror a +asrw3: cpy #$80 + ror <__temp + ror a +asrw2: cpy #$80 + ror <__temp + ror a +asrw1: cpy #$80 + ror <__temp + ror a +asrw0: ldy <__temp + rts + +; ************** +; Y:A = Y:A >> const + +lsrw15: lsr a +lsrw14: lsr a +lsrw13: lsr a +lsrw12: lsr a +lsrw11: lsr a +lsrw10: lsr a +lsrw9: lsr a +lsrw8: cly + rts + +lsrw7: lsr <__temp + ror a +lsrw6: lsr <__temp + ror a +lsrw5: lsr <__temp + ror a +lsrw4: lsr <__temp + ror a +lsrw3: lsr <__temp + ror a +lsrw2: lsr <__temp + ror a +lsrw1: lsr <__temp + ror a +lsrw0: ldy <__temp + rts + + + +; *************************************************************************** +; *************************************************************************** +; subroutines for logical and arithmetic shifts by a variable amount +; *************************************************************************** +; *************************************************************************** + +; ************** +; Y:A = stacked-value << Y:A + +aslw: pha ; preserve count + lda.h <__stack, x + sta <__temp + lda.l <__stack, x + inx + inx + ply ; restore count + beq .done + cpy #16 + bcs .zero +.loop: asl a + rol <__temp + dey + bne .loop +.done: ldy <__temp + rts +.zero: cla + cly + rts + +; ************** +; Y:A = stacked-value >> Y:A + +asrw: pha ; preserve count + lda.h <__stack, x + bpl asrw_positive +asrw_negative: sta <__temp + lda.l <__stack, x + inx + inx + ply ; restore count + beq .done + cpy #16 + bcs .sign +.loop: sec + ror <__temp + ror a + dey + bne .loop +.done: ldy <__temp + rts + +.sign: lda #$FF + tay + rts + +; ************** +; Y:A = stacked-value >> Y:A + +lsrw: pha ; preserve count + lda.h <__stack, x +asrw_positive: sta <__temp + lda.l <__stack, x + inx + inx + ply ; restore count + beq .done + cpy #16 + bcs .zero +.loop: lsr <__temp + ror a + dey + bne .loop +.done: ldy <__temp + rts + +.zero: cla + cly + rts + + + +; *************************************************************************** +; *************************************************************************** +; subroutines for signed and unsigned multiplication and division +; *************************************************************************** +; *************************************************************************** + +; ************** +; Y:A = stacked-value * Y:A +; +; N.B. signed and unsigned multiply only differ in the top 16 of the 32bits! + +mulw: sta.l val3, val2, val1, .BAT_SIZE ; Size of BAT in words. + sta <_bl + + call clear_vram_vdc ; Clear VRAM. + .if SUPPORT_SGX + call clear_vram_sgx + .endif + + lda #<.mode_256x224 ; Disable BKG & SPR layers but + sta.l <_bp ; enable RCR & VBLANK IRQ. + lda #>.mode_256x224 + sta.h <_bp + + .if SUPPORT_SGX + call sgx_detect ; Are we really on an SGX? + bcc !+ + ldy #^.mode_256x224 ; Set SGX 1st, with no VBL. + call set_mode_sgx + + ldy #VDC_MWR_64x32 >> 4 ; HuCC sets up various vars + call screen_size_sgx ; related to the BAT size. + .endif +!: ldy #^.mode_256x224 ; Set VDC 2nd, VBL allowed. + call set_mode_vdc + + lda #VDC_MWR_64x32 >> 4 ; HuCC sets up various vars + sta <_al ; related to the BAT size. + call screen_size_vdc + + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue VBL. + plp ; Restore interrupts. + + call wait_vsync ; Wait for the next VBLANK. + + plx ; Restore X (aka __sp). + + leave ; All done, phew! + + ; A standard 256x224 screen with overscan. + +.mode_256x224: db $80 ; VCE Control Register. + db VCE_CR_5MHz + XRES_SOFT ; Video Clock + Artifact Reduction + + db VDC_MWR ; Memory-access Width Register + dw VDC_MWR_64x32 + VDC_MWR_1CYCLE + db VDC_HSR ; Horizontal Sync Register + dw VDC_HSR_256 + db VDC_HDR ; Horizontal Display Register + dw VDC_HDR_256 + db VDC_VPR ; Vertical Sync Register + dw VDC_VPR_224 + db VDC_VDW ; Vertical Display Register + dw VDC_VDW_224 + db VDC_VCR ; Vertical Display END position Register + dw VDC_VCR_224 + db VDC_DCR ; DMA Control Register + dw $0010 ; Enable automatic VRAM->SATB + db VDC_DVSSR ; VRAM->SATB address $7F00 + dw .SAT_ADDR + db VDC_BXR ; Background X-Scroll Register + dw $0000 + db VDC_BYR ; Background Y-Scroll Register + dw $0000 + db VDC_RCR ; Raster Counter Register + dw $0000 ; Never occurs! + db VDC_CR ; Control Register + dw $00CC ; Enable VSYNC & RCR IRQ, BG & SPR + db 0 + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe set_352x224( void ); + +_set_352x224 .proc + +.BAT_SIZE = 64 * 32 +.CHR_0x20 = .BAT_SIZE / 16 ; 1st tile # after the BAT. +.SAT_ADDR = $7F00 ; SAT takes 16 tiles of VRAM. + + phx ; Preserve X (aka __sp). + + php ; Disable interrupts. + sei + + call clear_vce ; Clear all palettes. + + lda.l #.CHR_0x20 ; Tile # of ' ' CHR. + sta.l <_ax + lda.h #.CHR_0x20 + sta.h <_ax + + lda #>.BAT_SIZE ; Size of BAT in words. + sta <_bl + + call clear_vram_vdc ; Clear VRAM. + .if SUPPORT_SGX + call clear_vram_sgx + .endif + + lda #<.mode_352x224 ; Disable BKG & SPR layers but + sta.l <_bp ; enable RCR & VBLANK IRQ. + lda #>.mode_352x224 + sta.h <_bp + + .if SUPPORT_SGX + call sgx_detect ; Are we really on an SGX? + bcc !+ + ldy #^.mode_352x224 ; Set SGX 1st, with no VBL. + call set_mode_sgx + + ldy #VDC_MWR_64x32 >> 4 ; HuCC sets up various vars + call screen_size_sgx ; related to the BAT size. + .endif +!: ldy #^.mode_352x224 ; Set VDC 2nd, VBL allowed. + call set_mode_vdc + + lda #VDC_MWR_64x32 >> 4 ; HuCC sets up various vars + sta <_al ; related to the BAT size. + call screen_size_vdc + + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue RCR/VBL. + plp ; Restore interrupts. + + call wait_vsync ; Wait for the next VBLANK. + + plx ; Restore X (aka __sp). + + leave ; All done, phew! + + ; A standard 352x224 screen with overscan. + +.mode_352x224: db $80 ; VCE Control Register. + db VCE_CR_7MHz + XRES_SOFT ; Video Clock + Artifact Reduction + + db VDC_MWR ; Memory-access Width Register + dw VDC_MWR_64x32 + VDC_MWR_1CYCLE + db VDC_HSR ; Horizontal Sync Register + dw VDC_HSR_352 + db VDC_HDR ; Horizontal Display Register + dw VDC_HDR_352 + db VDC_VPR ; Vertical Sync Register + dw VDC_VPR_224 + db VDC_VDW ; Vertical Display Register + dw VDC_VDW_224 + db VDC_VCR ; Vertical Display END position Register + dw VDC_VCR_224 + db VDC_DCR ; DMA Control Register + dw $0010 ; Enable automatic VRAM->SATB + db VDC_DVSSR ; VRAM->SATB address $7F00 + dw .SAT_ADDR + db VDC_BXR ; Background X-Scroll Register + dw $0000 + db VDC_BYR ; Background Y-Scroll Register + dw $0000 + db VDC_RCR ; Raster Counter Register + dw $0000 ; Never occurs! + db VDC_CR ; Control Register + dw $00CC ; Enable VSYNC & RCR IRQ, BG & SPR + db 0 + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe set_496x224( void ); + +_set_496x224 .proc + +.BAT_SIZE = 64 * 32 +.CHR_0x20 = .BAT_SIZE / 16 ; 1st tile # after the BAT. +.SAT_ADDR = $7F00 ; SAT takes 16 tiles of VRAM. + + phx ; Preserve X (aka __sp). + + php ; Disable interrupts. + sei + + call clear_vce ; Clear all palettes. + + lda.l #.CHR_0x20 ; Tile # of ' ' CHR. + sta.l <_ax + lda.h #.CHR_0x20 + sta.h <_ax + + lda #>.BAT_SIZE ; Size of BAT in words. + sta <_bl + + call clear_vram_vdc ; Clear VRAM. + .if SUPPORT_SGX + call clear_vram_sgx + .endif + + lda #<.mode_496x224 ; Disable BKG & SPR layers but + sta.l <_bp ; enable RCR & VBLANK IRQ. + lda #>.mode_496x224 + sta.h <_bp + + .if SUPPORT_SGX + call sgx_detect ; Are we really on an SGX? + bcc !+ + ldy #^.mode_496x224 ; Set SGX 1st, with no VBL. + call set_mode_sgx + + ldy #VDC_MWR_64x32 >> 4 ; HuCC sets up various vars + call screen_size_sgx ; related to the BAT size. + .endif +!: ldy #^.mode_496x224 ; Set VDC 2nd, VBL allowed. + call set_mode_vdc + + lda #VDC_MWR_64x32 >> 4 ; HuCC sets up various vars + sta <_al ; related to the BAT size. + call screen_size_vdc + + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue RCR/VBL. + plp ; Restore interrupts. + + call wait_vsync ; Wait for the next VBLANK. + + plx ; Restore X (aka __sp). + + leave ; All done, phew! + + ; A standard 496x224 screen with overscan. + +.mode_496x224: db $80 ; VCE Control Register. + db VCE_CR_10MHz + XRES_SOFT; Video Clock + Artifact Reduction + + db VDC_MWR ; Memory-access Width Register + dw VDC_MWR_64x32 + VDC_MWR_2CYCLE + db VDC_HSR ; Horizontal Sync Register + dw VDC_HSR_496 + db VDC_HDR ; Horizontal Display Register + dw VDC_HDR_496 + db VDC_VPR ; Vertical Sync Register + dw VDC_VPR_224 + db VDC_VDW ; Vertical Display Register + dw VDC_VDW_224 + db VDC_VCR ; Vertical Display END position Register + dw VDC_VCR_224 + db VDC_DCR ; DMA Control Register + dw $0010 ; Enable automatic VRAM->SATB + db VDC_DVSSR ; VRAM->SATB address $7F00 + dw .SAT_ADDR + db VDC_BXR ; Background X-Scroll Register + dw $0000 + db VDC_BYR ; Background Y-Scroll Register + dw $0000 + db VDC_RCR ; Raster Counter Register + dw $0000 ; Never occurs! + db VDC_CR ; Control Register + dw $00CC ; Enable VSYNC & RCR IRQ, BG & SPR + db 0 + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe set_screen_size( unsigned char value<_al> ); +; void __fastcall __xsafe sgx_set_screen_size( unsigned char value<_al> ); +; +; screen_size_sgx +; screen_size_vdc +; +; set bg map virtual size +; +; IN : X:Y = new size (0-7) +; +; (VDC_MWR_32x32 >> 4) or in HuC, SCR_SIZE_32x32 +; (VDC_MWR_32x64 >> 4) or in HuC, SCR_SIZE_32x64 +; (VDC_MWR_64x32 >> 4) or in HuC, SCR_SIZE_64x32 +; (VDC_MWR_64x64 >> 4) or in HuC, SCR_SIZE_64x64 +; (VDC_MWR_128x32 >> 4) or in HuC, SCR_SIZE_128x32 +; (VDC_MWR_128x64 >> 4) or in HuC, SCR_SIZE_128x64 + +huc_screen_size .procgroup + + .if SUPPORT_SGX +screen_size_sgx .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref screen_size_vdc + .endp + .endif + +screen_size_vdc .proc + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + lda <_al ; Get screen size value. + and #7 ; Sanitize screen size value. + tay + asl a ; Put it in bits 4..6. + asl a + asl a + asl a + sta <__temp + + lda .width, y + sta vdc_bat_width, x + dec a + sta vdc_bat_x_mask, x + + lda .height, y + sta vdc_bat_height, x + dec a + sta vdc_bat_y_mask, x + + lda .limit, y + sta vdc_bat_limit, x + + lda .increment, y ; Put the VRAM increment for a + sta $03FF), (>$07FF), (>$0FFF), (>$1FFF) + +; Initialized by set_tile_data() +vdc_tile_type ds 1 ; HuC sets 8 or 16 +vdc_num_tiles ds 2 ; HuC sets 0..255, 0==256. +vdc_tile_addr ds 2 ; Where the TILE data is in ROM. +vdc_tile_bank ds 1 +vdc_attr_bank ds 1 ; Where the ATTR data is in ROM. +vdc_attr_addr ds 2 + +; Initialized by load_tile() or set_tile_address() +vdc_tile_base ds 2 ; Where the TILE data is in VRAM / 16. + + .if SUPPORT_SGX + +; ************** +; 16-bytes of SGX HuC BAT and TILE info. +; +; N.B. MUST be 16-bytes after the VDC versions to use SGX_VDC_OFFSET. +; +; N.B. Declared inside this .proc so that they can be stripped if unused. + +; Initialized by sgx_set_screen_size() +sgx_bat_width: ds 1 ; $20, $40, $80 +sgx_bat_height: ds 1 ; $20, $40 +sgx_bat_x_mask: ds 1 ; $1F, $3F, $7F +sgx_bat_y_mask: ds 1 ; $1F, $3F +sgx_bat_limit: ds 1 ; (>$03FF), (>$07FF), (>$0FFF), (>$1FFF) + +; Initialized by sgx_set_tile_data() +sgx_tile_type ds 1 ; HuC sets 8 or 16 +sgx_num_tiles ds 2 ; HuC sets 0..255, 0==256. +sgx_tile_addr ds 2 ; Where the TILE data is in ROM. +sgx_tile_bank ds 1 +sgx_attr_bank ds 1 ; Where the ATTR data is in ROM. +sgx_attr_addr ds 2 + +; Initialized by sgx_load_tile() or sgx_set_tile_address() +sgx_tile_base ds 2 ; Where the TILE data is in VRAM / 16. + + .endif + + .code + + .endp + + .endprocgroup ; huc_screen_size + + .alias _set_screen_size.1 = screen_size_vdc + .alias _sgx_set_screen_size.1 = screen_size_sgx + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe _macro set_xres( unsigned int x_pixels<_ax> ); +; void __fastcall __xsafe _macro sgx_set_xres( unsigned int x_pixels<_ax> ); +; +; void __fastcall __xsafe set_xres( unsigned int x_pixels<_ax>, unsigned char blur_flag<_bl> ); +; void __fastcall __xsafe sgx_set_xres( unsigned int x_pixels<_ax>, unsigned char blur_flag<_bl> ); +; +; blur_flag = XRES_SOFT (default if not specified), XRES_SHARP or XRES_KEEP + +set_xres_group .procgroup ; These routines share code! + + .if SUPPORT_SGX + +_sgx_set_xres.2 .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .endp + .endif + +_set_xres.2 .proc + +.hdw = _bh +.hds = _al +.hde = _ah + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + lda.l <_ax ; Convert x pixel resolution to + lsr.h <_ax ; tiles. + ror a + lsr.h <_ax + ror a + lsr.h <_ax + ror a + dec a ; HDW = width - 1 + sta <.hdw + + ldy <_bl ; Keep the current VCE clock? + bpl .calc_speed + +.read_speed: tay ; Read the current VCE clock + lda vce_cr ; speed from the shadow. + and #3 + say + bra .got_speed + +.calc_speed: cly ; Calculate VCE clock speed. + cmp #36 ; Is resolution <= 288? + bcc .got_speed + iny + cmp #48 ; Is resolution <= 384? + bcc .got_speed + iny + +.got_speed: lda .hds_tbl, y + clc ; Subtract hdw+1 + sbc <.hdw + lsr a + sta <.hds + + lda .hde_tbl, y + clc ; Subtract hdw+1 + sbc <.hdw + sbc <.hds + sta <.hde + + php ; Disable interrupts. + sei + + tya ; 0=5MHz, 1=7MHz, 2=10MHz. + ora <_bl ; SOFT setting. + bmi .set_hsr_hdr ; Keep the current VCE clock? + + sta vce_cr ; No SGX shadow for this! + sta VCE_CR ; Set the VCE clock speed. + and #2 ; Is this VCE_CR_10MHz? + beq .mwr_shadow ; VDC_MWR_1CYCLE when <= 7MHz. + lda #VDC_MWR_2CYCLE ; VDC_MWR_2CYCLE when == 10MHz. +.mwr_shadow: sta vdc_mwr ; No SGX shadow for this! + +.set_hsr_hdr: lda #VDC_HSR ; Set the VDC's HSR register. + sta ); +; void __fastcall sgx_set_tile_address( unsigned int vram ); + + .if SUPPORT_SGX +set_tiles_sgx: ldx #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + .endif + +set_tiles_vdc: clx ; Offset to PCE VDC. + +set_tile_base: sty <__temp ; Set TILE base = (VRAM / 16). + lsr <__temp + ror a + lsr <__temp + ror a + lsr <__temp + ror a + lsr <__temp + ror a + sta.l vdc_tile_base, x + lda <__temp + sta.h vdc_tile_base, x + rts + + .alias _set_tile_address.1 = set_tiles_vdc + .alias _sgx_set_tile_address.1 = set_tiles_sgx + + .alias _set_map_tile_base.1 = set_tiles_vdc + .alias _sgx_set_map_tile_base.1= set_tiles_sgx + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe set_tile_data( unsigned char *tile_ex<_di> ); +; void __fastcall __xsafe __nop set_tile_data( unsigned char far *map, unsigned char nb_tile, unsigned char far *ptable, unsigned char type ); +; void __fastcall __xsafe __nop sgx_set_tile_data( unsigned char far *map, unsigned char nb_tile, unsigned char far *ptable, unsigned char type ); +; +; tile, tile base index +; nb_tile, number of tile +; ptable, tile palette table address +; type, tile type (8 or 16) + +_set_tile_data.1: + cly + lda [_di], y + sta.l vdc_num_tiles + iny + iny + lda [_di], y + sta vdc_tile_type + iny + iny + lda [_di], y + sta vdc_tile_bank + iny + iny + lda [_di], y + sta.l vdc_tile_addr + iny + lda [_di], y + sta.h vdc_tile_addr + iny + lda [_di], y + sta.l vdc_attr_addr + iny + lda [_di], y + sta.h vdc_attr_addr + lda #CONST_BANK + _bank_base + sta vdc_attr_bank + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; HuC VRAM Functions +; +; *************************************************************************** +; *************************************************************************** + + +load_vram_group .procgroup ; These routines share code! + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_tile( unsigned int vram<_di> ); +; void __fastcall __xsafe sgx_load_tile( unsigned int vram<_di> ); + + .if SUPPORT_SGX + .proc _sgx_load_tile.1 + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _load_tile.1 + .endp + .endif + + .proc _load_tile.1 + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + lda.l <_di ; Set VRAM address. + ldy.h <_di + jsr set_tile_base ; Set TILE number (VRAM / 16). + + lda.l vdc_tile_addr, x + sta.l <_bp + lda.h vdc_tile_addr, x + sta.h <_bp + lda vdc_tile_bank, x + sta <_bp_bank + + lda.l vdc_num_tiles, x ; #tiles lo-byte (0 == 256). + stz.l <_ax + cmp #1 ; CC if 0, CS if NZ. +!: ror a + eor #$80 ; Invert top bit. + ror.l <_ax + lsr a + ror.l <_ax + + ldy vdc_tile_type, x ; Set C if using 8x8. + cpy #16 + beq !+ + lsr a + ror.l <_ax + lsr a + ror.l <_ax + +!: sta.h <_ax + bra huc_load_vram ; This is __xsafe! + + .ref _load_vram.3 + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_vram( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_words<_ax> ); +; void __fastcall __xsafe sgx_load_vram( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_words<_ax> ); +; +; load_vram_sgx - copy a block of memory to VRAM +; load_vram_vdc - copy a block of memory to VRAM +; +; _bp = BAT memory location +; _bp_bank = BAT bank +; _di = VRAM base address +; _ax = nb of words to copy +; ---- +; N.B. BAT data *must* be word-aligned! + + .ifndef VRAM_XFER_SIZE +VRAM_XFER_SIZE = 16 + .endif + + .if SUPPORT_SGX + .proc _sgx_load_vram.3 + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _load_vram.3 + .endp + .endif + + .proc _load_vram.3 + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + +huc_load_vram: tma3 + pha + tma4 + pha + + ldy <_bp_bank + jsr set_bp_to_mpr34 ; Map data to MPR3 & MPR4. + + jsr set_di_to_mawr + +; tii .vdc_tai, ram_tia, 8 + + .if SUPPORT_SGX + txa ; Select which VDC to write + inc a ; to. + inc a + sta.l ram_tia_dst + .endif + + lda #VRAM_XFER_SIZE ; Split into 16-byte chunks + sta.l ram_tia_len ; for stable IRQ response. + + ldx.l <_bp + stx.l ram_tia_src + ldy.h <_bp + sty.h ram_tia_src + + lda.l <_ax ; Length in words. + pha ; Preserve length.l + + lsr.h <_ax + ror a + lsr.h <_ax + ror a + lsr.h <_ax + ror a + .if VRAM_XFER_SIZE == 32 + lsr.h <_ax + ror a + .endif + + sax ; x=chunks-lo + beq .next_block ; a=source-lo, y=source-hi + +.chunk_loop: jsr ram_tia ; transfer 16-bytes + + clc ; increment source + adc #VRAM_XFER_SIZE + sta.l ram_tia_src + bcc .same_page + iny + bpl .same_bank ; remap_data + + say + tma4 + tam3 + inc a + tam4 + lda #$60 + say + +.same_bank: sty.h ram_tia_src + +.same_page: dex + bne .chunk_loop + +.next_block: dec.h <_ax + bpl .chunk_loop + + pla ; Restore length.l + and #VRAM_XFER_SIZE / 2 - 1 + beq .done + + asl a ; Convert words to bytes. + sta.l ram_tia_len + + jsr ram_tia ; transfer remainder + +.done: pla + tam4 + pla + tam3 + + plx ; Restore X (aka __sp). + + leave + + .endp + + .endprocgroup ; load_vram_group + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_bat( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned char tiles_w<_al>, unsigned char tiles_h<_ah> ); +; void __fastcall __xsafe sgx_load_bat( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned char tiles_w<_al>, unsigned char tiles_h<_ah> ); +; +; load_bat_sgx - transfer a BAT to VRAM +; load_bat_vdc - transfer a BAT to VRAM +; +; transfer a BAT to VRAM +; ---- +; _bp = BAT memory location +; _bp_bank = BAT bank +; _di = VRAM base address +; _al = nb of column to copy +; _ah = nb of row +; ---- +; N.B. BAT data *must* be word-aligned! + +_gfx_load_bat_PARM_2 = _bp +_gfx_load_bat_PARM_3 = _di +_gfx_load_bat_PARM_4 = _al +_gfx_load_bat_PARM_5 = _ah + +load_bat_group .procgroup ; These routines share code! + + .if SUPPORT_SGX + .proc _sgx_load_bat.4 + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _load_bat.4 + .endp + .endif + + .proc _load_bat.4 + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + tma3 + pha + + ldy <_bp_bank + jsr set_bp_to_mpr3 ; Map data to MPR3. + + ldy.l <_bp + stz.l <_bp + +.line_loop: jsr set_di_to_mawr + + ldx <_al +.tile_loop: lda [_bp], y + sta VDC_DL + iny + lda [_bp], y + sta VDC_DH + iny + bne !+ + jsr inc.h_bp_mpr3 +!: dex + bne .tile_loop + + lda vdc_bat_width, x + clc + adc.l <_di + sta.l <_di + bcc !+ + inc.h <_di + +!: dec <_ah + bne .line_loop + + pla + tam3 + + plx ; Restore X (aka __sp). + + leave + + .endp + + .endprocgroup ; load_bat_group + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_palette( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp>, unsigned char num_palettes<_ah> ); + + .proc _load_palette.3 + + ldy color_queue_w ; Get the queue's write index. + + lda.l <_bp ; Add this set of palettes to + sta color_addr_l, y ; the queue. + lda.h <_bp + sta color_addr_h, y + lda <_bp_bank + sta color_bank, y + lda <_al + sta color_index, y + lda <_ah + sta color_count, y + + iny ; Increment the queue index. + tya + and #7 + +.wait: cmp color_queue_r ; If the queue is full, wait + beq .wait ; for the next VBLANK. + + sta color_queue_w ; Signal item is in the queue. + + leave ; All done, phew! + + .endp + + + + .if 0 + +_gfx_load_palette_PARM_2 = _bp +_gfx_load_palette_PARM_3 = _di +_gfx_load_palette_PARM_4 = _al +_gfx_load_palette_PARM_5 = _ah +_gfx_load_palette .alias load_palette + +; tay +; jmp _load_palette + +; ---- +; _gfx_load_vram +; ---- + +_gfx_load_vram_PARM_2 = _bp +_gfx_load_vram_PARM_3 = _di +_gfx_load_vram_PARM_4 = _ax +_gfx_load_vram .alias load_vram_vdc + +_gfx_load_vram: + tay + jmp load_vram + + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_background( unsigned char __far *tiles<_bp_bank:_bp>, unsigned char __far *palettes<__fbank:__fptr>, unsigned char __far *bat<_cl:_bx>, unsigned char w<_dl>, unsigned char w<_dh> ); + + .proc _load_background.5 + + stz.l <_di + lda.h #$1000 + sta.h <_di + stz.l <_ax + lda.h #$4000 + sta.h <_ax + call _load_vram.3 ; This is __xsafe! + + lda.l <__fptr + sta.l <_bp + lda.h <__fptr + sta.h <_bp + lda <__fbank + sta <_bp_bank + stz <_al + lda #16 + sta <_ah + call _load_palette.3 ; This is __xsafe! + + jsr wait_vsync ; This is __xsafe! + + stz.l <_di + stz.h <_di + lda.l <_bx + sta.l <_bp + lda.h <_bx + sta.h <_bp + lda <_cl + sta <_bp_bank + lda <_dl + sta <_al + lda <_dh + sta <_ah + jmp _load_bat.4 ; This is __xsafe! + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; HuC Font Functions +; +; *************************************************************************** +; *************************************************************************** + +; ************** +; void __fastcall __xsafe set_font_addr( unsigned int vram ); + +_set_font_addr: + sty <__temp + lsr <__temp + ror a + lsr <__temp + ror a + lsr <__temp + ror a + lsr <__temp + ror a + sec + sbc #$20 + sta.l _font_base + bcs !+ + dec <__temp + +!: lda.h _font_base + and #$F0 + ora <__temp + sta.h _font_base + rts + + .alias _set_font_addr.1 = _set_font_addr + + +; ************** +; void __fastcall __xsafe set_font_pal( unsigned char palette ); + +_set_font_pal: + asl a + asl a + asl a + asl a + sta <__temp + + lda.h _font_base + and #$0F + ora <__temp + sta.h _font_base + rts + + .alias _set_font_pal.1 = _set_font_pal + + +; ************** +; void __fastcall __xsafe load_font( char far *font<_bp_bank:_bp>, unsigned char count<_al> ); +; void __fastcall __xsafe load_font( char far *font<_bp_bank:_bp>, unsigned char count<_al>, unsigned int vram ); + +_load_font.2: ldy vdc_bat_limit ; BAT limit mask hi-byte. + iny + cla + +_load_font.3: sta.l <_di ; Load the font directly + sty.h <_di ; after the BAT (stupid!). + + jsr _set_font_addr ; Set _font_base from addr. + + lda <__al ; Convert #tiles into #words. + stz <__ah + asl a + rol <__ah + asl a + rol <__ah + asl a + rol <__ah + asl a + rol <__ah + sta <__al + jmp _load_vram.3 ; This is __xsafe! + + + +; ************** +; void __fastcall cls( int tile ); + +_cls: lda.l _font_base + ldy.h _font_base + clc + adc #' ' + bcc _cls.1 + iny + +_cls.1: sta.l <_ax ; VRAM word to write. + sty.h <_ax + lda vdc_bat_limit ; BAT size hi-byte. + inc a + sta <_bl + jmp clear_bat_vdc + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_default_font( void ); +; +; huc_font_sgx - transfer a 8x8 monochrome font into VRAM +; huc_font_vdc - transfer a 8x8 monochrome font into VRAM +; +; Args: _bp, _bp_bank = _farptr to font data mapped into MPR3 & MPR4. +; Args: _di = VRAM destination address. +; Args: monofont_fg = font color (0..15) +; Args: monofont_bg = background color (0..15) +; Args: _al = number of tiles (aka characters) 0==256 + +huc_mono_font .procgroup + + .if SUPPORT_SGX +huc_font_sgx .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + bra !+ + + .ref huc_font_vdc ; Need huc_font_vdc + .endp + .endif + + .proc _load_default_font + + .data +font_1: incbin "data/font8x8-bold-short-iso646-fr.dat", 128 + .code + + ldy vdc_bat_limit ; BAT limit mask hi-byte. + iny + cla + sta.l <_di ; Load the font directly + sty.h <_di ; after the BAT (stupid!). + + jsr _set_font_addr ; Set _font_base from addr. + + lda.l #font_1 + sta.l <_bp + lda.h #font_1 + sta.h <_bp + ldy #^font_1 + sty <_bp_bank + + lda #$60 ; #characters. + sta <_al + + .ref huc_font_vdc ; Need huc_font_vdc + .endp + +huc_font_vdc .proc + + .bss +monofont_fg: .ds 1 +monofont_bg: .ds 1 + .code + + cly ; Offset to PCE VDC. + +!: phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + tma3 ; Preserve MPR3. + pha + tma4 ; Preserve MPR4. + pha + + ldy <_bp_bank + jsr set_bp_to_mpr34 + + jsr set_di_to_mawr + + lda monofont_fg ; Foreground pixel color. + sta <__temp + lda monofont_bg ; Background pixel color. + phx + ldx.l #_cx ; Create a bit mask for each +.bg_loop: stz $2000, x ; plane of the background. + lsr a + bcc .bg_plane + dec $2000, x +.bg_plane: inx + bne .bg_loop + plx + +.tile_loop: cly + +.plane01: lda [_bp], y ; Get font byte. + bbs0 <__temp, .set_plane0 +.clr_plane0: eor #$FF ; Clr font bits in background. + and <_cx + 0 + bra .put_plane0 +.set_plane0: ora <_cx + 0 ; Set font bits in background. +.put_plane0: sta VDC_DL, x + + lda [_bp], y ; Get font byte. + bbs1 <__temp, .set_plane1 +.clr_plane1: eor #$FF ; Clr font bits in background. + and <_cx + 1 + bra .put_plane1 +.set_plane1: ora <_cx + 1 ; Set font bits in background. +.put_plane1: sta VDC_DH, x + + iny + cpy #8 + bcc .plane01 + + cly + +.plane23: lda [_bp], y ; Get font byte. + bbs2 <__temp, .set_plane2 +.clr_plane2: eor #$FF ; Clr font bits in background. + and <_cx + 2 + bra .put_plane2 +.set_plane2: ora <_cx + 2 ; Set font bits in background. +.put_plane2: sta VDC_DL, x + + lda [_bp], y ; Get font byte. + bbs3 <__temp, .set_plane3 +.clr_plane3: eor #$FF ; Clr font bits in background. + and <_cx + 3 + bra .put_plane3 +.set_plane3: ora <_cx + 3 ; Set font bits in background. +.put_plane3: sta VDC_DH, x + + iny + cpy #8 + bcc .plane23 + + lda.l <_bp + adc #8-1 + sta.l <_bp + bcc !+ + inc.h <_bp + +!: dec <_al + bne .tile_loop + + pla ; Restore MPR4. + tam4 + pla ; Restore MPR3. + tam3 + + plx ; Restore X (aka __sp). + + leave ; All done, phew! + + .endp + + .endprocgroup ; huc_mono_font + + + +; *************************************************************************** +; *************************************************************************** +; +; HuC Text Output +; +; *************************************************************************** +; *************************************************************************** + + + +vdc_tty_out .procgroup ; These routines share code! + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe put_char( unsigned char digit<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + + .if SUPPORT_SGX +put_char_sgx .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .endp + .endif + +put_char_vdc .proc + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + jsr set_di_xy_mawr + + cla ; Push EOL marker. + pha + + lda <_bl + pha ; Push character to output. + bra !output+ + + .ref put_hex_vdc ; Need put_number_vdc + + .endp + + .alias _put_char.3 = put_char_vdc + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe put_digit( unsigned char digit<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + + .if SUPPORT_SGX +put_digit_sgx .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .endp + .endif + +put_digit_vdc .proc + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + jsr set_di_xy_mawr + + cla ; Push EOL marker. + pha + + lda <_bl ; Convert hex digit to ASCII. + and #$0F + cmp #10 + bcc !+ + adc #6 +!: adc #'0' + pha ; Push character to output. + bra !output+ + + .ref put_hex_vdc ; Need put_number_vdc + + .endp + + .alias _put_digit.3 = put_digit_vdc + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe put_hex( unsigned int number<_bx>, unsigned char length<_cl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + + .if SUPPORT_SGX +put_hex_sgx .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .endp + .endif + +put_hex_vdc .proc + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + jsr set_di_xy_mawr + + ldy <_cl ; Total #characters to print, + beq !exit+ ; NOT minimum #characters! + + stx <__temp ; Preserve which VDC. + + clx ; Push EOL marker. + phx + +.hex_byte: lda.l <_bx, x ; Convert hex digit to ASCII. + and #$0F + cmp #10 + bcc !+ + adc #6 +!: adc #'0' + pha ; Push character to output. + dey + beq .hex_done + + lda.l <_bx, x ; Convert hex digit to ASCII. + lsr a + lsr a + lsr a + lsr a + cmp #10 + bcc !+ + adc #6 +!: adc #'0' + pha ; Push character to output. + dey + beq .hex_done + + inx + bra .hex_byte + +.hex_done: ldx <__temp ; Restore which VDC. + bra !output+ + +.write: clc + adc.l _font_base + sta VDC_DL, x + cla + adc.h _font_base + sta VDC_DH, x + +!output: pla ; Pop the digits and output. + bne .write + +!exit: plx ; Restore X (aka __sp). + + leave ; All done! + + .endp + + .alias _put_hex.4 = put_hex_vdc + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe put_number( unsigned int number<_bx>, unsigned char length<_cl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + + .if SUPPORT_SGX +put_number_sgx .proc + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "clx" into a "beq". + + .endp + .endif + +put_number_vdc .proc + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + jsr set_di_xy_mawr + + ldy <_cl ; Total #characters to print, + beq !exit- ; NOT minimum #characters! + + stx <__temp ; Preserve which VDC. + + clx ; Push EOL marker. + phx + + ldx.h <_bx ; Is the number -ve? + stx <_cl ; Remember this. + bpl .divide_by_ten + + sec ; Make the number +ve. + lda.l <_bx + eor #$FF + adc #0 + sta.l <_bx + txa + eor #$FF + adc #0 + sta.h <_bx + +.divide_by_ten: ldx #16 + cla ; Clear Remainder. + asl.l <_bx ; Rotate Dividend, MSB -> C. + rol.h <_bx +.divide_loop: rol a ; Rotate C into Remainder. + cmp #10 ; Test Divisor. + bcc .divide_less ; CC if Divisor > Remainder. + sbc #10 ; Subtract Divisor. +.divide_less: rol.l <_bx ; Quotient bit -> Dividend LSB. + rol.h <_bx ; Rotate Dividend, MSB -> C. + dex + bne .divide_loop + + clc + adc #'0' ; Always leaves C clr. + pha ; Push character to output. + dey + beq !pad+ + lda.l <_bx ; Repeat while non-zero. + ora.h <_bx + bne .divide_by_ten + + ldx <__temp ; Restore which VDC. + + lda <_cl ; Was the number -ve? + bpl !pad+ + lda #'-' ; Output a leading '-'. + pha + dey + +!pad: lda #' ' ; Add padding characters. +.loop: dey + bmi !output- + pha + bra .loop + + .ref put_hex_vdc ; Need put_number_vdc + + .endp + + .alias _put_number.4 = put_number_vdc + + .endprocgroup ; vdc_tty_out + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe put_string( unsigned char *string<_bp>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +; +; N.B. This is not a .proc right now because it is called from procedures +; that contain embedded strings, and the string aren't banked in before +; printing (yet). + +; .if SUPPORT_SGX +;put_string_sgx .proc +; +; ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. +; db $F0 ; Turn "cly" into a "beq". +; +; .endp +; .endif + +put_string_vdc: ; .proc + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + tma3 + pha + tma4 + pha + +; ldy <_bp_bank ; Map memory block to MPR34. +; beq !+ +; jsr set_bp_to_mpr34 + +!: jsr set_di_xy_mawr + +.chr_loop: lda [_bp] + beq .done + + clc + adc.l _font_base + sta VDC_DL, x + cla + adc.h _font_base + sta VDC_DH, x + + inc.l <_bp + bne .chr_loop + inc.h <_bp + bra .chr_loop + +.done: pla + tam4 + pla + tam3 + + plx ; Restore X (aka __sp). + + rts + +; leave +; +; .endp + + .alias _put_string.3 = put_string_vdc + + + + +; *************************************************************************** +; *************************************************************************** +; put_xy(char x, char y) +; ---- +; _di + 0 = x coordinate +; _di + 1 = y coordinate +; ---- +; _di = VRAM address +; ---- + +; .if SUPPORT_SGX +;xput_xy_sgx: ldx #SGX_VDC_OFFSET ; Offset to SGX VDC. +; db $F0 ; Turn "clx" into a "beq". +; .endif +; +;xput_xy_vdc: clx ; Offset to PCE VDC. +; +; sta.l <_al +; sty.h <_ah + +set_di_xy_mawr: cla + bit vdc_bat_width, x + bmi .w128 + bvs .w64 +.w32: lsr <_ah + ror a +.w64: lsr <_ah + ror a +.w128: lsr <_ah + ror a + ora <_al + sta.l <_di + lda <_ah + sta.h <_di + jmp set_di_to_mawr diff --git a/include/hucc/hucc-gfx.h b/include/hucc/hucc-gfx.h new file mode 100644 index 00000000..7ae72a57 --- /dev/null +++ b/include/hucc/hucc-gfx.h @@ -0,0 +1,131 @@ +#ifndef _hucc_gfx_h +#define _hucc_gfx_h + +/**************************************************************************** +; *************************************************************************** +; +; huc-gfx.h +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Screen defines ... +// ************* + +#define SCR_SIZE_32x32 0 +#define SCR_SIZE_64x32 1 +#define SCR_SIZE_128x32 2 +#define SCR_SIZE_32x64 4 +#define SCR_SIZE_64x64 5 +#define SCR_SIZE_128x64 6 + +#define XRES_SHARP 0 +#define XRES_SOFT 4 +#define XRES_KEEP 128 + +#define VPC_WIN_A 0x00 +#define VPC_WIN_B 0x01 +#define VPC_WIN_AB 0x02 +#define VPC_WIN_NONE 0x03 +#define VPC_NORM 0x00 +#define VPC_SPR 0x04 +#define VPC_INV_SPR 0x08 +#define VDC1_ON 0x01 +#define VDC1_OFF 0x00 +#define VDC2_ON 0x02 +#define VDC2_OFF 0x00 +#define VDC_ON 0x03 +#define VDC_OFF 0x00 + +// ************* +// Functions in hucc-gfx.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_GFX 1 + +extern void __fastcall __xsafe set_256x224( void ); +//extern void __fastcall __xsafe set_352x224( void ); +//extern void __fastcall __xsafe set_496x224( void ); + +extern void __fastcall __xsafe set_screen_size( unsigned char value<_al> ); +extern void __fastcall __xsafe sgx_set_screen_size( unsigned char value<_al> ); + +extern void __fastcall __xsafe __macro set_xres( unsigned int x_pixels<_ax> ); +extern void __fastcall __xsafe __macro sgx_set_xres( unsigned int x_pixels<_ax> ); + +extern void __fastcall __xsafe set_xres( unsigned int x_pixels<_ax>, unsigned char blur_flag<_bl> ); +extern void __fastcall __xsafe sgx_set_xres( unsigned int x_pixels<_ax>, unsigned char blur_flag<_bl> ); + +extern unsigned int __fastcall __xsafe __macro vram_addr( unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +extern unsigned int __fastcall __xsafe __macro sgx_vram_addr( unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + +extern unsigned int __fastcall __xsafe __macro get_vram( unsigned int address<_di> ); +extern unsigned int __fastcall __xsafe __macro sgx_get_vram( unsigned int address<_di> ); + +extern void __fastcall __xsafe __macro put_vram( unsigned int address<_di>, unsigned int data ); +extern void __fastcall __xsafe __macro sgx_put_vram( unsigned int address<_di>, unsigned int data ); + +extern void __fastcall set_tile_address( unsigned int vram ); +extern void __fastcall sgx_set_tile_address( unsigned int vram ); + +extern void __fastcall __xsafe __nop set_tile_data( unsigned char __far *tiles, unsigned char num_tiles, unsigned char __far *palette_table, unsigned char tile_type ); +extern void __fastcall __xsafe __nop sgx_set_tile_data( unsigned char __far *tiles, unsigned char num_tiles, unsigned char __far *palette_table, unsigned char tile_type ); + +extern void __fastcall __xsafe load_vram( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_words<_ax> ); +extern void __fastcall __xsafe sgx_load_vram( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_words<_ax> ); + +extern void __fastcall __xsafe load_tile( unsigned int vram<_di> ); +extern void __fastcall __xsafe sgx_load_tile( unsigned int vram<_di> ); + +extern void __fastcall __xsafe load_bat( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned char tiles_w<_al>, unsigned char tiles_h<_ah> ); +extern void __fastcall __xsafe sgx_load_bat( unsigned int vram<_di>, unsigned char __far *data<_bp_bank:_bp>, unsigned char tiles_w<_al>, unsigned char tiles_h<_ah> ); + +extern void __fastcall __xsafe load_palette( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp>, unsigned char num_palettes<_ah> ); + +extern void __fastcall __xsafe set_font_addr( unsigned int vram ); +extern void __fastcall __xsafe set_font_pal( unsigned char palette ); + +extern void __fastcall __xsafe load_font( char __far *font<_bp_bank:_bp>, unsigned char count<_al> ); +extern void __fastcall __xsafe load_font( char __far *font<_bp_bank:_bp>, unsigned char count<_al>, unsigned int vram ); + +extern void __fastcall __xsafe __nop set_font_color( unsigned char foreground, unsigned char background ); +extern void __fastcall __xsafe load_default_font( void ); + +extern void __fastcall __xsafe put_char( unsigned char digit<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +extern void __fastcall __xsafe put_digit( unsigned char digit<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +extern void __fastcall __xsafe put_hex( unsigned int number<_bx>, unsigned char length<_cl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +extern void __fastcall __xsafe put_number( unsigned int number<_bx>, unsigned char length<_cl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +extern void __fastcall __xsafe put_string( unsigned char *string<_bp>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + +extern void __fastcall cls( void ); /* NOT __xsafe! */ +extern void __fastcall cls( unsigned int tile ); /* NOT __xsafe! */ + +extern void __fastcall __xsafe disp_on( void ); +extern void __fastcall __xsafe disp_off( void ); + +extern void __fastcall __xsafe set_tile_data( unsigned char *tile_ex<_di> ); + +extern void __fastcall __xsafe load_background( unsigned char __far *tiles<_bp_bank:_bp>, unsigned char __far *palettes<__fbank:__fptr>, unsigned char __far *bat<_cl:_bx>, unsigned char w<_dl>, unsigned char h<_dh> ); + +// Deprecated functions ... + +extern void __fastcall __xsafe __macro set_bgpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp> ); +extern void __fastcall __xsafe __macro set_bgpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_palettes<_ah> ); +extern void __fastcall __xsafe __macro set_sprpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp> ); +extern void __fastcall __xsafe __macro set_sprpal( unsigned char palette<_al>, unsigned char __far *data<_bp_bank:_bp>, unsigned int num_palettes<_ah> ); + +#endif // __HUCC__ + +#endif // _hucc_gfx_h diff --git a/include/hucc/hucc-math.asm b/include/hucc/hucc-math.asm new file mode 100644 index 00000000..0cee925a --- /dev/null +++ b/include/hucc/hucc-math.asm @@ -0,0 +1,618 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-math.asm +; +; Basic (i.e. very slow) 8-bit and 16-bit multiply and divide routines. +; +; Copyright John Brandwood 2021-2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; This is basically a set of SDCC-compatible routines, but using Y:A for the +; primary register instead of X:A. +; +; Using Y:A makes the routines instantly usable with HuCC, and it also makes +; them usable with SDCC with just an "sxy" before and after the call. +; +; *************************************************************************** +; *************************************************************************** + + .code + +multiplier = __temp +multiplicand = ___SDCC_m6502_ret0 +product = multiplicand + +__mulint_PARM_2 = multiplier + +divisor = __temp +dividend = ___SDCC_m6502_ret0 +quotient = dividend +remainder = ___SDCC_m6502_ret2 + +__moduint_PARM_2 = divisor +__modsint_PARM_2 = divisor +__divuint_PARM_2 = divisor +__divsint_PARM_2 = divisor + + + +; *************************************************************************** +; int +; _mulint (int a, int b) +; +; 1st parameter in Y:A (multiplicand) +; 2nd parameter in __mulint_PARM_2 (multiplier) +; result in Y:A +; +; N.B. signed and unsigned multiply only differ in the top 16 of the 32bits! + +__mulint: sta C. + rol.h remainder. +; db $90 ; Turn "plp" into "bcc" to skip. +;.subtract: plp ; Discard remainder 17th bit. +; sec + +; tax ; If dividend has more bits +; pla ; than the divisor, then we +; and #1 ; need to check rotated bit. +; sbc #0 +; txa + bcc .skip ; CC if divisor > remainder. + + sta.h dividend LSB. + + db $F0 ; Turn "tya" into "beq" to skip. +.skip: tya ; Restore remainder lo-byte. + + dex + bne .loop + + ldy.h dividend LSB. + rol.h C. + + dex + beq .finished + + rol a ; Rotate C into remainder. + rol.h remainder. + +; cmp.l remainder. +; db $90 ; Turn "plp" into "bcc" to skip. +;.subtract: plp ; Discard remainder 17th bit. +; sec + + sta.h C. + sta.l remainder. + sbc dividend LSB. + dey + bne .loop + + cly ; Clear hi-byte of return. + rts ; Return the 16-bit remainder. + + + +; *************************************************************************** +; unsigned int +; _divuchar (unsigned char x, unsigned char y) +; +; 1st parameter in A (unsigned dividend) +; 2nd parameter in Y (unsigned divisor) +; result in Y:A + +__divuchar: jsr __moduchar + + lda ); +; +; initialize graphics mode +; - points graphics map to tiles at start_vram_addr + +_gfx_init.1 .proc + + phx ; Preserve X (aka __sp). + + stz.l <_di + stz.h <_di + jsr vdc_di_to_mawr + + lda vdc_bat_limit ; Size of BAT determines + inc a ; how many bitmapped BAT + sta <__temp ; entries to write. + + lda.h <_ax + lsr a + ror.l <_ax + lsr a + ror.l <_ax + lsr a + ror.l <_ax + lsr a + ror.l <_ax + ora #0 ; Palette 0. + ldy.l <_ax + + clx +.loop: sty VDC_DL + sta VDC_DH + iny + bne !+ + inc a +!: dex + bne .loop + dec <__temp + bne .loop + + plx ; Restore X (aka __sp). + + leave + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe gfx_clear( unsigned int start_vram_addr<_di> ); +; +; Clear the values in the graphics tiles +; - places zeroes in graphics tiles at start_vram_addr + +_gfx_clear.1 .proc + + phx ; Preserve X (aka __sp). + + jsr vdc_di_to_mawr + + lda vdc_bat_limit ; Size of BAT determines + inc a ; how many tiles to clear. + asl a + asl a + asl a + cly + st1 #0 +.loop: st2 #0 + st2 #0 + dey + bne .loop + dec a + bne .loop + + plx ; Restore X (aka __sp). + + leave + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe gfx_line( unsigned int x1<_gfx_x1>, unsigned int y1<_gfx_y1>, unsigned int x2<_gfx_x2>, unsigned int y2<_gfx_y2>, unsigned char color<_gfx_color> ); + +huc_gfx_line .procgroup + +_gfx_line.5: .proc + +; On entry ... + +_gfx_x1 = _ax +_gfx_y1 = _bx +_gfx_x2 = _cx +_gfx_y2 = _dx +_gfx_color = __fptr + +; During routine ... + +_gfx_err = _cx +_gfx_adj = _dx +_gfx_dx = _bp +_gfx_dy = _si +_gfx_xdir = __fptr + 1 + + phx ; Preserve X (aka __sp). + + clx ; Offset to PCE VDC. + + sec + lda.l <_gfx_y2 + sbc.l <_gfx_y1 + tay + lda.h <_gfx_y2 + sbc.h <_gfx_y1 + bcc .y2_lt_y1 + +.y2_ge_y1: sty.l <_gfx_dy + sta.h <_gfx_dy + + sec + lda.l <_gfx_x2 + sbc.l <_gfx_x1 + tay + lda.h <_gfx_x2 + sbc.h <_gfx_x1 + bra .check_dx + +.y2_lt_y1: eor #$FF + say + eor #$FF + inc a + bne !+ + iny +!: sta.l <_gfx_dy + sty.h <_gfx_dy + + sec + lda.l <_gfx_x1 + sbc.l <_gfx_x2 + tay + lda.h <_gfx_x1 + sbc.h <_gfx_x2 + + tii _gfx_x2, _gfx_x1, 4 + +.check_dx: sta <_gfx_xdir + bpl .save_dx + +.negate_dx: say + eor #$FF + adc #1 + say + eor #$FF + adc #0 + +.save_dx: sty.l <_gfx_dx + sta.h <_gfx_dx + + say + cmp.l <_gfx_dy + say + sbc.h <_gfx_dy + bcc .dy_gt_dx + + ; ****** + ; _gfx_dy is difference from end to start (positive) + ; _gfx_dx is difference from end to start (positive) + ; _gfx_xdir shows whether to apply deltax positive or negative + +.dx_ge_dy: asl.l <_gfx_dy ; _gfx_dy * 2 + rol.h <_gfx_dy + sec ; _gfx_err = _gfx_dy * 2 - _gfx_dx + lda.l <_gfx_dy + sbc.l <_gfx_dx + tay + lda.h <_gfx_dy + sbc.h <_gfx_dx + sty.l <_gfx_err + sta.h <_gfx_err + say + sec ; _gfx_adj = _gfx_dy * 2 - _gfx_dx * 2 + sbc.l <_gfx_dx + sta.l <_gfx_adj + tya + sbc.h <_gfx_dx + sta.h <_gfx_adj + bra .plot_x + +.loop_x: lda.l <_gfx_dx ; used as counter - get both endpoints + bne !+ + dec.h <_gfx_dx + bmi .finished +!: dec.l <_gfx_dx + +.plot_x: jsr !plot_pixel+ ; draw the current pixel at (_ax, _bx). + + lda.h <_gfx_err + bmi .loop_x_keep_y + +.loop_x_next_y: inc.l <_gfx_y1 + bne !+ + inc.h <_gfx_y1 + +!: clc ; _gfx_err += _gfx_dy * 2 - _gfx_dx * 2 + lda.l <_gfx_err + adc.l <_gfx_adj + sta.l <_gfx_err + lda.h <_gfx_err + adc.h <_gfx_adj + sta.h <_gfx_err + bra .loop_x_next_x + +.loop_x_keep_y: clc ; _gfx_err += _gfx_dy * 2 + lda.l <_gfx_err + adc.l <_gfx_dy + sta.l <_gfx_err + lda.h <_gfx_err + adc.h <_gfx_dy + sta.h <_gfx_err + +.loop_x_next_x: lda <_gfx_xdir ; adjust currx + bpl .loop_x_inc_x + +.loop_x_dec_x: lda.l <_gfx_x1 + bne !+ + dec.h <_gfx_x1 +!: dec.l <_gfx_x1 + bra .loop_x + +.loop_x_inc_x: inc.l <_gfx_x1 + bne .loop_x + inc.h <_gfx_x1 + bra .loop_x + + ; ****** + +.finished: plx ; Restore X (aka __sp). + + leave + + ; ****** + +.dy_gt_dx: asl.l <_gfx_dx ; _gfx_dx * 2 + rol.h <_gfx_dx + sec ; _gfx_err = _gfx_dx * 2 - _gfx_dy + lda.l <_gfx_dx + sbc.l <_gfx_dy + tay + lda.h <_gfx_dx + sbc.h <_gfx_dy + sty.l <_gfx_err + sta.h <_gfx_err + say + sec ; _gfx_adj = _gfx_dx * 2 - _gfx_dy * 2 + sbc.l <_gfx_dy + sta.l <_gfx_adj + tya + sbc.h <_gfx_dy + sta.h <_gfx_adj + bra .plot_y + +.loop_y: lda.l <_gfx_dy ; used as counter - get both endpoints + bne !+ + dec.h <_gfx_dy + bmi .finished +!: dec.l <_gfx_dy + +.plot_y: jsr !plot_pixel+ ; draw the current pixel at (_ax, _bx). + +.loop_y_next_y: inc.l <_gfx_y1 + bne !+ + inc.h <_gfx_y1 + +!: lda.h <_gfx_err + bmi .loop_y_keep_x + + clc ; _gfx_err += _gfx_dx * 2 - _gfx_dy * 2 + lda.l <_gfx_err + adc.l <_gfx_adj + sta.l <_gfx_err + lda.h <_gfx_err + adc.h <_gfx_adj + sta.h <_gfx_err + +.loop_y_next_x: lda <_gfx_xdir + bpl .loop_y_inc_x + +.loop_y_dec_x: lda.l <_gfx_x1 + bne !+ + dec.h <_gfx_x1 +!: dec.l <_gfx_x1 + bra .loop_y + +.loop_y_inc_x: inc.l <_gfx_x1 + bne .loop_y + inc.h <_gfx_x1 + bra .loop_y + +.loop_y_keep_x: clc ; _gfx_err += _gfx_dx * 2 + lda.l <_gfx_err + adc.l <_gfx_dx + sta.l <_gfx_err + lda.h <_gfx_err + adc.h <_gfx_dx + sta.h <_gfx_err + bra .loop_y + + .endp + + ; ****** + ; Plot a point at location (x,y) in color + +!plot_pixel: jsr .set_vram_addr + + lda.l <_gfx_x1 ; X coordinate. + and #7 + eor #7 ; Flip bits. + tay + + lda bit_mask, y + bbr0 <_si, .clr_bit0 +.set_bit0: ora VDC_DL, x + bra !+ +.clr_bit0: eor #$FF + and VDC_DL, x +!: sta VDC_DL, x + + lda bit_mask, y + bbr1 <_si, .clr_bit1 +.set_bit1: ora VDC_DH, x + bra !+ +.clr_bit1: eor #$FF + and VDC_DH, x +!: sta VDC_DH, x + + smb3 <_di + jsr set_di_to_marr + jsr set_di_to_mawr + + lda bit_mask, y + bbr2 <_si, .clr_bit2 +.set_bit2: ora VDC_DL, x + bra !+ +.clr_bit2: eor #$FF + and VDC_DL, x +!: sta VDC_DL, x + + lda bit_mask, y + bbr3 <_si, .clr_bit3 +.set_bit3: ora VDC_DH, x + bra !+ +.clr_bit3: eor #$FF + and VDC_DH, x +!: sta VDC_DH, x + + rts + + ; ****** + ; Utility routine to select x/y pixel co-ordinates in VRAM + +.set_vram_addr: lda.h <_gfx_x1 ; X pixel (0..1023) to tile (0..127). + lsr a + tay + lda.l <_gfx_x1 + ror a + say + lsr a + tya + ror a + lsr a + and vdc_bat_x_mask, x + sta.l <_di + + lda.h <_gfx_y1 ; Y pixel (0..511) to tile (0..63). + lsr a + lda.l <_gfx_y1 + ror a + lsr a + lsr a + sta.h <_di + cla + bit vdc_bat_width, x + bmi .w128 + bvs .w64 +.w32: lsr.h <_di + ror a +.w64: lsr.h <_di + ror a +.w128: lsr.h <_di + ror a + ora.l <_di + sta.l <_di + jsr set_di_to_marr + + lda VDC_DL, x ; Read tile# from BAT + sta.l <_di ; and calc its address. + lda VDC_DH, x + asl.l <_di + asl a + asl.l <_di + asl a + asl.l <_di + asl a + asl.l <_di + asl a + sta.h <_di + + lda.l <_gfx_y1 ; Add row within tile. + and #7 + clc + adc.l <_di + sta.l <_di + + jsr set_di_to_marr + jmp set_di_to_mawr + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe gfx_plot( unsigned int x<_gfx_x1>, unsigned int y<_gfx_y1>, char color<_gfx_color> ); + +_gfx_plot.3: .proc + + phx ; Preserve X (aka __sp). + clx ; Offset to PCE VDC. + + jsr !plot_pixel- + + plx ; Restore X (aka __sp). + leave + + .endp + + .endprocgroup ; huc_gfx_line diff --git a/include/hucc/hucc-old-line.h b/include/hucc/hucc-old-line.h new file mode 100644 index 00000000..09eb307d --- /dev/null +++ b/include/hucc/hucc-old-line.h @@ -0,0 +1,36 @@ +#ifndef _hucc_old_line_h +#define _hucc_old_line_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-old-line.h +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Functions in hucc-old-line.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_OLD_LINE 1 + +extern void __fastcall __xsafe gfx_init( unsigned int start_vram_addr<_ax> ); +extern void __fastcall __xsafe gfx_clear( unsigned int start_vram_addr<_di> ); +extern void __fastcall __xsafe gfx_plot( unsigned int x<_gfx_x1>, unsigned int y<_gfx_y1>, char color<_gfx_color> ); +extern void __fastcall __xsafe gfx_line( unsigned int x1<_gfx_x1>, unsigned int y1<_gfx_y1>, unsigned int x2<_gfx_x2>, unsigned int y2<_gfx_y2>, unsigned char color<_gfx_color> ); + +#endif // __HUCC__ + +#endif // _hucc_old_line_h diff --git a/include/hucc/hucc-old-map.asm b/include/hucc/hucc-old-map.asm new file mode 100644 index 00000000..5ecae358 --- /dev/null +++ b/include/hucc/hucc-old-map.asm @@ -0,0 +1,759 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-old-map.asm +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe load_map( unsigned char bat_x<_al>, unsigned char bat_y<_ah>, int map_x<_bx>, int map_y<_dx>, unsigned char tiles_w<_cl>, unsigned char tiles_h<_ch> ); +; void __fastcall __xsafe sgx_load_map( unsigned char bat_x<_al>, unsigned char bat_y<_ah>, int map_x<_bx>, int map_y<_dx>, unsigned char tiles_w<_cl>, unsigned char tiles_h<_ch> ); +; +; Transfer a HuC tiled map into the BAT in VRAM +; +; _al = BAT x screen coordinate (in tile units) +; _ah = BAT y screen coordinate +; _bl = MAP x start coordinate in the map +; _bh = MAP y start coordinate +; _cl = #TILES width to draw +; _ch = #TILES height to draw +; +; set by load_map_init() +; _di = BAT address +; _si = palette index table ptr +; _bp = map address + +huc_map_funcs .procgroup + + .bss + +; ************** +; 16-bytes of VDC HuC map info. +; +; N.B. MUST be 16-bytes before the SGX versions to use PCE_VDC_OFFSET. + +; Initialized by set_map_data() +vdc_map_wrap ds 1 ; unused +vdc_map_bank ds 1 +vdc_map_addr ds 2 +vdc_map_width ds 1 +vdc_map_height ds 1 + +; From hucc-old-spr.asm just to save space. This NEEDS to be changed! +spr_max: ds 1 +spr_clr: ds 1 + + ds 8 ; WASTED (at the moment) + + .if SUPPORT_SGX + +; ************** +; 16-bytes of SGX HuC map info. +; +; N.B. MUST be 16-bytes after the VDC versions to use SGX_VDC_OFFSET. + +; Initialized by sgx_set_map_data() +sgx_map_wrap ds 1 ; unused +sgx_map_bank ds 1 +sgx_map_addr ds 2 +sgx_map_width ds 1 +sgx_map_height ds 1 + +; From hucc-old-spr.asm just to save space. This NEEDS to be changed! +sgx_spr_max: ds 1 +sgx_spr_clr: ds 1 + + .endif + + .code + + .if SUPPORT_SGX + + .proc _sgx_load_map.6 + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _load_map.6 + .endp + + .endif + + .proc _load_map.6 + +.bat_x = _al +.bat_y = _ah +.map_x = _bl +.map_y = _bh +.tiles_w = _cl +.tiles_h = _ch +.bat_line = _di +.map_line = _bp +.attr_tbl = _si + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + ; wrap 16-bit signed map x coordinate, and only use the bottom byte. + +.wrap_map_x: lda.l <_bx + ldy vdc_map_width, x ; If map_width == 256, then + beq .mapx_ok ; just take the lo-byte of X. + + ldy.h <_bx + bmi .mapx_neg +.mapx_pos: sec + sbc vdc_map_width, x + bcs .mapx_pos + dey + bpl .mapx_pos +.mapx_neg: clc + adc vdc_map_width, x + bcc .mapx_neg + iny + bmi .mapx_neg + +.mapx_ok: sta <.map_x ; 0 <= map_x < mapwidth + + ; wrap 16-bit signed map y coordinate, and only use the bottom byte. + +.wrap_map_y: lda.l <_dx + ldy vdc_map_height, x ; If map_height == 256, then + beq .mapy_ok ; just take the lo-byte of Y. + + ldy.h <_dx + bmi .mapy_neg +.mapy_pos: sec + sbc vdc_map_height, x + bcs .mapy_pos + dey + bpl .mapy_pos +.mapy_neg: clc + adc vdc_map_height, x + bcc .mapy_neg + iny + bmi .mapy_neg + +.mapy_ok: sta <.map_y ; 0 <= map_y < mapheight + + tma2 ; Preserve MPR2, MPR3, MPR4. + pha + tma3 + pha + tma4 + pha + + ; ****************************** + ; Calculate the map/bat pointers + ; ****************************** + + jsr !calc_bat_tile+ ; Calculate bat tile address. + + jsr !calc_map_line+ ; Calculate map line address. + + ; Now actually draw the map! + + lda vdc_tile_type, x + cmp #16 + bcc .draw_line8 + jmp .draw_line16 + + ; ****************************** + ; Draw a bytemap of 8x8 tiles + ; ****************************** + +.next_line8: clc ; 8x8 tiles + jsr .next_map_line + +.draw_line8: lda <.tiles_w + sta.l <__temp ; width counter in __temp.l + + lda vdc_bat_width, x ; calculate #tiles to edge + sec + sbc <.bat_x + sta.h <__temp ; wrap counter in __temp.h + + ldy <.map_x + + stz , unsigned char map_y<_bh> ); +; unsigned char __fastcall sgx_map_get_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh> ); + + .if SUPPORT_SGX + + .proc _sgx_map_get_tile.2 + + ldx #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "clx" into a "beq". + + .ref _map_get_tile.2 + .endp + + .endif + + .proc _map_get_tile.2 + +.map_x = _bl ; N.B. These MUST be the same +.map_y = _bh ; addresses used by _load_map.6 +.map_line = _bp + + clx ; Offset to PCE VDC. + + tma3 ; Preserve MPR3, MPR4. + pha + tma4 + pha + + jsr !calc_map_line- ; Calculate map line address. + + ldy <.map_x ; Read the tile from the map. + lda [.map_line], y + tax ; Put return code in X. + + pla ; Restore MPR3, MPR4. + tam4 + pla + tam3 + + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + + .ref _load_map.6 + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe map_put_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh>, unsigned char tile<_al> ); +; void __fastcall __xsafe sgx_map_put_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh>, unsigned char tile<_al> ); + + .if SUPPORT_SGX + + .proc _sgx_map_put_tile.3 + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _map_put_tile.3 + .endp + + .endif + + .proc _map_put_tile.3 + +.map_x = _bl ; N.B. These MUST be the same +.map_y = _bh ; addresses used by _load_map.6 +.map_line = _bp + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + tma3 ; Preserve MPR3, MPR4. + pha + tma4 + pha + + jsr !calc_map_line- ; Calculate map line address. + + ldy <.map_x ; Write the tile to the map. + lda <_al + sta [.map_line], y + + pla ; Restore MPR3, MPR4. + tam4 + pla + tam3 + + plx ; Restore X (aka __sp). + + leave ; All done! + + .ref _load_map.6 + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe put_tile( unsigned char tile<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +; void __fastcall __xsafe sgx_put_tile( unsigned char tile<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +; +; Transfer a single HuC map tile to the BAT in VRAM +; +; _al = BAT x screen coordinate (in tile units) +; _ah = BAT y screen coordinate +; _di = BAT address +; _bl = MAP tile number to write + + .if SUPPORT_SGX + + .proc _sgx_put_tile.3 + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _put_tile.3 + .endp + + .endif + + .proc _put_tile.3 + +.bat_x = _al ; N.B. These MUST be the same +.bat_y = _ah ; addresses used by _load_map.6 +.bat_tile = _bl +.bat_line = _di +.attr_tbl = _si + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + tma2 ; Preserve MPR2. + pha + + jsr !calc_bat_tile- ; Calculate bat tile address. + + stz , unsigned char w, unsigned char h ); +extern void __fastcall __xsafe __nop sgx_set_map_data( unsigned char __far *map, unsigned char w, unsigned char h ); + +extern void __fastcall __xsafe load_map( unsigned char bat_x<_al>, unsigned char bat_y<_ah>, int map_x<_bx>, int map_y<_dx>, unsigned char tiles_w<_cl>, unsigned char tiles_h<_ch> ); +extern void __fastcall __xsafe sgx_load_map( unsigned char bat_x<_al>, unsigned char bat_y<_ah>, int map_x<_bx>, int map_y<_dx>, unsigned char tiles_w<_cl>, unsigned char tiles_h<_ch> ); + +extern unsigned char __fastcall map_get_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh> ); +extern unsigned char __fastcall sgx_map_get_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh> ); + +extern void __fastcall __xsafe map_put_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh>, unsigned char tile<_al> ); +extern void __fastcall __xsafe sgx_map_put_tile( unsigned char map_x<_bl>, unsigned char map_y<_bh>, unsigned char tile<_al> ); + +extern void __fastcall __xsafe put_tile( unsigned char tile<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); +extern void __fastcall __xsafe sgx_put_tile( unsigned char tile<_bl>, unsigned char bat_x<_al>, unsigned char bat_y<_ah> ); + +// Deprecated functions ... + +extern void __fastcall __xsafe __nop set_map_pals( unsigned char __far *palette_table ); +extern void __fastcall __xsafe __nop set_map_tile_type( unsigned char tile_type ); + +extern void __fastcall __xsafe __nop sgx_set_map_pals( unsigned char __far *palette_table ); +extern void __fastcall __xsafe __nop sgx_set_map_tile_type( unsigned char tile_type ); + +extern void __fastcall set_map_tile_base( unsigned int vram ); +extern void __fastcall sgx_set_map_tile_base( unsigned int vram ); + +#endif // __HUCC__ + +#endif // _hucc_old_map_h diff --git a/include/hucc/hucc-old-scroll.asm b/include/hucc/hucc-old-scroll.asm new file mode 100644 index 00000000..d73ad45b --- /dev/null +++ b/include/hucc/hucc-old-scroll.asm @@ -0,0 +1,404 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-old-scroll.asm +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; HuC's old scrolling library is provided for use with existing HuC projects, +; but it should preferably be avoided in new projects because it is slow and +; forever limited by its choice to handle gaps between areas, and sorting. +; +; HuCC's new scrolling library puts the responibility for defining both gaps +; and the display order into the project's hands, but in return it runs much +; faster, using less than 1/6 of the processing time in VBLANK, and far less +; time in the RCR interrputs themselves. It also supports the 2nd SuperGRAFX +; screen layer, which HuC's old scrolling library ignores. +; +; *************************************************************************** +; *************************************************************************** + + ; Signal that the old scrolling library is used. + +HUCC_OLD_SCROLL = 1 + + ; Use the old name to configure the #scroll regions. + + .ifndef HUC_NUM_SCROLLS +HUC_NUM_SCROLLS = 4 + .endif + + .if HUC_NUM_SCROLLS > 8 + .fail Number of defined scrolls cannot exceed 8 + .endif + +; [ 28] user scrolling vars + .bss +scroll_top: .ds HUC_NUM_SCROLLS ; top +scroll_btm: .ds HUC_NUM_SCROLLS ; btm +scroll_crl: .ds HUC_NUM_SCROLLS ; control +scroll_xl: .ds HUC_NUM_SCROLLS ; x +scroll_xh: .ds HUC_NUM_SCROLLS ; +scroll_yl: .ds HUC_NUM_SCROLLS ; y +scroll_yh: .ds HUC_NUM_SCROLLS ; scrolling table + +; [ 69] display list + .bss + +active_index .ds 1 +active_list .ds HUC_NUM_SCROLLS + 1 + +active_top .ds HUC_NUM_SCROLLS + 1 +active_btm .ds HUC_NUM_SCROLLS +active_crl .ds HUC_NUM_SCROLLS +active_xl .ds HUC_NUM_SCROLLS +active_xh .ds HUC_NUM_SCROLLS +active_yl .ds HUC_NUM_SCROLLS +active_yh .ds HUC_NUM_SCROLLS + + .code + +SCROLL_IRQ = $0C ; VDC CR for VBL and RCR IRQ. +HUC_SCR_HEIGHT = 224 +HUC_1ST_RCR = $144 + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe scroll( unsigned char num<_al>, unsigned int x<_cx>, unsigned int y<_dx>, unsigned char top<_ah>, unsigned char bottom<_bl>, unsigned char disp ); +; +; set screen scrolling + +_scroll.6: ldy <_al ; Region number. + + and #$C0 ; Flags (mark it as enabled). + ora #SCROLL_IRQ + sta scroll_crl, y + + lda <_bl ; BTM+1 so that it's easier to + inc a ; calcute gaps between regions. + sta scroll_btm, y + + lda <_ah ; TOP + sta scroll_top, y + + sec ; Either Y at top of the frame + beq !+ ; or Y-1 because the RCR code + clc ; sets it on the line before. +!: lda.l <_dx + sbc #0 + sta scroll_yl, y + lda.h <_dx + sbc #0 + sta scroll_yh, y + + lda.l <_cx + sta scroll_xl, y + lda.h <_cx + sta scroll_xh, y + + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe scroll_disable( unsigned char num ); +; +; disable screen scrolling for a scroll region + +_scroll_disable.1: + tay + lda scroll_crl, y + and #~SCROLL_IRQ + sta scroll_crl, y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; vbl_init_scroll +; +; N.B. Y of $FF is the first "set-in-vblank" region. +; +; Y ... $FF, $BF, $F0 for 2 regions at $00 and $C0. +; +; From Charles MacDonald's pcetech.txt ... +; +; Raster Compare Register (RCR): +; +; The range of the RCR is 263 lines, relative to the start of the active +; display period. (defined by VSW, VDS, and VCR) The VDC treats the first +; scanline of the active display period as $0040, so the valid ranges for +; the RCR register are $0040 to $0146. +; +; For example, assume VSW=$02, VDS=$17. This positions the first line of +; the active display period at line 25 of the frame. An RCR value of $0040 +; (zero) causes an interrupt at line 25, and a value of $0146 (262) causes an +; interrupt at line 24 of the next frame. +; +; Any other RCR values that are out of range ($00-$3F, $147-$3FF) will never +; result in a successful line compare. + +vbl_init_scroll .proc + + clx ; Active List index + ldy #$FF ; Scroll List index + +.region_loop: iny ; Scroll List index + cpy #HUC_NUM_SCROLLS + bcs .last_region + +.next_region: lda scroll_crl, y ; Add all the enabled Scroll + and #SCROLL_IRQ ; regions to the Active list. + beq .region_loop + + lda scroll_top, y ; Ignore the region if it is + cmp #HUC_SCR_HEIGHT ; off-screen. + bcs .region_loop + + phx ; Preserve Active List index. + +.check_unique: dex ; Check all Active List entries + bmi .is_unique ; to see if the top is the same. + cmp active_top, x + bne .check_unique + + plx ; This region has the same + bra .region_loop ; active_top as another! + +.is_unique: plx ; Restore Active List index. + + sta active_top, x ; Copy top scanline. + lda scroll_btm, y ; Copy btm scanline. + sta active_btm, x + lda scroll_crl, y ; Copy control bits. + sta active_crl, x + lda scroll_xl, y ; Copy BAT coordinates. + sta active_xl, x + lda scroll_xh, y + sta active_xh, x + lda scroll_yl, y + sta active_yl, x + lda scroll_yh, y + sta active_yh, x + + txa ; Initialize the index. + sta active_list, x + + inx + bra .region_loop + +.last_region: lda #HUC_SCR_HEIGHT ; Terminate active list. + sta active_top, x + + txa ; Initialize the index. + sta active_list, x + + pha ; Number of active regions. + + cmp #2 ; No sort needed if there are + bcc .sort_done ; less than 2 active regions. + + ; Bubble-sort the order of indexes in the Active List. + +.sort_pass: sta <__temp ; #regions left to sort. + + clv ; Reset swap flag. + + ldy #1 + +.pass_loop: ldx active_list - 1, y ; Index of previous. + lda active_top, x + + ldx active_list + 0, y ; Index of current. + cmp active_top, x + bcc .no_swap + + lda active_list - 1, y ; Swap them in the list. + sta active_list + 0, y + txa + sta active_list - 1, y + + bit #$40 ; Set V flag to signal a swap. + +.no_swap: iny ; Reached the end of the list? + cpy <__temp ; #regions left to sort. + bcc .pass_loop + bvc .sort_done ; Was there a swap last pass? + + lda <__temp ; #regions left to sort. + dec a + cmp #2 ; Is there only 1 active region + bcs .sort_pass ; left to sort? + +.sort_done: pla ; Number of active regions. + beq .finished ; No RCR if no active regions. + + ; Set up the first RCR and scroll coordinates. + + ldx active_list ; 1st region in active_list. + lda active_top, x ; Is 1st region top > line 0? + beq !+ + lda #$FF ; Start display with a gap. +!: sta active_index ; Init RCR active_list index. + + ldy active_xl, x ; Set VBL bg_x1 and bg_y1 from + sty.l bg_x1 ; the 1st scroll region. + ldy active_xh, x + sty.h bg_x1 + ldy active_yl, x + sty.l bg_y1 + ldy active_yh, x + sty.h bg_y1 + + smb7 HUC_1ST_RCR + +.finished: leave ; All done! + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; rcr_next_scroll +; +; BTM 189 GAP +; BTM+1 190 CMP TOP -> CC +; TOP 192 CMP BTM+1 -> CS +; +; BTM 190 GAP +; BTM+1 191 CMP TOP -> CC +; TOP 192 CMP BTM+1 -> CS +; +; BTM 191 NO GAP +; BTM+1 192 CMP TOP -> CS +; TOP 192 CMP BTM+1 -> CS & Z +; +; BTM 192 NO GAP +; BTM+1 193 CMP TOP -> CS +; TOP 192 CMP BTM+1 -> CC +; +; BTM 193 NO GAP +; BTM+1 194 CMP TOP -> CS +; TOP 192 CMP BTM+1 -> CC + +; ;;; ; 8 (cycles for the INT) +; bbs1 line 0. + bmi .top_is_blank ; 2 + + ldx active_list, y ; 5 X = region# of this RCR. + iny ; 2 Remember index of next RCR. + sty active_index ; 5 + lda active_list, y ; 5 Y = region# of next RCR. + tay ; 2 + + st0 #VDC_CR ; 5 + lda active_crl, x ; 5 = 121 cycles from RCR + sta VDC_DL ; 6 + + lda active_top, y ; Is next region off-screen? + cmp #HUC_SCR_HEIGHT + bcs .end_of_screen + + cmp active_btm, x ; Is there a gap before the + beq .set_next_rcr ; next region starts? + bcs .gap_next_rcr + +.set_next_rcr: st0 #VDC_RCR ; Set next RCR 1 line before + clc ; the region begins. + adc #64-1 + sta VDC_DL + cla + rol a + sta VDC_DH + +.set_scroll: st0 #VDC_BXR + lda active_xl, x + sta VDC_DL + lda active_xh, x + sta VDC_DH + + st0 #VDC_BYR + lda active_yl, x + sta VDC_DL + lda active_yh, x + sta VDC_DH + rts + +.top_is_blank: stz active_index ; Start at top next RCR. + + st0 #VDC_CR ; Disable BG & SPR before the + st1 #SCROLL_IRQ ; top of the screen. + + ldx active_list ; Set 1st RCR when the region + lda active_top, x ; actually begins. + bra .set_next_rcr + +.gap_next_rcr: dec active_index ; Repeat the current region. + lda #SCROLL_IRQ ; Disable BG & SPR in the gap. + sta active_crl, x + + lda #HUC_SCR_HEIGHT ; No gap when region repeated. + ldy active_btm, x + sta active_btm, x + tya ; Set next RCR at the start of + bra .set_next_rcr ; the gap. + +.end_of_screen: ldy active_btm, x ; Does the current region stop + cpy #HUC_SCR_HEIGHT ; before the screen ends? + bcc .gap_next_rcr + + st0 #VDC_RCR ; Stop further RCRs by setting + st1 #0 ; a value that is never taken. + st2 #0 + bra .set_scroll diff --git a/include/hucc/hucc-old-scroll.h b/include/hucc/hucc-old-scroll.h new file mode 100644 index 00000000..bd775542 --- /dev/null +++ b/include/hucc/hucc-old-scroll.h @@ -0,0 +1,47 @@ +#ifndef _hucc_old_scroll_h +#define _hucc_old_scroll_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-old-scroll.h +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; HuC's old scrolling library is provided for use with existing HuC projects, +; but it should preferably be avoided in new projects because it is slow and +; forever limited by its choice to handle gaps between areas, and sorting. +; +; HuCC's new scrolling library puts the responibility for defining both gaps +; and the display order into the project's hands, but in return it runs much +; faster, using less than 1/6 of the processing time in VBLANK, and far less +; time in the RCR interrputs themselves. It also supports the 2nd SuperGRAFX +; screen layer, which HuC's old scrolling library ignores. +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Functions in hucc-old-scroll.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_OLD_SCROLL 1 + +extern void __fastcall __xsafe scroll( unsigned char num<_al>, unsigned int x<_cx>, unsigned int y<_dx>, unsigned char top<_ah>, unsigned char bottom<_bl>, unsigned char disp ); +extern void __fastcall __xsafe scroll_disable( unsigned char num ); + +#endif // __HUCC__ + +#endif // _hucc_old_scroll_h diff --git a/include/hucc/hucc-old-spr.asm b/include/hucc/hucc-old-spr.asm new file mode 100644 index 00000000..fe4bc07c --- /dev/null +++ b/include/hucc/hucc-old-spr.asm @@ -0,0 +1,579 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-old-spr.asm +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** + +; +; Include dependancies ... +; + + include "common.asm" ; Common helpers. + include "vce.asm" ; Useful VCE routines. + include "vdc.asm" ; Useful VCE routines. + + + +; *************************************************************************** +; *************************************************************************** +; +; HuC Sprite Functions +; +; *************************************************************************** +; *************************************************************************** + + .zp +spr_ptr: ds 2 + .bss +spr_sat: ds 512 + .code + + .if SUPPORT_SGX + .zp +sgx_spr_ptr: ds 2 + .bss +sgx_spr_sat: ds 512 ; N.B. Directly after spr_sat! + .code + .endif + +; Moved to hucc-old-map.asm just to save space. This NEEDS to be changed! +; +; .bss +;spr_max: ds 1 +;spr_clr: ds 1 +; .if SUPPORT_SGX +;sgx_spr_max: ds 1 +;sgx_spr_clr: ds 1 +; .endif +; .code + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe init_satb( void ); +; void __fastcall __xsafe reset_satb( void ); +; +; void __fastcall __xsafe sgx_init_satb( void ); +; void __fastcall __xsafe sgx_reset_satb( void ); + +_reset_satb: +_init_satb: cly + cla +!: sta spr_sat + $0000, y + sta spr_sat + $0100, y + iny + bne !- + sty spr_max + iny + sty spr_clr + rts + + .if SUPPORT_SGX +_sgx_reset_satb: +_sgx_init_satb: cly + cla +!: sta sgx_spr_sat + $0000, y + sta sgx_spr_sat + $0100, y + iny + bne !- + sty sgx_spr_max + iny + sty sgx_spr_clr + rts + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe satb_update( void ); +; void __fastcall __xsafe sgx_satb_update( void ); + +old_satb_group .procgroup + + .if SUPPORT_SGX + .proc _sgx_satb_update + + ldy #SGX_VDC_OFFSET ; Offset to SGX VDC. + db $F0 ; Turn "cly" into a "beq". + + .ref _satb_update + .endp + .endif + + .proc _satb_update + + cly ; Offset to PCE VDC. + + phx ; Preserve X (aka __sp). + sxy ; Put VDC offset in X. + + lda.h #$7F00 ; HuC puts the SAT here in VRAM +; lda.h #$0800 ; but we put it here instead + stz.l <_di + sta.h <_di + jsr set_di_to_mawr + + .if SUPPORT_SGX + txa ; Select which VDC to write + inc a ; to. + inc a + sta.l ram_tia_dst + .endif + + lda #VRAM_XFER_SIZE ; Split into 16-byte chunks + sta.l ram_tia_len ; for stable IRQ response. + + ldy spr_max, x ; Highest sprite that was set. + iny + + lda spr_clr, x + beq !+ + stz spr_clr, x + ldy #64 + +!: tya + beq .exit + + dec a ; round up to the next group of 2 sprites + lsr a + .if VRAM_XFER_SIZE == 32 + lsr a + .endif + inc a + tay + + lda.h #spr_sat + + .if SUPPORT_SGX + cpx #0 + beq !+ + + lda.h #sgx_spr_sat + .endif + +!: sta.h ram_tia_src + + lda.l #spr_sat ; Same for SGX and PCE! +.chunk_loop: sta.l ram_tia_src + + jsr ram_tia ; transfer 16-bytes + + clc ; increment source + adc #VRAM_XFER_SIZE + bcc .same_page + inc.h ram_tia_src + +.same_page: dey + bne .chunk_loop + +.exit: plx ; Restore X. + + leave + + .endp + + .endprocgroup ; old_satb_group + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe spr_set( unsigned char num ); + +_spr_set.1: cmp spr_max + bcc !+ + sta spr_max +!: ldy.h #spr_sat + asl a + asl a + asl a + bcc !+ + iny + clc +!: adc.l #spr_sat + sta.l ); + +_spr_x.1: phy + clc + adc #32 + ldy #2 + sta [spr_ptr], y + pla + adc #0 + iny + sta [spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe spr_y( unsigned int value ); + +_spr_y.1: clc + adc #64 + sta [spr_ptr] + tya + adc #0 + ldy #1 + sta [spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe spr_pattern( unsigned int vaddr ); + +_spr_pattern.1: sty <__temp ; zp=fedcba98 a=76543210 + asl a ; c=f zp=edcba987 a=6543210_ + rol <__temp + rol a ; c=e zp=dcba9876 a=543210_f + rol <__temp + rol a ; c=d zp=cba98765 a=43210_fe + rol <__temp + rol a ; c=4 zp=cba98765 a=3210_fed + ldy #5 + sta [spr_ptr], y + lda <__temp + dey + sta [spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe spr_ctrl( unsigned char mask<_al>, unsigned char value ); + +_spr_ctrl.2: and <_al + sta <__temp + lda <_al + eor #$FF + ldy #7 + and [spr_ptr], y + ora <__temp + sta [spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe spr_pal( unsigned char palette ) + +_spr_pal.1: and #$0F + sta <__temp + ldy #6 + lda [spr_ptr], y + and #$F0 + ora <__temp + sta [spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe spr_pri( unsigned char priority ) + +_spr_pri.1: cmp #1 + ldy #6 + lda [spr_ptr], y + and #$7F + bcc !+ + ora #$80 +!: sta [spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe spr_get_x( void ); + +_spr_get_x: sec + ldy #2 + lda [spr_ptr], y + sbc #32 + pha + iny + lda [spr_ptr], y + sbc #0 + tay + pla + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe spr_get_y( void ); + +_spr_get_y: sec + lda [spr_ptr] + sbc #64 + pha + ldy #1 + lda [spr_ptr], y + sbc #0 + tay + pla + rts + + + + .if SUPPORT_SGX + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe sgx_spr_set( unsigned char num ); + +_sgx_spr_set.1: cmp sgx_spr_max + bcc !+ + sta sgx_spr_max +!: ldy.h #sgx_spr_sat + asl a + asl a + asl a + bcc !+ + iny + clc +!: adc.l #sgx_spr_sat + sta.l ); + +_sgx_spr_x.1: phy + clc + adc #32 + ldy #2 + sta [sgx_spr_ptr], y + pla + adc #0 + iny + sta [sgx_spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe sgx_spr_y( unsigned int value ); + +_sgx_spr_y.1: clc + adc #64 + sta [sgx_spr_ptr] + tya + adc #0 + ldy #1 + sta [sgx_spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe sgx_spr_pattern( unsigned int vaddr ); + +_sgx_spr_pattern.1: + sty <__temp ; zp=fedcba98 a=76543210 + asl a ; c=f zp=edcba987 a=6543210_ + rol <__temp + rol a ; c=e zp=dcba9876 a=543210_f + rol <__temp + rol a ; c=d zp=cba98765 a=43210_fe + rol <__temp + rol a ; c=4 zp=cba98765 a=3210_fed + ldy #5 + sta [sgx_spr_ptr], y + lda <__temp + dey + sta [sgx_spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe sgx_spr_ctrl( unsigned char mask<_al>, unsigned char value ); + +_sgx_spr_ctrl.2:and <_al + sta <__temp + lda <_al + eor #$FF + ldy #7 + and [sgx_spr_ptr], y + ora <__temp + sta [sgx_spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe sgx_spr_pal( unsigned char palette ) + +_sgx_spr_pal.1: and #$0F + sta <__temp + ldy #6 + lda [sgx_spr_ptr], y + and #$F0 + ora <__temp + sta [sgx_spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe sgx_spr_pri( unsigned char priority ) + +_sgx_spr_pri.1: cmp #1 + ldy #6 + lda [sgx_spr_ptr], y + and #$7F + bcc !+ + ora #$80 +!: sta [sgx_spr_ptr], y + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe sgx_spr_get_x( void ); + +_sgx_spr_get_x: sec + ldy #2 + lda [sgx_spr_ptr], y + sbc #32 + pha + iny + lda [sgx_spr_ptr], y + sbc #0 + tay + pla + rts + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe sgx_spr_get_y( void ); + +_sgx_spr_get_y: sec + lda [sgx_spr_ptr] + sbc #64 + pha + ldy #1 + lda [sgx_spr_ptr], y + sbc #0 + tay + pla + rts + + .endif SUPPORT_SGX diff --git a/include/hucc/hucc-old-spr.h b/include/hucc/hucc-old-spr.h new file mode 100644 index 00000000..9d447dc2 --- /dev/null +++ b/include/hucc/hucc-old-spr.h @@ -0,0 +1,84 @@ +#ifndef _hucc_old_spr_h +#define _hucc_old_spr_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-old-spr.h +; +; Based on the original HuC and MagicKit functions by David Michel and the +; other original HuC developers. +; +; Modifications copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Sprite defines ... +// ************* + +#define FLIP_X_MASK 0x08 +#define FLIP_Y_MASK 0x80 +#define FLIP_MAS 0x88 +#define SIZE_MAS 0x31 + +#define NO_FLIP 0x00 +#define NO_FLIP_X 0x00 +#define NO_FLIP_Y 0x00 +#define FLIP_X 0x08 +#define FLIP_Y 0x80 +#define SZ_16x16 0x00 +#define SZ_16x32 0x10 +#define SZ_16x64 0x30 +#define SZ_32x16 0x01 +#define SZ_32x32 0x11 +#define SZ_32x64 0x31 + +// ************* +// Functions in hucc-old-spr.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_OLD_SPR 1 + +extern void __fastcall __xsafe init_satb( void ); +extern void __fastcall __xsafe reset_satb( void ); +extern void __fastcall __xsafe satb_update( void ); +extern void __fastcall __xsafe spr_set( unsigned char num ); +extern void __fastcall __xsafe spr_hide( void ); +extern void __fastcall __xsafe spr_show( void ); +extern void __fastcall __xsafe spr_x( unsigned int value ); +extern void __fastcall __xsafe spr_y( unsigned int value ); +extern void __fastcall __xsafe spr_pattern( unsigned int vaddr ); +extern void __fastcall __xsafe spr_ctrl( unsigned char mask<_al>, unsigned char value ); +extern void __fastcall __xsafe spr_pal( unsigned char palette ); +extern void __fastcall __xsafe spr_pri( unsigned char priority ); + +extern unsigned int __fastcall __xsafe spr_get_x( void ); +extern unsigned int __fastcall __xsafe spr_get_y( void ); + +extern void __fastcall __xsafe sgx_init_satb( void ); +extern void __fastcall __xsafe sgx_reset_satb( void ); +extern void __fastcall __xsafe sgx_satb_update( void ); +extern void __fastcall __xsafe sgx_spr_set( unsigned char num ); +extern void __fastcall __xsafe sgx_spr_hide( void ); +extern void __fastcall __xsafe sgx_spr_show( void ); +extern void __fastcall __xsafe sgx_spr_x( unsigned int value ); +extern void __fastcall __xsafe sgx_spr_y( unsigned int value ); +extern void __fastcall __xsafe sgx_spr_pattern( unsigned int vaddr ); +extern void __fastcall __xsafe sgx_spr_ctrl( unsigned char mask<_al>, unsigned char value ); +extern void __fastcall __xsafe sgx_spr_pal( unsigned char palette ); +extern void __fastcall __xsafe sgx_spr_pri( unsigned char priority ); + +extern unsigned int __fastcall __xsafe sgx_spr_get_x( void ); +extern unsigned int __fastcall __xsafe sgx_spr_get_y( void ); + +#endif // __HUCC__ + +#endif // _hucc_old_spr_h diff --git a/include/hucc/hucc-scroll.asm b/include/hucc/hucc-scroll.asm new file mode 100644 index 00000000..50f45ec9 --- /dev/null +++ b/include/hucc/hucc-scroll.asm @@ -0,0 +1,635 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-scroll.asm +; +; Routines for a fast split-screen scrolling system. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** + + + + .ifndef HUCC_PCE_SPLITS +HUCC_PCE_SPLITS = 8 ; #splits on foreground layer. + .endif + + .ifndef HUCC_SGX_SPLITS +HUCC_SGX_SPLITS = 8 ; #splits on background layer. + .endif + + .if (HUCC_PCE_SPLITS < 2) || (HUCC_PCE_SPLITS > 128) + .fail HUCC_PCE_SPLITS must be >= 2 and <= 128 + .endif + + .if (HUCC_SGX_SPLITS < 2) || (HUCC_SGX_SPLITS > 128) + .fail HUCC_SGX_SPLITS must be >= 2 and <= 128 + .endif + +HUCC_1ST_RCR = $144 +HUCC_SCR_HEIGHT = 224 + + .code + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe scroll_split( unsigned char index<_al>, unsigned char top<_ah>, unsigned int x<_bx>, unsigned int y<_cx>, unsigned char disp<_dl> ); +; void __fastcall __xsafe sgx_scroll_split( unsigned char index<_al>, unsigned char top<_ah>, unsigned int x<_bx>, unsigned int y<_cx>, unsigned char disp<_dl> ); +; +; set screen scrolling + + .proc _scroll_split.5 + + ldy <_al ; Region number. + cpy #HUCC_PCE_SPLITS +.hang: bcs .hang ; Better a hang than a crash! + + lda vdc_region_sel, y ; Update the parameter copy + bne .regionA ; that is not displayed now. + +.regionB: lda <_ah ; Scanline (i.e. top). + cmp #HUCC_SCR_HEIGHT ; Skip if offscreen. + bcs !done+ + sta vdc_regionB_rcr, y + + cmp #0 ; Either Y at top of the frame + beq !+ ; or Y-1 because the RCR code + clc ; sets it on the line before. +!: lda.l <_cx + sbc #0 + sta vdc_regionB_yl, y + lda.h <_cx + sbc #0 + sta vdc_regionB_yh, y + + lda.l <_bx + sta vdc_regionB_xl, y + lda.h <_bx + sta vdc_regionB_xh, y + + lda <_dl ; Flags (mark it as enabled). + and #$C0 + ora #$0C + sta vdc_regionB_crl, y + + lda #1 ; Update last so there is no + sta vdc_region_sel, y ; need to disable irqs. + +!done: leave ; All done! + +.regionA: lda <_ah ; Scanline (i.e. top). + cmp #HUCC_SCR_HEIGHT ; Skip if offscreen. + bcs !done+ + sta vdc_regionA_rcr, y + + cmp #0 ; Either Y at top of the frame + beq !+ ; or Y-1 because the RCR code + clc ; sets it on the line before. +!: lda.l <_cx + sbc #0 + sta vdc_regionA_yl, y + lda.h <_cx + sbc #0 + sta vdc_regionA_yh, y + + lda.l <_bx + sta vdc_regionA_xl, y + lda.h <_bx + sta vdc_regionA_xh, y + + lda <_dl ; Flags (mark it as enabled). + and #$C0 + ora #$0C + sta vdc_regionA_crl, y + + cla ; Update last so there is no + sta vdc_region_sel, y ; need to disable irqs. + +!done: leave ; All done! + + .endp + + .if SUPPORT_SGX + + .proc _sgx_scroll_split.5 + + ldy <_al ; Region number. + cpy #HUCC_SGX_SPLITS +.hang: bcs .hang ; Better a hang than a crash! + + lda sgx_region_sel, y ; Update the parameter copy + bne .regionA ; that is not displayed now. + +.regionB: lda <_ah ; Scanline (i.e. top). + cmp #HUCC_SCR_HEIGHT ; Skip if offscreen. + bcs !done+ + sta sgx_regionB_rcr, y + + cmp #0 ; Either Y at top of the frame + beq !+ ; or Y-1 because the RCR code + clc ; sets it on the line before. +!: lda.l <_cx + sbc #0 + sta sgx_regionB_yl, y + lda.h <_cx + sbc #0 + sta sgx_regionB_yh, y + + lda.l <_bx + sta sgx_regionB_xl, y + lda.h <_bx + sta sgx_regionB_xh, y + + lda <_dl + and #$C0 ; Flags (mark it as enabled). + ora #$0C + sta sgx_regionB_crl, y + + lda #1 ; Update last so there is no + sta sgx_region_sel, y ; need to disable irqs. + +!done: leave ; All done! + +.regionA: lda <_ah ; Scanline (i.e. top). + cmp #HUCC_SCR_HEIGHT ; Skip if offscreen. + bcs !done+ + sta sgx_regionA_rcr, y + + cmp #0 ; Either Y at top of the frame + beq !+ ; or Y-1 because the RCR code + clc ; sets it on the line before. +!: lda.l <_cx + sbc #0 + sta sgx_regionA_yl, y + lda.h <_cx + sbc #0 + sta sgx_regionA_yh, y + + lda.l <_bx + sta sgx_regionA_xl, y + lda.h <_bx + sta sgx_regionA_xh, y + + lda <_dl + and #$C0 ; Flags (mark it as enabled). + ora #$0C + sta sgx_regionA_crl, y + + cla ; Update last so there is no + sta sgx_region_sel, y ; need to disable irqs. + +!done: leave ; All done! + + .endp + + .endif SUPPORT_SGX + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe disable_split( unsigned char index ); +; void __fastcall __xsafe sgx_disable_split( unsigned char index ); +; +; disable screen scrolling for a scroll region + +_disable_split.1: + cmp #HUCC_PCE_SPLITS +.hang: bcs .hang ; Better a hang than a crash! + sax + + ldy vdc_region_sel, x ; Update the parameter copy + bne .regionA ; that is not displayed now. + +.regionB: stz vdc_regionB_crl, x ; Region disabled if $00. + + inc vdc_region_sel, x ; Update last so there is no + tax ; need to disable irqs. + rts + +.regionA: stz vdc_regionA_crl, x ; Region disabled if $00. + + stz vdc_region_sel, x ; Update last so there is no + tax ; need to disable irqs. + rts + + .if SUPPORT_SGX + +_sgx_disable_split.1: + cmp #HUCC_SGX_SPLITS +.hang: bcs .hang ; Better a hang than a crash! + sax + + ldy sgx_region_sel, x ; Update the parameter copy + bne .regionA ; that is not displayed now. + +.regionB: stz sgx_regionB_crl, x ; Region disabled if $00. + + inc sgx_region_sel, x ; Update last so there is no + tax ; need to disable irqs. + rts + +.regionA: stz sgx_regionA_crl, x ; Region disabled if $00. + + stz sgx_region_sel, x ; Update last so there is no + tax ; need to disable irqs. + rts + + .endif SUPPORT_SGX + + + +; *************************************************************************** +; *************************************************************************** +; +; vbl_init_scroll +; +; From Charles MacDonald's pcetech.txt ... +; +; Raster Compare Register (RCR): +; +; The range of the RCR is 263 lines, relative to the start of the active +; display period. (defined by VSW, VDS, and VCR) The VDC treats the first +; scanline of the active display period as $0040, so the valid ranges for +; the RCR register are $0040 to $0146. +; +; For example, assume VSW=$02, VDS=$17. This positions the first line of +; the active display period at line 25 of the frame. An RCR value of $0040 +; (zero) causes an interrupt at line 25, and a value of $0146 (262) causes an +; interrupt at line 24 of the next frame. +; +; Any other RCR values that are out of range ($00-$3F, $147-$3FF) will never +; result in a successful line compare. +; +; Memory used is 15 bytes per scroll per VDC! +; +; Old HuC rcr_init: 2148 cycles if all 8 regions pre-sorted +; Old HuC rcr_init: 4346 cycles if all 8 regions need sorting +; +; New HuCC vbl_init_scroll: 8 disabled splits: 246 cycles +; New HuCC vbl_init_scroll: 8 enabled splits: 340 cycles +; +; New HuCC vbl_init_scroll: 16 disabled splits: 422 cycles +; New HuCC vbl_init_scroll: 16 enabled splits: 588 cycles +; +; New HuCC vbl_init_scroll: 32 disabled splits: 774 cycles +; New HuCC vbl_init_scroll: 32 enabled splits: 1084 cycles +; +; New HuCC vbl_init_scroll: 64 disabled splits: 1478 cycles +; New HuCC vbl_init_scroll: 64 enabled splits: 2076 cycles +; +; New HuCC vbl_init_scroll: 128 disabled splits: 2886 cycles +; New HuCC vbl_init_scroll: 128 enabled splits: 4060 cycles + + .bss + +vdc_region_sel: .ds HUCC_PCE_SPLITS ; Use A or B region next frame? + +vdc_regionA_crl:.ds HUCC_PCE_SPLITS ; Two copies of each setting +vdc_regionB_crl:.ds HUCC_PCE_SPLITS ; HUCC_PCE_SPLITS bytes apart. +vdc_regionA_rcr:.ds HUCC_PCE_SPLITS +vdc_regionB_rcr:.ds HUCC_PCE_SPLITS +vdc_regionA_xl: .ds HUCC_PCE_SPLITS +vdc_regionB_xl: .ds HUCC_PCE_SPLITS +vdc_regionA_xh: .ds HUCC_PCE_SPLITS +vdc_regionB_xh: .ds HUCC_PCE_SPLITS +vdc_regionA_yl: .ds HUCC_PCE_SPLITS +vdc_regionB_yl: .ds HUCC_PCE_SPLITS +vdc_regionA_yh: .ds HUCC_PCE_SPLITS +vdc_regionB_yh: .ds HUCC_PCE_SPLITS + +vdc_next_region:.ds 1 ; Linked list of region indexes +vdc_regionA_nxt:.ds HUCC_PCE_SPLITS ; for the current frame. +vdc_regionB_nxt:.ds HUCC_PCE_SPLITS + + .if SUPPORT_SGX + +sgx_region_sel: .ds HUCC_SGX_SPLITS ; Use A or B region next frame? + +sgx_regionA_crl:.ds HUCC_SGX_SPLITS ; Two copies of each setting +sgx_regionB_crl:.ds HUCC_SGX_SPLITS ; HUCC_SGX_SPLITS bytes apart. +sgx_regionA_rcr:.ds HUCC_SGX_SPLITS +sgx_regionB_rcr:.ds HUCC_SGX_SPLITS +sgx_regionA_xl: .ds HUCC_SGX_SPLITS +sgx_regionB_xl: .ds HUCC_SGX_SPLITS +sgx_regionA_xh: .ds HUCC_SGX_SPLITS +sgx_regionB_xh: .ds HUCC_SGX_SPLITS +sgx_regionA_yl: .ds HUCC_SGX_SPLITS +sgx_regionB_yl: .ds HUCC_SGX_SPLITS +sgx_regionA_yh: .ds HUCC_SGX_SPLITS +sgx_regionB_yh: .ds HUCC_SGX_SPLITS + +sgx_next_region:.ds 1 ; Linked list of region indexes +sgx_regionA_nxt:.ds HUCC_SGX_SPLITS ; for the current frame. +sgx_regionB_nxt:.ds HUCC_SGX_SPLITS + + .endif + + .code + +vbl_init_scroll .proc + + lda #$FF ; A = previous active index + ldx #HUCC_PCE_SPLITS ; so $FF for end-of-screen. + + clc ; For regionB indexes. + +!next_region: dex ; All regions updated? + bmi !save_first+ + + ldy vdc_region_sel, x ; 0=regionA or 1=regionB. + beq !use_regionA+ + +!use_regionB: ldy vdc_regionB_crl, x ; Region disabled if $00. + beq !next_region- + sta vdc_regionB_nxt, x ; Save index of next region. + txa ; A = current region index. + adc #HUCC_PCE_SPLITS ; Always leaves CC! + bra !next_region- + +!use_regionA: ldy vdc_regionA_crl, x ; Region disabled if $00. + beq !next_region- + sta vdc_regionA_nxt, x ; Save index of next region. + txa ; A = current region index. + bra !next_region- + +!save_first: sta vdc_next_region ; Save index of 1st region. + tax ; $FF if no active regions. + bmi !+ + + smb7 , unsigned char top<_ah>, unsigned int x<_bx>, unsigned int y<_cx>, unsigned char disp<_dl> ); +extern void __fastcall __xsafe sgx_scroll_split( unsigned char index<_al>, unsigned char top<_ah>, unsigned int x<_bx>, unsigned int y<_cx>, unsigned char disp<_dl> ); + +extern void __fastcall __xsafe disable_split( unsigned char index ); +extern void __fastcall __xsafe sgx_disable_split( unsigned char index ); + +#endif // __HUCC__ + +#endif // _hucc_scroll_h diff --git a/include/hucc/hucc-sound.inc b/include/hucc/hucc-sound.inc new file mode 100644 index 00000000..7cace123 --- /dev/null +++ b/include/hucc/hucc-sound.inc @@ -0,0 +1,54 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-sound.inc +; +; Included by STARTUP.ASM to customize the sound driver. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; A customized sound driver for HuCard or CDROM usage can create a +; version of this file, and then have startup.asm use the new +; definitions just by including the new sound driver's path +; in the PCE_INCLUDE environment variable BEFORE the standard +; "include/hucc" path. +; +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; +; Tell startup.asm that we need the SOUND_BANK and to include sound.asm + +NEED_SOUND_BANK = 0 + + + +; *************************************************************************** +; *************************************************************************** +; +; The driver might wish to reserve some extra banks, or it can just let the +; actual project do it in hucc-config.inc + +; RESERVE_BANKS = 0 + + + +; *************************************************************************** +; *************************************************************************** +; +; This macro is invoked in hucc.asm just after the RAM is cleared, and before +; interrupts are enabled. + +__sound_init .macro + .endm diff --git a/include/hucc/hucc-string.asm b/include/hucc/hucc-string.asm new file mode 100644 index 00000000..55dc565f --- /dev/null +++ b/include/hucc/hucc-string.asm @@ -0,0 +1,377 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-string.asm +; +; Not-quite-standard, but fast, replacements for . +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; !!! WARNING : non-standard return values !!! +; +; Strings are limited to a maximum of 255 characters (+ the terminator)! +; +; The memcpy(), strcpy() and strcat() functions do NOT return the destination +; address, and they are declared "void" to check that the value is not used. +; +; mempcpy() is provided which returns the end address instead of the starting +; address, because this is typically more useful. +; +; Please note that both memcpy() and memset() are implemented using a TII for +; speed, and so the length should be < 16 bytes if used in time-critical bits +; of code (such as when using a split screen) because they delay interrupts. +; +; strncpy() and strncat() are not provided, because strncpy() was not created +; for the purpose of avoiding string overruns, and strncat() is just a poorly +; designed function. +; +; POSIX strlcpy() and strlcat() are provided instead, but once again they are +; slightly non-standard in that the return value when there is an overflow is +; the buffer size (so that the overflow can be detected), instead of the full +; size of the destination string that was too big to fit in the buffer. +; +; *************************************************************************** +; *************************************************************************** + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe strcpy( char *destination<_di>, char *source<_bp> ); +; void __fastcall __xsafe strcat( char *destination<_di>, char *source<_bp> ); +; +; unsigned int __fastcall __xsafe strlcpy( char *destination<_di>, char *source<_bp>, unsigned char size ); +; unsigned int __fastcall __xsafe strlcat( char *destination<_di>, char *source<_bp>, unsigned char size ); +; unsigned int __fastcall __xsafe strlen( char *source<_bp> ); +; +; NOT WORKING YET (needs compiler changes) ... +; +; void __fastcall __xsafe strcpy( char *destination<_di>, char __far *source<_bp_bank:_bp> ); +; void __fastcall __xsafe strcat( char *destination<_di>, char __far *source<_bp_bank:_bp> ); +; +; unsigned int __fastcall __xsafe strlcpy( char *destination<_di>, char __far *source<_bp_bank:_bp>, unsigned char size ); +; unsigned int __fastcall __xsafe strlcat( char *destination<_di>, char __far *source<_bp_bank:_bp>, unsigned char size ); +; unsigned int __fastcall __xsafe strlen( char __far *source<_bp_bank:_bp> ); + +_strcat: cla ; Max string length == 256! + ldy.h #256 + +_strlcat: phx ; Preserve X (aka __sp). + tax ; X = buffer length (1..256). + + .ifdef _DEBUG + bne !+ ; Sanity check buffer length. + dey +!: tya +.hang: bne .hang ; Hang if 1 > buffer length > 256. + .endif + + tma3 ; Preserve MPR3 and MPR4. + pha + tma4 + pha + +; ldy <_bp_bank ; Map the source string. + ldy #0 ; Map the source memory. + beq .no_bank + jsr set_bp_to_mpr34 + +.no_bank: cly + +.find: lda [_di], y ; Find the end of the string. + beq .adjust + iny + dex + bne .find + tya ; A:Y = buffer length. + cla + bra str_overflow + +.adjust: tya ; Subtract Y from _bp so that + eor #$FF ; _bp and _di use the same Y. + sec + adc.l <_bp + sta.l <_bp + bcs str_copy + dec.h <_bp + bra str_copy + + ; + +_strcpy: cla ; Max string length == 256! + ldy.h #256 + +_strlcpy: phx ; Preserve X (aka __sp). + tax ; X = buffer length (1..256). + + .ifdef _DEBUG + bne !+ ; Sanity check buffer length. + dey +!: tya +.hang: bne .hang ; Hang if 1 > buffer length > 256. + .endif + + tma3 ; Preserve MPR3 and MPR4. + pha + tma4 + pha + +; ldy <_bp_bank ; Map the source string. + ldy #0 ; Map the source memory. + beq .no_bank + jsr set_bp_to_mpr34 + +.no_bank: cly + +str_copy: lda [_bp], y + sta [_di], y + beq str_exit ; A:Y = string length. + iny + dex + bne str_copy + + dey + cla + sta [_di], y + iny ; A:Y = buffer length. +str_overflow: bne str_exit + inc a ; A:Y = buffer length = 256. + bra str_exit + + ; + +_strlen: phx ; Preserve X (aka __sp). + + tma3 + pha + tma4 + pha + +; ldy <_bp_bank + ldy #0 ; Map the source memory. + beq .no_bank + jsr set_bp_to_mpr34 + +.no_bank: cly + +.find: lda [_bp], y + beq str_exit + iny + bne .find + lda.h #256 ; A:Y = overflow length = 256. + +str_exit: tax ; X:Y = string or buffer length. + + pla ; Restore MPR3 and MPR4. + tam4 + pla + tam3 + + txa ; A:Y = string or buffer length. + say ; Y:A = string or buffer length. + + plx ; Restore X (aka __sp). + rts + + .alias _strlen.1 = _strlen + .alias _strcpy.2 = _strcpy + .alias _strcat.2 = _strcat + .alias _strlcpy.3 = _strlcpy + .alias _strlcat.3 = _strlcat + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe memcpy( unsigned char *destination, unsigned char *source, unsigned int count ); +; unsigned char * __fastcall __xsafe mempcpy( unsigned char *destination, unsigned char *source, unsigned int count ); +; +; NOT WORKING YET (needs compiler changes) ... +; void __fastcall __xsafe memcpy( unsigned char *destination, unsigned char __far *source<_bp_bank:ram_tii_src>, unsigned int count ); +; unsigned char * __fastcall __xsafe mempcpy( unsigned char *destination, unsigned char __far *source<_bp_bank:ram_tii_src>, unsigned int count ); + +_memcpy: +_mempcpy: sty.h ram_tii_len ; Check for zero length. + sta.l ram_tii_len + ora.h ram_tii_len + beq .zero_length + + tma3 ; Preserve MPR3 and MPR4. + pha + tma4 + pha + +; ldy <_bp_bank ; Map the source memory. + ldy #0 ; Map the source memory. + beq .no_bank + + lda.h ram_tii_src + cmp #$60 + bcc .no_bank + and #$1F ; Remap ptr to MPR3. + ora #$60 + sta.h ram_tii_src + + tya ; Put bank into MPR3. + tam3 + inc a ; Put next into MPR4. + tam4 + +.no_bank: jsr ram_tii ; Copy the memory. + + pla ; Restore MPR3 and MPR4. + tam4 + pla + tam3 + +.zero_length: clc ; Return the end address + lda.l ram_tii_dst ; like mempcpy(). + adc.l ram_tii_len + tay + lda.h ram_tii_dst + adc.h ram_tii_len + say + + rts + + .alias _memcpy.3 = _memcpy + .alias _mempcpy.3 = _mempcpy + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe memset( unsigned char *destination, unsigned char value<_al>, unsigned int count ); + +_memset: cmp #0 ; Decrement the length, check + bne !+ ; for zero and set C. + cpy #0 + beq .zero_length + dey +!: dec a + sta.l ram_tii_len + sty.h ram_tii_len + + lda.l ram_tii_src ; ram_tii_dst = ram_tii_src + 1 + sta.l <__ptr + adc #0 + sta.l ram_tii_dst + lda.h ram_tii_src + sta.h <__ptr + adc #0 + sta.h ram_tii_dst + + lda <_al ; Set the fill value. + sta [__ptr] + + jmp ram_tii ; Copy the memory. + +.zero_length: rts + + .alias _memset.3 = _memset + + + +; *************************************************************************** +; *************************************************************************** +; +; int __fastcall strcmp( char *destination<_di>, char *source<_bp> ); +; int __fastcall strncmp( char *destination<_di>, char *source<_bp>, unsigned int count<_ax> ); +; int __fastcall memcmp( unsigned char *destination<_di>, unsigned char *source<_bp>, unsigned int count<_ax> ); +; +; NOT WORKING YET (needs compiler changes) ... +; +; int __fastcall strcmp( char *destination<_di>, char __far *source<_bp_bank:_bp> ); +; int __fastcall strncmp( char *destination<_di>, char __far *source<_bp_bank:_bp>, unsigned char count<_al> ); +; int __fastcall memcmp( unsigned char *destination<_di>, unsigned char __far *source<_bp_bank:_bp>, unsigned int count<_ax> ); +; +; 0 if strings are equal +; 1 if the first non-matching character in string1 > string2 (in ASCII). +; -1 if the first non-matching character in string1 < string2 (in ASCII). + +hucc_memcmp .procgroup + +_strcmp .proc + stz.l <_ax ; Max string length == 256! + lda.h #256 + sta.h <_ax + .ref _strncmp ; Don't strip _strncmp.3! + .endp ; Fall through. + +_strncmp .proc + bit #$40 ; Set the V bit for strcmp. + db $50 ; Turn "clv" into "bvc". + .ref _memcmp ; Don't strip _memcmp.3! + .endp ; Fall through. + +_memcmp .proc + clv ; Clr the V bit for memcmp. + + tma3 ; Preserve MPR3 and MPR4. + pha + tma4 + pha + +; ldy <_bp_bank ; Map the source string. + ldy #0 ; Map the source memory. + beq .no_bank + jsr set_bp_to_mpr34 + +.no_bank: cly + + ldx.l <_ax ; Increment length.l + inx +.loop: dex ; Decrement length.l + beq .page +.test: lda [_di], y ; string1 - string2 + cmp [_bp], y + bcc .return_neg ; string1 < string2 + bne .return_pos ; string1 > string2 + bvc !+ ; Only check for end-of-string + cmp #0 ; if the V flag is set. + beq .return_same +!: iny + bne .loop + inc.h <_di + jsr inc.h_bp_mpr34 + bra .loop + +.page: dec.h <_ax ; Decrement length.h + bpl .test ; Limit comparison to 32KB. +; bra cmp_same + +.return_same: clx ; Return code in Y:X, X -> A. + cly + bra !+ + +.return_pos: ldx #$01 ; Return code in Y:X, X -> A. + cly + bra !+ + +.return_neg: ldx #$FF ; Return code in Y:X, X -> A. + ldy #$FF + +!: pla ; Restore MPR3 and MPR4. + tam4 + pla + tam3 + + leave ; Return and copy X -> A. + + .endp + + .endprocgroup ; hucc_memcmp + + .alias _strcmp.2 = _strcmp + .alias _strncmp.3 = _strncmp + .alias _memcmp.3 = _memcmp diff --git a/include/hucc/hucc-string.h b/include/hucc/hucc-string.h new file mode 100644 index 00000000..e3130a46 --- /dev/null +++ b/include/hucc/hucc-string.h @@ -0,0 +1,98 @@ +#ifndef _hucc_string_h +#define _hucc_string_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-string.h +; +; Not-quite-standard, but fast, replacements for . +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; !!! WARNING : non-standard return values !!! +; +; Strings are limited to a maximum of 255 characters (+ the terminator)! +; +; The memcpy(), strcpy() and strcat() functions do NOT return the destination +; address, and they are declared "void" to check that the value is not used. +; +; mempcpy() is provided which returns the end address instead of the starting +; address, because this is typically more useful. +; +; Please note that both memcpy() and memset() are implemented using a TII for +; speed, and so the length should be < 16 bytes if used in time-critical bits +; of code (such as when using a split screen) because they delay interrupts. +; +; strncpy() and strncat() are not provided, because strncpy() was not created +; for the purpose of avoiding string overruns, and strncat() is just a poorly +; designed function IMHO. +; +; POSIX strlcpy() and strlcat() are provided instead, but once again they are +; slightly non-standard in that the return value when there is an overflow is +; the buffer size (so that the overflow can be detected), instead of the full +; size of the destination string that was too big to fit in the buffer. +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Functions in hucc-string.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_STRING 1 + +#if 1 + +extern void __fastcall __xsafe strcpy( char *destination<_di>, char *source<_bp> ); +extern void __fastcall __xsafe strcat( char *destination<_di>, char *source<_bp> ); + +extern unsigned int __fastcall __xsafe strlen( char *source<_bp> ); + +extern unsigned int __fastcall __xsafe strlcpy( char *destination<_di>, char *source<_bp>, unsigned char size ); +extern unsigned int __fastcall __xsafe strlcat( char *destination<_di>, char *source<_bp>, unsigned char size ); + +extern void __fastcall __xsafe memcpy( unsigned char *destination, unsigned char *source, unsigned int count ); +extern unsigned char * __fastcall __xsafe mempcpy( unsigned char *destination, unsigned char *source, unsigned int count ); + +extern void __fastcall __xsafe memset( unsigned char *destination, unsigned char value<_al>, unsigned int count ); + +extern int __fastcall strcmp( char *destination<_di>, char *source<_bp> ); +extern int __fastcall strncmp( char *destination<_di>, char *source<_bp>, unsigned int count<_ax> ); +extern int __fastcall memcmp( unsigned char *destination<_di>, unsigned char *source<_bp>, unsigned int count ); + +#else + +/* NOT WORKING YET (needs compiler changes) ... */ + +extern void __fastcall __xsafe strcpy( char *destination<_di>, char __far *source<_bp_bank:_bp> ); +extern void __fastcall __xsafe strcat( char *destination<_di>, char __far *source<_bp_bank:_bp> ); + +extern unsigned int __fastcall __xsafe strlen( char __far *source<_bp_bank:_bp> ); + +extern unsigned int __fastcall __xsafe strlcpy( char *destination<_di>, char __far *source<_bp_bank:_bp>, unsigned char size ); +extern unsigned int __fastcall __xsafe strlcat( char *destination<_di>, char __far *source<_bp_bank:_bp>, unsigned char size ); + +extern void __fastcall __xsafe memcpy( unsigned char *destination, unsigned char __far *source<_bp_bank:ram_tii_src>, unsigned int count ); +extern unsigned char * __fastcall __xsafe mempcpy( unsigned char *destination, unsigned char __far *source<_bp_bank:ram_tii_src>, unsigned int count ); + +extern void __fastcall __xsafe memset( unsigned char *destination, unsigned char value<_al>, unsigned int count ); + +extern int __fastcall strcmp( char *destination<_di>, char __far *source<_bp_bank:_bp> ); +extern int __fastcall strncmp( char *destination<_di>, char __far *source<_bp_bank:_bp>, unsigned int count<_ax> ); +extern int __fastcall memcmp( unsigned char *destination<_di>, unsigned char __far *source<_bp_bank:_bp>, unsigned int count<_ax> ); + +#endif + +#endif // __HUCC__ + +#endif // _hucc_string_h diff --git a/include/hucc/hucc-systemcard.asm b/include/hucc/hucc-systemcard.asm new file mode 100644 index 00000000..be5b7a5c --- /dev/null +++ b/include/hucc/hucc-systemcard.asm @@ -0,0 +1,863 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc-systemcard.asm +; +; Macros and library functions for using the System Card. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; Because these are mainly macros, and so must be included before being used +; in compiled code, the actual functions here are written to avoid using any +; BSS memory so that HuCC's overlay global-shared-variables are not effected. +; +; *************************************************************************** +; *************************************************************************** + +; +; Standard parameters for CD-ROM system functions +; + +; These attributes are used for CD_PLAY: + +CD_SECTOR = %00000000 +CD_MSF = %01000000 +CD_TRACK = %10000000 +CD_CURRPOS = %11000000 +CD_LEADOUT = %11000000 +CD_PLAYMODE = %00111111 + +CDPLAY_MUTE = 0 +CDPLAY_REPEAT = 1 +CDPLAY_NORMAL = 2 +CDPLAY_ENDOFDISC= 0 ; XXX: really? + +CDFADE_CANCEL = 0 +CDFADE_PCM6 = 8 +CDFADE_ADPCM6 = 10 +CDFADE_PCM2 = 12 +CDFADE_ADPCM2 = 14 + +CDTRK_AUDIO = 0 +CDTRK_DATA = 4 + +GRP_FILL = 1 +GRP_NOFILL = 0 + +BM_OK = 0 +BM_NOT_FOUND = 1 +BM_BAD_CHECKSUM = 2 +BM_DIR_CORRUPTED= 3 +BM_FILE_EMPTY = 4 +BM_FULL = 5 +BM_NOT_FORMATED = $FF ; HuC incorrect spelling. +BM_NOT_FORMATTED= $FF ; HuCC can use a dictionary! + + + .bss +__bm_error .ds 1 + .code + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe __macro cd_getver( void ); + +_cd_getver .macro + phx ; Preserve X (aka __sp). + system ex_getver + txa ; Put version in A:Y + say ; Put version in Y:A + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro cd_boot( void ); + +_cd_boot .macro + system cd_boot + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro cd_reset( void ); + +_cd_reset .macro + phx ; Preserve X (aka __sp). + system cd_reset + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro cd_pause( void ); + +_cd_pause .macro + phx ; Preserve X (aka __sp). + system cd_pause + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro cd_fade( unsigned char type ); +; +; type = $00 -> cancel fade +; $08 -> PCM fadeout 6 seconds +; $0A -> ADPCM fadeout 6 seconds +; $0C -> PCM fadeout 2.5 seconds +; $0E -> ADPCM fadeout 2.5 seconds + +_cd_fade.1 .macro + phx ; Preserve X (aka __sp). + system cd_fade + plx ; Restore X (aka __sp). + .endm + + + +_cd_playgroup .procgroup ; Routines share variables. + +cdplay_end_ctl ds 1 ; saved 'cd_play end' information - type +cdplay_end_h ds 1 ; high byte of address +cdplay_end_m ds 1 ; mid byte +cdplay_end_l ds 1 ; low byte + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall cd_unpause( void ); + +_cd_unpause .proc + + lda cdplay_end_ctl + sta <_dh + lda cdplay_end_h + sta <_cl + lda cdplay_end_m + sta <_ch + lda cdplay_end_l + sta <_dl + lda #CD_CURRPOS + sta <_bh + + system cd_play + tax ; Put return code in X. + + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall cd_playtrk( +; unsigned char start_track<_bx>, unsigned char end_track<_cx>, unsigned char mode<_dh> ); +; +; mode = CDPLAY_MUTE / CDPLAY_REPEAT / CDPLAY_NORMAL + +_cd_playtrk.3 .proc + + lda <_dh + and #CD_PLAYMODE + ora #CD_TRACK + sta <_dh ; End type + play mode + sta cdplay_end_ctl + lda #CD_TRACK + sta <_bh ; Start type + + lda <_cl + bne .endtrk + +.endofdisc: lda <_dh ; Repeat to end of disc + ora #CD_LEADOUT + sta <_dh + sta cdplay_end_ctl + bra .starttrk + +.endtrk: system ex_binbcd + sta <_cl ; End track + sta cdplay_end_h + stz <_ch + stz cdplay_end_m + stz <_dl + stz cdplay_end_l + +.starttrk: lda <_bl ; Track # + system ex_binbcd + sta <_al ; From track + stz <_ah + stz <_bl + + system cd_play + tax ; Put return code in X. + + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall cd_playmsf( +; unsigned char start_minute<_al>, unsigned char start_second<_ah>, unsigned char start_frame<_bl>, +; unsigned char end_minute<_cl>, unsigned char end_second<_ch>, unsigned char end_frame<_dl>, unsigned char mode<_dh> ); +; +; mode = CDPLAY_MUTE / CDPLAY_REPEAT / CDPLAY_NORMAL + +_cd_playmsf.7 .proc + + lda <_dh + and #CD_PLAYMODE + ora #CD_MSF + sta <_dh ; End type + play mode + sta cdplay_end_ctl + lda #CD_MSF + sta <_bh ; Start type + +.endmsf: lda <_dl ; End frame + system ex_binbcd + sta <_dl + sta cdplay_end_l + + lda <_ch ; End second + system ex_binbcd + sta <_ch + sta cdplay_end_m + + lda <_cl ; End minute + system ex_binbcd + sta <_cl + sta cdplay_end_h + +.startmsf: lda <_bl ; Start frame + system ex_binbcd + sta <_bl + + lda <_ah ; Start second + system ex_binbcd + sta <_ah + + lda <_al ; Start minute + system ex_binbcd + sta <_al + + system cd_play + tax ; Put return code in X. + + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + + .endp + + .endprocgroup ; _cd_playgroup + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall cd_loadvram( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned int vramaddr<_bx>, unsigned int bytes<_ax> ); + +_cd_loadvram.4 .proc + + ldx <_cl ; Get file address and length. + jsr get_file_lba + + lda.l <_si ; Add the sector offset. + ldy.h <_si + jsr _add_sectors + + lda #$FE ; Signal a VRAM load. + sta <_dh + + system cd_read + tax ; Put return code in X. + + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall cd_loaddata( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned char __far *buffer<_bp_bank:_bp>, unsigned int bytes<__ptr> ); +; +; This is overly complicated because the HuC/MagicKit design reads 0..65535 +; bytes instead of complete sectors. + +_cd_loaddata.4 .proc + + tma3 ; Preserve MPR3 and MPR4. + pha + tma4 + pha + + ldx <_cl ; Get file's LBA (not length). + jsr get_file_lba + + lda.l <_si ; Add the sector offset. + ldy.h <_si + jsr _add_sectors + + ldy <_bp_bank ; Map data to MPR3 & MPR4. + jsr set_bp_to_mpr34 + + tii _bp, _bx, 2 ; Set destination ptr. + +.loop: ldy.l .cdread_len ; Still bytes to read? + lda.h .cdread_len + bne !+ + cpy #0 + beq .done + +!: cmp.h #$2000 ; Is there 8KB left to read? + bcc .read_end + +.read_max: sbc.h #$2000 ; Read the next 8KB of data. + sta.h .cdread_len + cly + lda.h #$2000 + bra !+ + +.read_end: stz.l .cdread_len ; Read the final data. + stz.h .cdread_len + +!: sty.l <_ax ; Set read length in bytes. + sta.h <_ax + + stz <_dh ; Signal bytes, not sectors. + + tii _bx, .cdread_ptr, 5 ; Preserve parameters. + + system cd_read + tax ; Put return code in X. + bne .done ; Exit if NZ error code. + + tii .cdread_ptr, _bx, 5 ; Restore parameters. + + lda #4 ; Add the #sectors just read. + cly + jsr _add_sectors + + tma4 ; Increment the bank. + tam3 + inc a + tam4 + + bra .loop ; Load the next chunk of data. + +.done: pla ; Restore MPR3 and MPR4. + tam4 + pla + tam3 + + cly ; Return code in Y:X, X -> A. + + leave ; Return and copy X -> A. + +.cdread_len = __ptr ; Reuse ZP location. +.cdread_ptr .ds 2 +.cdread_lba .ds 3 + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall cd_loadbank( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned char bank<_bl>, unsigned int sectors<_al> ); + +_cd_loadbank.4 .macro + phx ; Preserve X (aka __sp). + + ldx <_cl ; Get file address and length. + jsr get_file_info + + lda.l <_si ; Add the sector offset. + ldy.h <_si + jsr _add_sectors + + lda <_dh ; Get #sectors (0=whole file). + beq !+ + sta <_al + +!: lda #4 ; Use MPR4. + sta <_dh + + tma4 ; Preserve MPR4. + pha + + system cd_read + + tax ; Restore MPR4 because the + pla ; System Card function has + tam4 ; a bug which destroys the + txa ; value on a CD error. + + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro cd_status( unsigned char mode ); + +_cd_status.1 .macro + phx ; Preserve X (aka __sp). + system cd_stat + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro ad_reset( void ); + +_ad_reset .macro + phx ; Preserve X (aka __sp). + system ad_reset + plx ; Restore X (aka __sp). + .endm + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro ad_trans( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned char nb_sectors<_dh>, unsigned int ad_addr<_bx> ); + +_ad_trans.4 .macro + phx ; Preserve X (aka __sp). + ldx <_cl ; Get file address and length. + jsr get_file_info + + lda.l <_si ; Add the sector offset. + ldy.h <_si + jsr _add_sectors + + lda <_dh ; Get #sectors (0=whole file). + stz <_dh ; + beq !+ + sta <_al ; #sectors if not whole file. + +!: system ad_trans + cly + plx ; Restore X (aka __sp). + .endm + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro ad_read( unsigned int ad_addr<_cx>, unsigned char mode<_dh>, unsigned int buf<_bx>, unsigned int bytes<_ax> ); + +_ad_read.4 .macro + phx ; Preserve X (aka __sp). + system ad_read + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro ad_write( unsigned int ad_addr<_cx>, unsigned char mode<_dh>, unsigned int buf<_bx>, unsigned int bytes<_ax> ); + +_ad_write.4 .macro + phx ; Preserve X (aka __sp). + system ad_write + plx ; Restore X (aka __sp). + .endm + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro ad_play( unsigned int ad_addr<_bx>, unsigned int bytes<_ax>, unsigned char freq<_dh>, unsigned char mode<_dl> ); + +_ad_play.4 .macro + phx ; Preserve X (aka __sp). + system ad_play + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro ad_cplay( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned int nb_sectors<_bx>, unsigned char freq<_dh> ); + +_ad_cplay.4 .macro + phx ; Preserve X (aka __sp). + ldx <_cl ; Get file address and length. + jsr get_file_info + + lda.l <_si ; Add the sector offset. + ldy.h <_si + jsr _add_sectors + + lda.l <_bx ; Get #sectors (0=whole file). + ora.h <_bx + beq !+ + lda.l <_bx + ldy.h <_bx + sta.l <_ax + sty.h <_ax +!: stz <_bl ; Clear length bits 16..23. + + system ad_cplay + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe __macro ad_stop( void ); + +_ad_stop .macro + phx ; Preserve X (aka __sp). + system ad_stop + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro ad_stat( void ); + +_ad_stat .macro + phx ; Preserve X (aka __sp). + system ad_stat + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; void __fastcall __xsafe add_sectors( unsigned int sector_offset ); + +_add_sectors: clc + adc <_dl + sta <_dl + tya + adc <_ch + sta <_ch + bcc !+ + inc <_cl +!: rts + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall bm_check( void ); +; +; Determine whether BRAM exists on this system +; +; Returns 1 (TRUE) if BRAM exists, else 0 (FALSE). + +_bm_check .proc + + php ; Disable interrupts! + sei + + tma3 ; Preserve MPR3. + pha + + csl ; BRAM needs lo-speed access. + + lda #$48 ; Extended 3-byte unlock + sta IFU_BRAM_UNLOCK ; sequence for Tennokoe 2. + lda #$75 + sta IFU_BRAM_UNLOCK + lda #$80 + sta IFU_BRAM_UNLOCK + + lda #$F7 ; Map in the BRAM and shadow. + tam3 + + lda $6000 ; Confirm BRAM present. + tay + eor #$FF + sta $6000 + eor $6000 + sty $6000 + sta <__temp + + lda IFU_BRAM_LOCK ; Lock BRAM. + + pla ; Restore MPR3. + tam3 + + csh ; Restore hi-speed access. + plp ; Restore original IRQ mask. + + ldx <__temp ; $00 if BRAM exists, else NZ. + beq .done + ldx #$FF + +.done: inx ; $01 if BRAM exists, else $00. + + cly ; Return code in Y:X, X -> A. + leave ; Return and copy X -> A. + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall bm_format( void ); +; +; If BRAM is already formatted (*_PROPERLY_*) return OK, else format it. +; +; Returns either BM_OK, BM_NOT_FOUND. +; +; After return __bm_error = BM_OK, BM_NOT_FOUND. + +_bm_format .proc + + system bm_free + sta __bm_error + tax + beq .done + + lda.l #.password + sta.l <_ax + lda.h #.password + sta.h <_ax + + system bm_format + sta __bm_error + tax + beq .done + + ldx #BM_NOT_FORMATTED + +.done: stx __bm_error ; Return code in Y:X, X -> A. + cly + leave ; Return and copy X -> A. + +.password: db "!BM FORMAT!" + + .endp + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned int __fastcall __xsafe __macro bm_free( void ); +; +; Returns (int) number of user bytes available in BRAM, or 0 if error. +; +; After return __bm_error = BM_OK or BM_NOT_FORMATTED. + +_bm_free .macro + phx ; Preserve X (aka __sp). + system bm_free + sta __bm_error + tay + beq !ok+ + stz.l <_cx ; Return size 0 if error. + stz.h <_cx +!ok: lda.l <_cx + ldy.h <_cx + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro bm_read( unsigned char *buffer<_bx>, unsigned char *name<_ax>, unsigned int offset<_dx>, unsigned int length<_cx> ); +; +; Check for existence of BRAM file with a matching name +; +; Note: name is 12 bytes; first 2 bytes are a uniqueness value +; (should be zeroes), and the next 10 bytes are the ASCII name +; with trailing spaces as padding. +; +; Returns either BM_OK, BM_NOT_FOUND, BM_BAD_CHECKSUM or BM_NOT_FORMATTED. +; +; After return __bm_error = BM_OK or BM_NOT_FORMATTED. + +_bm_read.4 .macro + phx ; Preserve X (aka __sp). + system bm_read + sta __bm_error + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro bm_write( unsigned char *buffer<_bx>, unsigned char *name<_ax>, unsigned int offset<_dx>, unsigned int length<_cx> ); +; +; Given the name of a BRAM file, update some info inside of it +; +; Note: name is 12 bytes; first 2 bytes are a uniqueness value +; (should be zeroes), and the next 10 bytes are the ASCII name +; with trailing spaces as padding. +; +; Returns either BM_OK, BM_NOT_FOUND (i.e. not enough memory) or BM_NOT_FORMATTED. +; +; After return __bm_error = BM_OK, BM_NOT_FOUND (i.e. not enough memory) or BM_NOT_FORMATTED. + +_bm_write.4 .macro + phx ; Preserve X (aka __sp). + system bm_write + sta __bm_error + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro bm_delete( unsigned char *name<_ax> ); +; +; Delete the entry specified by the name provided +; +; Note: name is 12 bytes; first 2 bytes are a uniqueness value +; (should be zeroes), and the next 10 bytes are the ASCII name +; with trailing spaces as padding. +; +; Returns either BM_OK, BM_NOT_FOUND or BM_NOT_FORMATTED. +; +; After return __bm_error = BM_OK, BM_NOT_FOUND or BM_NOT_FORMATTED. + +_bm_delete.1 .macro + phx ; Preserve X (aka __sp). + system bm_delete + sta __bm_error + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro bm_exist( unsigned char *name<_ax> ); +; +; Check for existence of BRAM file with a matching name +; +; Note: name is 12 bytes; first 2 bytes are a uniqueness value +; (should be zeroes), and the next 10 bytes are the ASCII name +; with trailing spaces as padding. +; +; Returns 1 (TRUE) if the file exists and is OK, else 0 (FALSE). +; +; N.B. Pointless HuC function, it's easier to try to read the file. + +_bm_exist.1 .macro + stz.l <_bx ; Destination buffer. + stz.h <_bx + stz.l <_cx ; Length to read. + stz.h <_cx + stz.l <_dx ; Offset from start. + stz.h <_dx + phx ; Preserve X (aka __sp). + system bm_read + sta __bm_error + tay ; $00 if file OK, else NZ. + beq !done+ + lda #$FF +!done: inc a ; $01 if file OK, else $00. + cly + plx ; Restore X (aka __sp). + .endm + + + +; *************************************************************************** +; *************************************************************************** +; +; unsigned char __fastcall __xsafe __macro bm_create( unsigned char *name<_ax>, unsigned int length<_cx> ); +; +; Create a new BRAM file, given the name and size +; +; Note: name is 12 bytes; first 2 bytes are a uniqueness value +; (should be zeroes), and the next 10 bytes are the ASCII name +; with trailing spaces as padding. +; +; Returns either BM_OK, BM_NOT_FOUND (i.e. not enough memory) or BM_NOT_FORMATTED. +; +; After return __bm_error = BM_OK, BM_NOT_FOUND (i.e. not enough memory) or BM_NOT_FORMATTED. +; +; N.B. Pointless HuC function, it's easier to try to write the file. + +_bm_create.2 .macro + stz.l <_bx ; Source buffer. + lda.h #$6000 + sta.h <_bx + stz.l <_dx ; Offset from start. + stz.h <_dx + phx ; Preserve X (aka __sp). + system bm_write + sta __bm_error + cly + plx ; Restore X (aka __sp). + .endm diff --git a/include/hucc/hucc-systemcard.h b/include/hucc/hucc-systemcard.h new file mode 100644 index 00000000..c8d5a8db --- /dev/null +++ b/include/hucc/hucc-systemcard.h @@ -0,0 +1,125 @@ +#ifndef _hucc_systemcard_h +#define _hucc_systemcard_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-systemcard.h +; +; Macros and library functions for using the System Card. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; Because these are mainly macros, and so must be included before being used +; in compiled code, the actual functions here are written to avoid using any +; BSS memory so that HuCC's overlay global-shared-variables are not effected. +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Backup RAM defines ... +// ************* + +#define BM_OK 0 +#define BM_NOT_FOUND 1 +#define BM_BAD_CHECKSUM 2 +#define BM_DIR_CORRUPTED 3 +#define BM_FILE_EMPTY 4 +#define BM_FULL 5 +#define BM_NOT_FORMATED 0xFF // HuC incorrect spelling. +#define BM_NOT_FORMATTED 0xFF // HuCC can use a dictionary! + +#define BRAM_STARTPTR 0x8010 + +// ************* +// CD defines ... +// ************* + +#define CDPLAY_MUTE 0 +#define CDPLAY_REPEAT 1 +#define CDPLAY_NORMAL 2 +#define CDPLAY_ENDOFDISC 0 + +#define CDFADE_CANCEL 0 +#define CDFADE_PCM6 8 +#define CDFADE_ADPCM6 10 +#define CDFADE_PCM2 12 +#define CDFADE_ADPCM2 14 + +#define CDTRK_AUDIO 0 +#define CDTRK_DATA 4 + +// ************* +// ADPCM defines ... +// ************* + +#define ADPLAY_AUTOSTOP 0 +#define ADPLAY_REPEAT 0x80 + +#define ADPLAY_FREQ_16KHZ 0xE +#define ADPLAY_FREQ_10KHZ 0xD +#define ADPLAY_FREQ_8KHZ 0xC +#define ADPLAY_FREQ_6KHZ 0xB +#define ADPLAY_FREQ_5KHZ 0xA + +#define ADREAD_RAM 0 +#define ADREAD_VRAM 0xFF + +#define ADWRITE_RAM 0 +#define ADWRITE_VRAM 0xFF + +// ************* +// Functions in hucc-systemcard.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_SYSTEMCARD 1 + +extern void __fastcall __xsafe __macro cd_boot( void ); +extern unsigned int __fastcall __xsafe __macro cd_getver( void ); +extern void __fastcall __xsafe __macro cd_reset( void ); +extern unsigned char __fastcall __xsafe __macro cd_pause( void ); +extern unsigned char __fastcall __xsafe cd_unpause( void ); +extern void __fastcall __xsafe __macro cd_fade( unsigned char type ); +extern unsigned char __fastcall cd_playtrk( unsigned char start_track<_bx>, unsigned char end_track<_cx>, unsigned char mode<_dh> ); +extern unsigned char __fastcall cd_playmsf( unsigned char start_minute<_al>, unsigned char start_second<_ah>, unsigned char start_frame<_bl>, unsigned char end_minute<_cl>, unsigned char end_second<_ch>, unsigned char end_frame<_dl>, unsigned char mode<_dh> ); +extern unsigned char __fastcall cd_loadvram( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned int vramaddr<_bx>, unsigned int bytes<_ax> ); +extern unsigned char __fastcall cd_loaddata( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned char __far *buffer<_bp_bank:_bp>, unsigned int bytes<__ptr> ); +extern unsigned char __fastcall cd_loadbank( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned char bank<_bl>, unsigned int sectors<_al> ); +extern unsigned char __fastcall __xsafe __macro cd_status( unsigned char mode ); + +extern void __fastcall __xsafe __macro ad_reset( void ); +extern unsigned char __fastcall __xsafe __macro ad_trans( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned char nb_sectors<_dh>, unsigned int ad_addr<_bx> ); +extern void __fastcall __xsafe __macro ad_read( unsigned int ad_addr<_cx>, unsigned char mode<_dh>, unsigned int buf<_bx>, unsigned int bytes<_ax> ); +extern void __fastcall __xsafe __macro ad_write( unsigned int ad_addr<_cx>, unsigned char mode<_dh>, unsigned int buf<_bx>, unsigned int bytes<_ax> ); +extern unsigned char __fastcall __xsafe __macro ad_play( unsigned int ad_addr<_bx>, unsigned int bytes<_ax>, unsigned char freq<_dh>, unsigned char mode<_dl> ); +extern unsigned char __fastcall __xsafe __macro ad_cplay( unsigned char ovl_index<_cl>, unsigned int sect_offset<_si>, unsigned int nb_sectors<_bx>, unsigned char freq<_dh> ); +extern void __fastcall __xsafe __macro ad_stop( void ); +extern unsigned char __fastcall __xsafe __macro ad_stat( void ); + +extern unsigned char __fastcall bm_check( void ); +extern unsigned char __fastcall bm_format( void ); +extern unsigned int __fastcall __xsafe __macro bm_free( void ); +extern unsigned char __fastcall __xsafe __macro bm_read( unsigned char *buffer<_bx>, unsigned char *name<_ax>, unsigned int offset<_dx>, unsigned int length<_cx> ); +extern unsigned char __fastcall __xsafe __macro bm_write( unsigned char *buffer<_bx>, unsigned char *name<_ax>, unsigned int offset<_dx>, unsigned int length<_cx> ); +extern unsigned char __fastcall __xsafe __macro bm_delete( unsigned char *name<_ax> ); + +// Deprecated functions ... + +extern unsigned char __fastcall __xsafe __macro bm_exist( unsigned char *name<_ax> ); +extern unsigned char __fastcall __xsafe __macro bm_create( unsigned char *name<_ax>, unsigned int length<_cx> ); + +// void __fastcall _xsafe add_sectors( unsigned int sector_offset ); + +#endif // __HUCC__ + +#endif // _hucc_systemcard_h diff --git a/include/hucc/hucc-zx0.h b/include/hucc/hucc-zx0.h new file mode 100644 index 00000000..1d0eaba7 --- /dev/null +++ b/include/hucc/hucc-zx0.h @@ -0,0 +1,65 @@ +#ifndef _hucc_zx0_h +#define _hucc_zx0_h + +/**************************************************************************** +; *************************************************************************** +; +; hucc-zx0.h +; +; HuC6280 decompressor for Einar Saukas's "classic" ZX0 format. +; +; The code length is 205 bytes for RAM, plus 222 (shorter) or 262 (faster) +; bytes for direct-to-VRAM, plus some generic utility code. +; +; Copyright John Brandwood 2021-2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; ZX0 "modern" format is not supported, because it costs an extra 4 bytes of +; code in this decompressor, and it runs slower. +; +; Use Emmanuel Marty's SALVADOR ZX0 compressor which can be found here ... +; https://github.com/emmanuel-marty/salvador +; +; To create a ZX0 file to decompress to RAM +; +; salvador -classic +; +; To create a ZX0 file to decompress to VRAM, using a 2KB ring-buffer in RAM +; +; salvador -classic -w 2048 +; +; *************************************************************************** +; **************************************************************************/ + +// ************* +// Functions in unpack-zx0.asm ... +// ************* + +#ifdef __HUCC__ + +#asmdef HUCC_USES_ZX0 1 + +extern void __fastcall __macro zx0_to_vdc( unsigned int vaddr<_di>, char far *compressed<_bp_bank:_bp> ); +extern void __fastcall __macro zx0_to_sgx( unsigned int vaddr<_di>, char far *compressed<_bp_bank:_bp> ); + +#asm +_zx0_to_vdc.2 .macro + ldy <_bp_bank + call zx0_to_vdc + .endm + +_zx0_to_sgx.2 .macro + ldy <_bp_bank + call zx0_to_sgx + .endm +#endasm + +#endif // __HUCC__ + +#endif // _hucc_zx0_h diff --git a/include/hucc/hucc.asm b/include/hucc/hucc.asm new file mode 100644 index 00000000..280a3053 --- /dev/null +++ b/include/hucc/hucc.asm @@ -0,0 +1,413 @@ +; *************************************************************************** +; *************************************************************************** +; +; hucc.asm +; +; Wrapper for using HuCC with the "CORE(not TM)" PC Engine library code. +; +; Copyright John Brandwood 2024. +; +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +; +; *************************************************************************** +; *************************************************************************** +; +; 1) If we're running on a HuCard, the initialization is simple! +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM with ZP & Stack (BSS segment) +; MPR2 = bank $87 : SGX RAM or CD RAM +; MPR3 = bank $xx : HuCC const data, init to $02 (DATA segment) +; MPR4 = bank $xx : HuCC const data, init to $03 +; MPR5 = bank $01 : HuCC permanent code & data (CODE segment) +; MPR6 = bank $xx : Banked ASM library & HuCC procedures +; MPR7 = bank $00 : CORE(not TM) base code & call-trampolines +; +; +; 2) If we're running on a HuCard that supports the Turbo Everdrive, then the +; first bank is reserved for mapping the TED2 hardware. +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM with ZP & Stack (BSS segment) +; MPR2 = bank $01 : TED2 RAM +; MPR3 = bank $xx : HuCC const data, init to $04 (DATA segment) +; MPR4 = bank $xx : HuCC const data, init to $05 +; MPR5 = bank $03 : HuCC permanent code & data (CODE segment) +; MPR6 = bank $xx : Banked ASM library & HuCC procedures +; MPR7 = bank $02 : CORE(not TM) base code & call-trampolines +; +; +; 3) If we're running on an old CD System, the overlay is loaded from the ISO +; into banks $80-$87 (64KB max). +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM & CORE(not TM) kernel (BSS segment) +; MPR2 = bank $87 : SGX RAM or CD RAM +; MPR3 = bank $xx : HuCC const data, init to $82 (DATA segment) +; MPR4 = bank $xx : HuCC const data, init to $83 +; MPR5 = bank $81 : HuCC permanent code & data (CODE segment) +; MPR6 = bank $xx : Banked ASM library & HuCC procedures +; MPR7 = bank $80 : CORE(not TM) base code & call-trampolines +; +; +; 4) If we're running on a SuperCD System, the overlay is loaded from the ISO +; into banks $68-$87 (256KB max). +; +; The PC Engine's memory map is set to ... +; +; MPR0 = bank $FF : PCE hardware +; MPR1 = bank $F8 : PCE RAM & CORE(not TM) kernel (BSS segment) +; MPR2 = bank $87 : SGX RAM or CD RAM +; MPR3 = bank $xx : HuCC const data, init to $6A (DATA segment) +; MPR4 = bank $xx : HuCC const data, init to $6B +; MPR5 = bank $69 : HuCC permanent code & data (CODE segment) +; MPR6 = bank $xx : Banked ASM library & HuCC procedures +; MPR7 = bank $68 : CORE(not TM) base code & call-trampolines +; +; *************************************************************************** +; *************************************************************************** + + ; Set the PCEAS options that HuCC code needs. + + .3pass ; Commit to running 3-passes. + .opt a+ ; Enable auto-zp addressing. + .opt b+ ; Fix out-of-range branches. + + ; Tell the libraries that this is HuCC code. + +HUCC = 1 + + ; Read the project's HuCC configuration settings from the + ; local "hucc-config.inc", if it exists, before CORE. + ; + ; These settings configure the asm libraries for HuCC code, + ; which should be independent of whatever base library acts + ; as the foundation for the overall code structure. + + include "hucc-config.inc" ; Allow for HuCC customization. + + ; This is where you can change which asm library forms the + ; foundation structure. + + .ifndef HUCC_NO_CORE + + ; Use the CORE library, reading the project's configuration + ; settings from the local "core-config.inc", if it exists. + + include "core.inc" ; Foundation library. + .else + + ; Use a simple PCE-only and HuCARD-only foundation that is. + ; easy to understand and modify. + + include "bare-startup.asm" ; Foundation library. + .endif + + ; + + .list + .mlist + + ; + + .zp + .align 2 +__fptr .ds 2 +__fbank .ds 1 +__sp .ds 1 +__stack .ds HUCC_STACK_SZ +__ptr .ds 2 + + ; Pointer used by poke() because __ptr could be overwritten. + +__poke = __si + + ; Used for indirect calls because __ptr could be overwritten. + +__func = __si + + ; Data pointer used by SDCC for indirect indexed memory access. + +DPTR = __ptr + + ; REGTEMP stack for temporaries used by SDCC + ; Keep this in sync with NUM_TEMP_REGS in mos6502/gen.c + +REGTEMP: .ds 8 + + ; Values returned from SDCC functions that don't fit into XA. + ; These are also used as workspace for SDCC library functions, + ; including HuCC's multiplication and division functions. + +___SDCC_m6502_ret0: .ds 1 +___SDCC_m6502_ret1: .ds 1 +___SDCC_m6502_ret2: .ds 1 +___SDCC_m6502_ret3: .ds 1 + + .if 0 +___SDCC_m6502_ret4: .ds 1 +___SDCC_m6502_ret5: .ds 1 +___SDCC_m6502_ret6: .ds 1 +___SDCC_m6502_ret7: .ds 1 + .endif + + ; This is the lo-byte of the value returned by a HuCC function. + +__hucc_ret = ___SDCC_m6502_ret3 + + ; HuCC keeps a realtime clock, updated in hucc_vbl. + ; + ; Defining this here means that it will go before any HuCC + ; variables in "globals.h", and so it won't get cleared in + ; a CDROM game when loading different overlays. + + .bss +clock_hh .ds 1 ; System Clock, hours (0-11) +clock_mm .ds 1 ; System Clock, minutes (0-59) +clock_ss .ds 1 ; System Clock, seconds (0-59) +clock_tt .ds 1 ; System Clock, ticks (0-59) + .code + + ; Critical HuCC libraries that the compiler depends upon. + ; + ; These include various macros that must be defined before + ; they are encountered in any compiler-generated code. + + include "hucc-codegen.asm" ; HuCC i-code macros and funcs. + include "hucc-baselib.asm" ; HuCC base library macros. + + .if CDROM + include "hucc-systemcard.asm" ; HuCC System Card macros. + .endif + + ; Definitions for compatibility with old HuC/MagicKit projects. + + .ifndef HUCC_NO_DEPRECATED + include "hucc-deprecated.inc" + .endif + + ; + ; + ; + + + +; *************************************************************************** +; *************************************************************************** +; +; core_main - This is executed after "CORE(not TM)" library initialization. +; +; This is the first code assembled after the library includes, so we're still +; in the CORE_BANK, usually ".bank 0"; and because this is assembled with the +; default configuration from "include/core-config.inc", which sets the option +; "USING_MPR7", then we're running in MPR7 ($E000-$FFFF). +; + + .code + +core_main: tma7 ; Get the CORE_BANK. + + inc a ; MPR0 = $FF + tam6 ; MPR1 = PCE_RAM +; inc a ; MPR2 = SGX_RAM or CD_RAM + tam5 ; MPR3 = CONST_BANK + 0 + lda #CONST_BANK + _bank_base; MPR4 = CONST_BANK + 1 + tam3 ; MPR5 = CORE_BANK + 1 + inc a ; MPR6 = CORE_BANK + 1 + tam4 ; MPR7 = CORE_BANK + 0 + + .if SUPPORT_SGX + lda #$F9 ; Map the 2nd SGX RAM bank. + .else + lda #$87 ; Map the last CD RAM bank. + .endif + tam2 + + php ; Disable interrupts while + sei ; clearing overlay's BSS. + + .ifndef USING_RCR_MACROS + .ifdef hucc_rcr + lda #hucc_rcr + sta.h hsync_hook + .endif + .if SUPPORT_SGX + .ifdef hucc_rcr_sgx + lda #hucc_rcr_sgx + sta.h hsync_hook_sgx + .endif + .endif + .endif USING_RCR_MACROS + + lda #hucc_vbl + sta.h vsync_hook + + .if CDROM ; Overlays should clear BSS. + tai const_0000, huc_globals_end, (_bss_end - huc_globals_end) + .else + tii .rom_tia, ram_tia, 16 ; Only needed on HuCARD. + .endif CDROM + + .ifdef HAVE_INIT ; This method needs to be replaced! + tii huc_rodata, huc_data, huc_rodata_end - huc_rodata + .endif HAVE_INIT + + tai .stack_fill, __stack, HUCC_STACK_SZ + + lda #$10 ; Enable HuCC's vblank IRQ + tsb 684 pixel slots. VDC_HSR_480 = $0D05 ; HDS HSW (Reduced) VDC_HDR_480 = $053B ; HDE HDW +VDC_HSR_496 = $0C05 ; HDS HSW (Reduced) +VDC_HDR_496 = $043D ; HDE HDW + VDC_HSR_512 = $0B05 ; HDS HSW (Normal) VDC_HDR_512 = $033F ; HDE HDW diff --git a/examples/asm/elmer/include/random.asm b/include/hucc/random.asm similarity index 93% rename from examples/asm/elmer/include/random.asm rename to include/hucc/random.asm index ba1f5199..8faa50fe 100644 --- a/examples/asm/elmer/include/random.asm +++ b/include/hucc/random.asm @@ -119,43 +119,33 @@ init_random .proc ; ; The pseudo-random sequence repeats after (2^24)-1 calls. ; -; Written by Brad Smith, see https://github.com/bbbradsmith/prng_6502 +; Written by Wim Couwenberg, see ... ; -; Takes 88 cycles on the HuC6280, incl JSR & RTS. +; "https://wimcouwenberg.wordpress.com/2020/11/15/ ... +; a-fast-24-bit-prng-algorithm-for-the-6502-processor/" +; +; Takes 68 cycles on the HuC6280, incl JSR & RTS. +; +; N.B. HuCC library code relies on this preserving X and Y! ; -get_random: ; Rotate the middle byte left - - ldy >1 = %00001101) +_rand8: cly ; Entry point for HuCC. - lda +; +; To create a ZX0 file to decompress to VRAM, using a 2KB ring-buffer in RAM +; +; salvador -classic -w 2048 +; +; *************************************************************************** +; *************************************************************************** + +; +; Configure Library ... +; + + .ifndef SUPPORT_ACD +SUPPORT_ACD = 1 + .endif + + .ifndef SUPPORT_ZX0RAM +SUPPORT_ZX0RAM = 1 ; Include decompress-to-RAM? + .endif + + .ifndef SUPPORT_ZX0VRAM +SUPPORT_ZX0VRAM = 1 ; Include decompress-to-VRAM? + .endif + + .ifndef ZX0_PREFER_SIZE +ZX0_PREFER_SIZE = 1 ; Smaller size or 10% faster. + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; If you decompress directly to VRAM, then you need to define a ring-buffer +; in RAM, both sized and aligned to a power-of-two (i.e. 256, 512, 1KB, 2KB). +; +; You also need to make sure that you tell the compressor that it needs to +; limit the window size with its "-w" option. +; +; Note that CD-ROM developers should really just decompress to RAM, and then +; use a TIA to copy the data to VRAM, because that is faster, you get better +; compression without a window, and you save code memory by not needing both +; versions of the decompression routine. +; +; HuCARD developers who either can't afford the RAM, or who prefer execution +; speed over compression, can choose a ring-buffer size of 256 bytes so that +; a faster version of the decompression code is used. +; + + .ifndef ZX0_WINBUF + +ZX0_WINBUF = ($3800) ; Default to a 2KB window in +ZX0_WINMSK = ($0800 - 1) ; RAM, located at $3800. + + .endif + + + +; *************************************************************************** +; *************************************************************************** +; +; Data usage is 10..14 bytes of zero-page, using aliases for clarity. +; + +zx0_srcptr = _bp ; 1 word. +zx0_dstptr = _di ; 1 word. +zx0_winptr = _si ; 1 word. + +zx0_length = _ax ; 1 word. +zx0_offset = _bx ; 1 word. + + + + .if (SUPPORT_ZX0RAM + SUPPORT_ZX0VRAM) + +zx0_group .procgroup ; Keep RAM and VDC together. + + .if SUPPORT_ZX0RAM + +; *************************************************************************** +; *************************************************************************** +; +; zx0_to_ram - Decompress data stored in Einar Saukas's ZX0 "classic" format. +; +; Args: _bp, Y = _farptr to compressed data in MPR3. +; Args: _di = ptr to output address in RAM (anywhere except MPR3!). +; +; Returns: _bp, Y = _farptr to byte after compressed data. +; +; Uses: _bp, _di, _si, _ax, _bx ! +; + +zx0_to_ram .proc + + tma3 ; Preserve MPR3. + pha + + jsr set_bp_to_mpr3 ; Map zx0_srcptr to MPR3. + + ldx #$40 ; Initialize bit-buffer. + + lda #$FF ; Initialize offset to $FFFF. + sta.l .mode_240x224 + lda #>.mode_240x208 sta.h <_bp .if SUPPORT_SGX call sgx_detect ; Are we really on an SGX? - beq !+ - ldy #^.mode_240x224 ; Set SGX 1st, with no VBL. + bcc !+ + ldy #^.mode_240x208 ; Set SGX 1st, with no VBL. call set_mode_sgx .endif -!: ldy #^.mode_240x224 ; Set VDC 2nd, VBL allowed. +!: ldy #^.mode_240x208 ; Set VDC 2nd, VBL allowed. call set_mode_vdc + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue RCR/VBL. + plp ; Restore interrupts. + call wait_vsync ; Wait for the next VBLANK. leave ; All done, phew! ; A reduced 240x208 screen to save VRAM. -.mode_240x224: db $80 ; VCE Control Register. +.mode_240x208: db $80 ; VCE Control Register. db VCE_CR_5MHz ; Video Clock db VDC_MWR ; Memory-access Width Register @@ -656,6 +726,9 @@ init_256x224 .proc .CHR_0x10 = .CHR_ZERO + 16 ; 1st tile # after the SAT. .CHR_0x20 = .CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + php ; Disable interrupts. + sei + call clear_vce ; Clear all palettes. lda.l #.CHR_0x20 ; Tile # of ' ' CHR. @@ -678,13 +751,19 @@ init_256x224 .proc .if SUPPORT_SGX call sgx_detect ; Are we really on an SGX? - beq !+ + bcc !+ ldy #^.mode_256x224 ; Set SGX 1st, with no VBL. call set_mode_sgx .endif !: ldy #^.mode_256x224 ; Set VDC 2nd, VBL allowed. call set_mode_vdc + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue VBL. + plp ; Restore interrupts. + call wait_vsync ; Wait for the next VBLANK. leave ; All done, phew! @@ -692,7 +771,7 @@ init_256x224 .proc ; A standard 256x224 screen with overscan. .mode_256x224: db $80 ; VCE Control Register. - db VCE_CR_5MHz + 4 ; Video Clock + Artifact Reduction + db VCE_CR_5MHz + XRES_SOFT ; Video Clock + Artifact Reduction db VDC_MWR ; Memory-access Width Register dw VDC_MWR_64x32 + VDC_MWR_1CYCLE @@ -740,6 +819,9 @@ init_352x224 .proc .CHR_0x10 = .CHR_ZERO + 16 ; 1st tile # after the SAT. .CHR_0x20 = .CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + php ; Disable interrupts. + sei + call clear_vce ; Clear all palettes. lda.l #.CHR_0x20 ; Tile # of ' ' CHR. @@ -762,13 +844,19 @@ init_352x224 .proc .if SUPPORT_SGX call sgx_detect ; Are we really on an SGX? - beq !+ + bcc !+ ldy #^.mode_352x224 ; Set SGX 1st, with no VBL. call set_mode_sgx .endif !: ldy #^.mode_352x224 ; Set VDC 2nd, VBL allowed. call set_mode_vdc + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue RCR/VBL. + plp ; Restore interrupts. + call wait_vsync ; Wait for the next VBLANK. leave ; All done, phew! @@ -776,7 +864,7 @@ init_352x224 .proc ; A standard 352x224 screen with overscan. .mode_352x224: db $80 ; VCE Control Register. - db VCE_CR_7MHz + 4 ; Video Clock + Artifact Reduction + db VCE_CR_7MHz + XRES_SOFT ; Video Clock + Artifact Reduction db VDC_MWR ; Memory-access Width Register dw VDC_MWR_64x32 + VDC_MWR_1CYCLE @@ -824,6 +912,9 @@ init_512x224 .proc .CHR_0x10 = .CHR_ZERO + 16 ; 1st tile # after the SAT. .CHR_0x20 = .CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + php ; Disable interrupts. + sei + call clear_vce ; Clear all palettes. lda.l #.CHR_0x20 ; Tile # of ' ' CHR. @@ -846,13 +937,19 @@ init_512x224 .proc .if SUPPORT_SGX call sgx_detect ; Are we really on an SGX? - beq !+ + bcc !+ ldy #^.mode_512x224 ; Set SGX 1st, with no VBL. call set_mode_sgx .endif !: ldy #^.mode_512x224 ; Set VDC 2nd, VBL allowed. call set_mode_vdc + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue RCR/VBL. + plp ; Restore interrupts. + call wait_vsync ; Wait for the next VBLANK. leave ; All done, phew! @@ -860,7 +957,7 @@ init_512x224 .proc ; A standard 512x224 screen with overscan. .mode_512x224: db $80 ; VCE Control Register. - db VCE_CR_10MHz + 4 ; Video Clock + Artifact Reduction + db VCE_CR_10MHz + XRES_SOFT; Video Clock + Artifact Reduction db VDC_MWR ; Memory-access Width Register dw VDC_MWR_64x32 + VDC_MWR_2CYCLE @@ -910,6 +1007,9 @@ init_320x208 .proc .CHR_0x10 = .CHR_ZERO + 16 ; 1st tile # after the SAT. .CHR_0x20 = .CHR_ZERO + 32 ; ASCII ' ' CHR tile #. + php ; Disable interrupts. + sei + call clear_vce ; Clear all palettes. lda.l #.CHR_0x20 ; Tile # of ' ' CHR. @@ -932,13 +1032,19 @@ init_320x208 .proc .if SUPPORT_SGX call sgx_detect ; Are we really on an SGX? - beq !+ + bcc !+ ldy #^.mode_320x208 ; Set SGX 1st, with no VBL. call set_mode_sgx .endif !: ldy #^.mode_320x208 ; Set VDC 2nd, VBL allowed. call set_mode_vdc + .if SUPPORT_SGX + bit SGX_SR ; Purge any overdue RCR. + .endif + bit VDC_SR ; Purge any overdue VBL. + plp ; Restore interrupts. + call wait_vsync ; Wait for the next VBLANK. leave ; All done, phew! @@ -946,7 +1052,7 @@ init_320x208 .proc ; A standard 352x224 screen with overscan. .mode_320x208: db $80 ; VCE Control Register. - db VCE_CR_7MHz + 4 ; Video Clock + Artifact Reduction + db VCE_CR_7MHz + XRES_SOFT ; Video Clock + Artifact Reduction db VDC_MWR ; Memory-access Width Register dw VDC_MWR_64x32 + VDC_MWR_1CYCLE diff --git a/src/Make_src.inc b/src/Make_src.inc index de2dda42..53ecc536 100644 --- a/src/Make_src.inc +++ b/src/Make_src.inc @@ -14,6 +14,8 @@ CDEFS = CFLAGS = -Wall -g -O2 CFLAGS += -DGIT_VERSION="\"$(GIT_VERSION)\"" CFLAGS += -DGIT_DATE="\"$(GIT_DATE)\"" +CXXFLAGS += -DGIT_VERSION="\"$(GIT_VERSION)\"" +CXXFLAGS += -DGIT_DATE="\"$(GIT_DATE)\"" LDFLAGS = -g # @@ -29,3 +31,7 @@ EXESUFFIX = CP = cp RM = rm -f CC = cc +CXX = c++ +AWK = awk +LEX = lex +YACC = yacc diff --git a/src/Makefile b/src/Makefile index 3572b24b..d06821f4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ # Makefile for HuC sources # -SUBDIRS = huc mkit isolink tools +SUBDIRS = huc hucc mkit isolink tools all clean: @$(MAKE) $(SUBDIRS) "COMMAND=$@" diff --git a/src/Maketarg.inc b/src/Maketarg.inc index c14eb622..5f806a5f 100644 --- a/src/Maketarg.inc +++ b/src/Maketarg.inc @@ -7,10 +7,12 @@ clean:: $(RM) core $(RM) *.o *.gcno *.gcda *.gcov + $(RM) -rf msbuild/.vs msbuild/.x86 msbuild/.x64 ifneq "$(EXE)" "" - $(RM) $(EXE) $(BINDIR)/$(EXE) + $(RM) $(EXE) $(BINDIR)/$(EXE) $(BINDIR)/*.pdb endif %.o: %.c $(CC) $(CDEFS) $(CFLAGS) -c $< -o $@ - +%.o: %.cc + $(CXX) $(CDEFS) $(CXXFLAGS) -c $< -o $@ diff --git a/src/hucc/Makefile b/src/hucc/Makefile new file mode 100644 index 00000000..f46c79e2 --- /dev/null +++ b/src/hucc/Makefile @@ -0,0 +1,52 @@ +# Makefile for HuCC +# +# Written for Linux development version, March 4, 2001 by Dave Shadoff +# + +# +# Defines +# +BASEDIR=..d .. +include ../Make_src.inc + + +HDRS = code.h data.h defs.h error.h gen.h lex.h preproc.h pseudo.h sym.h while.h +OBJS = code.o const.o data.o error.o expr.o \ + function.o gen.o io.o lex.o main.o \ + optimize.o pragma.o preproc.o primary.o pseudo.o \ + stmt.o sym.o while.o struct.o enum.o initials.o +EXE = hucc$(EXESUFFIX) + +all: $(EXE) + +$(EXE): $(OBJS) $(LIBS) $(HDRS) + $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + $(CP) $(EXE) $(BINDIR) + +$(OBJS): code.h data.h defs.h error.h io.h + +code.o: function.h main.h optimize.h +const.o: const.h lex.h primary.h sym.h +expr.o: expr.h function.h gen.h lex.h primary.h +function.o: expr.h function.h gen.h lex.h optimize.h pragma.h pseudo.h stmt.h sym.h +gen.o: primary.h sym.h +io.o: optimize.h preproc.h +lex.o: lex.h preproc.h +main.o: const.h function.h gen.h lex.h main.h optimize.h pragma.h preproc.h \ + pseudo.h sym.h +optimize.o: function.h +pragma.o: lex.h pragma.h sym.h +preproc.o: lex.h optimize.h preproc.h sym.h +primary.o: expr.h gen.h lex.h primary.h sym.h +pseudo.o: lex.h optimize.h primary.h pseudo.h sym.h +stmt.o: expr.h gen.h lex.h preproc.h primary.h stmt.h sym.h while.h +sym.o: const.h gen.h lex.h primary.h pragma.h sym.h +while.o: gen.h while.h + +indent: uncrustify.cfg + uncrustify -l c -c $< --replace *.c *.h + +# +# Targets +# +include $(MAKETARG) diff --git a/src/hucc/code.c b/src/hucc/code.c new file mode 100644 index 00000000..bb3cc8be --- /dev/null +++ b/src/hucc/code.c @@ -0,0 +1,1896 @@ +/* File code.c: 2.2 (84/08/31,10:05:13) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include + +#include "defs.h" +#include "data.h" +#include "code.h" +#include "error.h" +#include "function.h" +#include "io.h" +#include "main.h" +#include "optimize.h" + +/* locals */ +int segment; + +/* externs */ +extern int arg_stack_flag; + +/* convert comparison operation to a string */ +const char * compare2str [] = { + "equ", // CMP_EQU + "neq", // CMP_NEQ + "slt", // CMP_SLT + "sle", // CMP_SLE + "sgt", // CMP_SGT + "sge", // CMP_SGE + "ult", // CMP_ULT + "ule", // CMP_ULE + "ugt", // CMP_UGT + "uge" // CMP_UGE +}; + +/* + * print all assembler info before any code is generated + * + */ +void gdata (void) +{ + if (segment == 1) { + segment = 0; + ol(".bss"); + } +} + +void gtext (void) +{ + if (segment == 0) { + segment = 1; + ol(".code"); + } +} + +void header (void) +{ + time_t today; + + outstr("; Small-C HuC6280 (1997-Nov-08)\n"); + outstr("; became HuC (2000-Feb-22)\n"); + outstr("; became HuCC (2024-May-01)\n"); + outstr(";\n"); + outstr("; This file generated by "); + outstr(HUC_VERSION); + outstr("\n"); + outstr("; on "); + time(&today); + outstr(ctime(&today)); + outstr(";\n"); + outstr("\n"); + outstr("HUC\t\t=\t1\n"); + outstr("HUCC\t\t=\t1\n"); + /* Reserve space for further global definitions. */ + output_globdef = ftell(output); + outstr(" "); + nl(); +} + +void asmdefines (void) +{ + outstr(asmdefs); +} + +void inc_startup (void) +{ + if (startup_incl == 0) { + startup_incl = 1; + + nl(); + outstr("\t\tinclude\t\"hucc.asm\"\n"); + outstr("\t\t.data\n"); + outstr("\t\t.bank\tDATA_BANK\n\n"); + gtext(); + nl(); + } +} + +/* + * print pseudo-op to define a byte + * + */ +void defbyte (void) +{ + ot(".db\t\t"); +} + +/* + * print pseudo-op to define storage + * + */ +void defstorage (void) +{ + ot(".ds\t\t"); +} + +/* + * print pseudo-op to define a word + * + */ +void defword (void) +{ + ot(".dw\t\t"); +} + +/* + * output instructions + * + */ +void out_ins (int code, int type, intptr_t data) +{ + INS tmp; + + memset(&tmp, 0, sizeof(INS)); + + tmp.ins_code = code; + tmp.ins_type = type; + tmp.ins_data = data; + gen_ins(&tmp); +} + +void out_ins_ex (int code, int type, intptr_t data, int imm_type, intptr_t imm_data) +{ + INS tmp; + + memset(&tmp, 0, sizeof(INS)); + + tmp.ins_code = code; + tmp.ins_type = type; + tmp.ins_data = data; + tmp.imm_type = imm_type; + tmp.imm_data = imm_data; + gen_ins(&tmp); +} + +void out_ins_sym (int code, int type, intptr_t data, SYMBOL *sym) +{ + INS tmp; + + memset(&tmp, 0, sizeof(INS)); + + tmp.ins_code = code; + tmp.ins_type = type; + tmp.ins_data = data; + tmp.sym = sym; + gen_ins(&tmp); +} + +void out_ins_cmp (int code, int type) +{ + INS tmp; + + memset(&tmp, 0, sizeof(INS)); + + tmp.ins_code = code; + tmp.cmp_type = type; + gen_ins(&tmp); +} + +void gen_ins (INS *tmp) +{ + if (optimize) + push_ins(tmp); + else { + if (arg_stack_flag) + arg_push_ins(tmp); + else + gen_code(tmp); + } +} + +static void out_type (int type, intptr_t data) +{ + switch (type) { + case T_VALUE: + outdec((int)data); + break; + case T_LABEL: + outlabel((int)data); + break; + case T_SYMBOL: + outsymbol((SYMBOL *)data); + break; + case T_LITERAL: + outstr((const char *)data); + break; + case T_STRING: + outconst(litlab); + outbyte('+'); + outdec((int)data); + break; + case T_BANK: + outstr("BANK("); + outstr((const char *)data); + outstr(")"); + break; + case T_VRAM: + outstr("VRAM("); + outstr((const char *)data); + outstr(")"); + break; + case T_PAL: + outstr("PAL("); + outstr((const char *)data); + outstr(")"); + break; + } +} + +static void out_addr (int type, intptr_t data) +{ + switch (type) { + case T_LABEL: + outlabel((int)data); + break; + case T_SYMBOL: + outsymbol((SYMBOL *)data); + break; + case T_LITERAL: + outstr((const char *)data); + break; + case T_PTR: + outstr("__ptr"); + break; + case T_VALUE: + outdec((int)data); + break; + case T_STACK: + outstr("__stack"); + break; + } +} + +void dump_ins (INS *tmp) +{ + FILE *save = output; + + output = stdout; + gen_code(tmp); + output = save; +} + +/* + * gen assembly code + * + */ +void gen_code (INS *tmp) +{ + enum ICODE code; + int type; + intptr_t data; + int imm_type; + intptr_t imm_data; + + code = tmp->ins_code; + type = tmp->ins_type; + data = tmp->ins_data; + imm_type = tmp->imm_type; + imm_data = tmp->imm_data; + + if (type == T_NOP) + return; + + switch (code) { + + /* i-code that retires the primary register contents */ + + case I_FENCE: + ot("__fence"); + nl(); + break; + + /* i-code that declares a byte sized primary register */ + + case I_SHORT: + ot("__short"); + nl(); + break; + + /* i-codes for handling farptr */ + + case I_FARPTR: + ot("__farptr\t"); + + switch (type) { + case T_LABEL: + outlabel((int)data); + break; + case T_SYMBOL: + outsymbol((SYMBOL *)data); + break; + case T_STRING: + outconst(litlab); + outbyte('+'); + outdec((int)data); + break; + } + outstr(", "); + outstr(tmp->arg[0]); + outstr(", "); + outstr(tmp->arg[1]); + nl(); + break; + + case I_FARPTR_I: + ot("__farptr_i\t"); + outsymbol((SYMBOL *)data); + outstr(", "); + outstr(tmp->arg[0]); + outstr(", "); + outstr(tmp->arg[1]); + nl(); + break; + + case I_FARPTR_GET: + ot("__farptr_get\t"); + outstr(tmp->arg[0]); + outstr(", "); + outstr(tmp->arg[1]); + nl(); + break; + + case I_FGETW: + ot("__farptr_i\t"); + outsymbol((SYMBOL *)data); + nl(); + ol(" jsr\t_farpeekw.fast"); + break; + + case I_FGETB: + ot("__farptr_i\t"); + outsymbol((SYMBOL *)data); + nl(); + ol("__fgetb"); + break; + + case I_FGETUB: + ot("__farptr_i\t"); + outsymbol((SYMBOL *)data); + nl(); + ol("__fgetub"); + break; + + /* i-codes for interrupts */ + + case I_SEI: + ol("sei"); + break; + + case I_CLI: + ol("cli"); + break; + + /* i-codes for calling functions */ + + case I_MACRO: + /* because functions don't need to be pre-declared + in HuC we get a string and not a symbol */ + switch (type) { + case T_LITERAL: + ot(" "); + prefix(); + outstr((const char *)data); + if (imm_data) { + outstr("."); + outdec((int)imm_data); + } + break; + } + nl(); + break; + + case I_CALL: + /* because functions don't need to be pre-declared + in HuC we get a string and not a symbol */ + switch (type) { + case T_LITERAL: + ot(" call\t\t"); + prefix(); + outstr((const char *)data); + if (imm_data) { + outstr("."); + outdec((int)imm_data); + } + break; + } + nl(); + break; + + case I_FUNCP_WR: + ol("__funcp.wr"); + break; + + case I_CALLP: + ol("__callp"); + break; + + /* i-codes for C functions and the C parameter stack */ + + case I_ENTER: + ot("__enter\t\t"); + outsymbol((SYMBOL *)data); + nl(); + break; + + case I_RETURN: + ot("__return\t\t"); + outdec((int)data); + nl(); + break; + + case I_GETACC: + ol("__getacc"); + break; + + case I_SAVESP: + ol("__savesp"); + break; + + case I_LOADSP: + ol("__loadsp"); + break; + + case I_MODSP: + ot("__modsp"); + if (type == T_LITERAL) { + outstr("_sym\t"); + outstr((const char *)data); + } + else { + outstr("\t\t"); + outdec((int)data); + } + nl(); + break; + + case I_PUSH_WR: + ol("__push.wr"); + break; + + case I_POP_WR: + ol("__pop.wr"); + break; + + case I_SPUSH_WR: + ol("__spush.wr"); + break; + + case I_SPOP_WR: + ol("__spop.wr"); + break; + + case I_SPUSH_UR: + ol("__spush.ur"); + break; + + case I_SPOP_UR: + ol("__spop.ur"); + break; + + /* i-codes for handling boolean tests and branching */ + + case I_SWITCH_WR: + ot("__switch.wr\t"); + outlabel((int)data); + nl(); + break; + + case I_SWITCH_UR: + ot("__switch.ur\t"); + outlabel((int)data); + nl(); + break; + + case I_CASE: + ot("__case\t\t"); + if (type == T_VALUE) + outdec((int)data); + nl(); + break; + + case I_ENDCASE: + ot("__endcase"); + nl(); + break; + + case I_LABEL: + outlabel((int)data); + col(); + break; + + case I_ALIAS: + outlabel((int)data); + ot(".alias\t\t"); + outlabel((int)imm_data); + nl(); + break; + + case I_BRA: + ot("__bra\t\t"); + outlabel((int)data); + nl(); + break; + + case I_BFALSE: + ot("__bfalse\t"); + outlabel((int)data); + nl(); + nl(); + break; + + case I_BTRUE: + ot("__btrue\t\t"); + outlabel((int)data); + nl(); + nl(); + break; + + case I_DEF: + outstr((const char *)data); + outstr(" .equ "); + outdec((int)imm_data); + nl(); + break; + + case I_CMP_WT: + ot("__cmp.wt\t"); + outstr(compare2str[tmp->cmp_type]); + outstr("_w"); + nl(); + break; + + case X_CMP_WI: + ot("__"); + outstr(compare2str[tmp->cmp_type]); + outstr("_w.wi\t"); + out_type(type, data); + nl(); + break; + + case X_CMP_WM: + ot("__"); + outstr(compare2str[tmp->cmp_type]); + outstr("_w.wm\t"); + out_type(type, data); + nl(); + break; + + case X_CMP_WS: + ot("__"); + outstr(compare2str[tmp->cmp_type]); + outstr("_w.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_CMP_UIQ: + ot("__"); + outstr(compare2str[tmp->cmp_type]); + outstr("_b.uiq\t"); + out_type(type, data); + nl(); + break; + + case X_CMP_UMQ: + ot("__"); + outstr(compare2str[tmp->cmp_type]); + outstr("_b.umq\t"); + out_type(type, data); + nl(); + break; + + case X_CMP_USQ: + ot("__"); + outstr(compare2str[tmp->cmp_type]); + outstr("_b.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case I_NOT_WR: + ol("__not.wr"); + break; + + case X_NOT_WP: + ot("__not.wp\t"); + out_addr(type, data); + nl(); + break; + + case X_NOT_WM: + ot("__not.wm\t"); + out_addr(type, data); + nl(); + break; + + case X_NOT_WS: + ot("__not.ws\t"); + outdec((int)data); + nl(); + break; + + case X_NOT_WAR: + ot("__not.war\t"); + out_addr(type, data); + nl(); + break; + + case X_NOT_UP: + ot("__not.up\t"); + out_addr(type, data); + nl(); + break; + + case X_NOT_UM: + ot("__not.um\t"); + out_addr(type, data); + nl(); + break; + + case X_NOT_US: + ot("__not.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_NOT_UAR: + ot("__not.uar\t"); + out_addr(type, data); + nl(); + break; + + case X_NOT_UAY: + ot("__not.uay\t"); + out_addr(type, data); + nl(); + break; + + case I_TST_WR: + ol("__tst.wr"); + break; + + case X_TST_WP: + ot("__tst.wp\t"); + out_addr(type, data); + nl(); + break; + + case X_TST_WM: + ot("__tst.wm\t"); + out_addr(type, data); + nl(); + break; + + case X_TST_WS: + ot("__tst.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_TST_WAR: + ot("__tst.war\t"); + out_addr(type, data); + nl(); + break; + + case X_TST_UP: + ot("__tst.up\t"); + out_addr(type, data); + nl(); + break; + + case X_TST_UM: + ot("__tst.um\t"); + out_addr(type, data); + nl(); + break; + + case X_TST_US: + ot("__tst.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_TST_UAR: + ot("__tst.uar\t"); + out_addr(type, data); + nl(); + break; + + case X_TST_UAY: + ot("__tst.uay\t"); + out_addr(type, data); + nl(); + break; + + case X_NAND_WI: + ot("__nand.wi\t"); + out_type(type, data); + nl(); + break; + + case X_TAND_WI: + ot("__tand.wi\t"); + out_type(type, data); + nl(); + break; + + case X_NOT_CF: + ol("__not.cf"); + break; + + case I_BOOLEAN: + ol("__bool"); + break; + + case X_BOOLNOT_WR: + ol("__boolnot.wr"); + break; + + case X_BOOLNOT_WP: + ot("__boolnot.wp\t"); + out_addr(type, data); + nl(); + break; + + case X_BOOLNOT_WM: + ot("__boolnot.wm\t"); + out_addr(type, data); + nl(); + break; + + case X_BOOLNOT_WS: + ot("__boolnot.ws\t"); + outdec((int)data); + nl(); + break; + + case X_BOOLNOT_WAR: + ot("__boolnot.war\t"); + out_addr(type, data); + nl(); + break; + + case X_BOOLNOT_UP: + ot("__boolnot.up\t"); + out_addr(type, data); + nl(); + break; + + case X_BOOLNOT_UM: + ot("__boolnot.um\t"); + out_addr(type, data); + nl(); + break; + + case X_BOOLNOT_US: + ot("__boolnot.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_BOOLNOT_UAR: + ot("__boolnot.uar\t"); + out_addr(type, data); + nl(); + break; + + case X_BOOLNOT_UAY: + ot("__boolnot.uay\t"); + out_addr(type, data); + nl(); + break; + + /* i-codes for loading the primary register */ + + case I_LD_WI: + ot("__ld.wi\t\t"); + out_type(type, data); + nl(); + break; + + case X_LD_UIQ: + ot("__ld.uiq\t"); + out_type(type, data); + nl(); + break; + + case I_LEA_S: + ot("__lea.s\t\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case I_LD_WM: + ot("__ld.wm\t\t"); + out_addr(type, data); + nl(); + break; + + case I_LD_BM: + ot("__ld.bm\t\t"); + out_type(type, data); + nl(); + break; + + case I_LD_UM: + ot("__ld.um\t\t"); + out_type(type, data); + nl(); + break; + + case I_LD_WMQ: + ot("__ld.wmq\t"); + out_addr(type, data); + nl(); + break; + + case I_LD_BMQ: + ot("__ld.bmq\t"); + out_type(type, data); + nl(); + break; + + case I_LD_UMQ: + ot("__ld.umq\t"); + out_type(type, data); + nl(); + break; + + case I_LDY_WMQ: + ot("__ldy.wmq\t"); + out_addr(type, data); + nl(); + break; + + case I_LDY_BMQ: + ot("__ldy.bmq\t"); + out_type(type, data); + nl(); + break; + + case I_LDY_UMQ: + ot("__ldy.umq\t"); + out_type(type, data); + nl(); + break; + + case I_LD_WP: + ot("__ld.wp\t\t"); + out_addr(type, data); + nl(); + break; + + case I_LD_BP: + ot("__ld.bp\t\t"); + out_addr(type, data); + nl(); + break; + + case I_LD_UP: + ot("__ld.up\t\t"); + out_addr(type, data); + nl(); + break; + + case X_LD_WAR: + ot("__ld.war\t"); + out_type(type, data); + nl(); + break; + + case X_LD_BAR: + ot("__ld.bar\t"); + out_type(type, data); + nl(); + break; + + case X_LD_UAR: + ot("__ld.uar\t"); + out_type(type, data); + nl(); + break; + + case X_LD_BAY: + ot("__ld.bay\t"); + out_type(type, data); + nl(); + break; + + case X_LD_UAY: + ot("__ld.uay\t"); + out_type(type, data); + nl(); + break; + + case X_LD_WS: + ot("__ld.ws\t\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD_BS: + ot("__ld.bs\t\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD_US: + ot("__ld.us\t\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD_WSQ: + ot("__ld.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD_BSQ: + ot("__ld.bsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD_USQ: + ot("__ld.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDY_WSQ: + ot("__ldy.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDY_BSQ: + ot("__ldy.bsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDY_USQ: + ot("__ldy.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDP_WAR: + ot("__ldp.war\t"); + out_type(type, data); + nl(); + break; + + case X_LDP_BAR: + ot("__ldp.bar\t"); + out_type(type, data); + nl(); + break; + + case X_LDP_UAR: + ot("__ldp.uar\t"); + out_type(type, data); + nl(); + break; + + case X_LDP_BAY: + ot("__ldp.bay\t"); + out_type(type, data); + nl(); + break; + + case X_LDP_UAY: + ot("__ldp.uay\t"); + out_type(type, data); + nl(); + break; + +// case X_LDWA_S: +// ot("__ld.was\t"); +// outsymbol((SYMBOL *)imm_data); +// outstr(", "); +// outdec((int)data); +// outlocal(tmp->sym); +// nl(); +// break; +// +// case X_LDBA_S: +// ot("__ld.bas\t"); +// outsymbol((SYMBOL *)imm_data); +// outstr(", "); +// outdec((int)data); +// outlocal(tmp->sym); +// nl(); +// break; +// +// case X_LDUBA_S: +// ot("__ld.uas\t"); +// outsymbol((SYMBOL *)imm_data); +// outstr(", "); +// outdec((int)data); +// outlocal(tmp->sym); +// nl(); +// break; + + /* i-codes for pre- and post- increment and decrement */ + + case X_INCLD_WM: + ot("__incld.wm\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_BM: + ot("__incld.bm\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_UM: + ot("__incld.um\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_WM: + ot("__decld.wm\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_BM: + ot("__decld.bm\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_UM: + ot("__decld.um\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_WM: + ot("__ldinc.wm\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_BM: + ot("__ldinc.bm\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_UM: + ot("__ldinc.um\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_WM: + ot("__lddec.wm\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_BM: + ot("__lddec.bm\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_UM: + ot("__lddec.um\t"); + out_type(type, data); + nl(); + break; + + case X_INC_WMQ: + ot("__inc.wmq\t"); + out_type(type, data); + nl(); + break; + + case X_INC_UMQ: + ot("__inc.umq\t"); + out_type(type, data); + nl(); + break; + + case X_DEC_WMQ: + ot("__dec.wmq\t"); + out_type(type, data); + nl(); + break; + + case X_DEC_UMQ: + ot("__dec.umq\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_WS: + ot("__incld.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_INCLD_BS: + ot("__incld.bs\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_INCLD_US: + ot("__incld.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_DECLD_WS: + ot("__decld.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_DECLD_BS: + ot("__decld.bs\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_DECLD_US: + ot("__decld.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDINC_WS: + ot("__ldinc.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDINC_BS: + ot("__ldinc.bs\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDINC_US: + ot("__ldinc.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDDEC_WS: + ot("__lddec.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDDEC_BS: + ot("__lddec.bs\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LDDEC_US: + ot("__lddec.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_INC_WSQ: + ot("__inc.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_INC_USQ: + ot("__inc.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_DEC_WSQ: + ot("__dec.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_DEC_USQ: + ot("__dec.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_INCLD_WAR: + ot("__incld.war\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_WAR: + ot("__ldinc.war\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_WAR: + ot("__decld.war\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_WAR: + ot("__lddec.war\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_BAR: + ot("__incld.bar\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_UAR: + ot("__incld.uar\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_BAR: + ot("__ldinc.bar\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_UAR: + ot("__ldinc.uar\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_BAR: + ot("__decld.bar\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_UAR: + ot("__decld.uar\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_BAR: + ot("__lddec.bar\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_UAR: + ot("__lddec.uar\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_BAY: + ot("__incld.bay\t"); + out_type(type, data); + nl(); + break; + + case X_INCLD_UAY: + ot("__incld.uay\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_BAY: + ot("__ldinc.bay\t"); + out_type(type, data); + nl(); + break; + + case X_LDINC_UAY: + ot("__ldinc.uay\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_BAY: + ot("__decld.bay\t"); + out_type(type, data); + nl(); + break; + + case X_DECLD_UAY: + ot("__decld.uay\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_BAY: + ot("__lddec.bar\t"); + out_type(type, data); + nl(); + break; + + case X_LDDEC_UAY: + ot("__lddec.uar\t"); + out_type(type, data); + nl(); + break; + + case X_INC_WARQ: + ot("__inc.warq\t"); + out_type(type, data); + nl(); + break; + + case X_INC_UARQ: + ot("__inc.uarq\t"); + out_type(type, data); + nl(); + break; + + case X_INC_UAYQ: + ot("__inc.uayq\t"); + out_type(type, data); + nl(); + break; + + case X_DEC_WARQ: + ot("__dec.warq\t"); + out_type(type, data); + nl(); + break; + + case X_DEC_UARQ: + ot("__dec.uarq\t"); + out_type(type, data); + nl(); + break; + + case X_DEC_UAYQ: + ot("__dec.uayq\t"); + out_type(type, data); + nl(); + break; + + /* i-codes for saving the primary register */ + + case I_ST_WMIQ: + ot("__st.wmiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case I_ST_UMIQ: + ot("__st.umiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case I_ST_WPI: + ot("__st.wpi\t\t"); + outdec((int)data); + nl(); + break; + + case I_ST_UPI: + ot("__st.upi\t\t"); + outdec((int)data); + nl(); + break; + + case I_ST_WM: + ot("__st.wm\t\t"); + out_addr(type, data); + nl(); + break; + + case I_ST_UM: + ot("__st.um\t\t"); + out_addr(type, data); + nl(); + break; + + case I_ST_WP: + ot("__st.wp\t\t"); + out_addr(type, data); + nl(); + break; + + case I_ST_UP: + ot("__st.up\t\t"); + out_addr(type, data); + nl(); + break; + + case I_ST_WPT: + ol("__st.wpt"); + break; + + case I_ST_UPT: + ol("__st.upt"); + break; + + case X_ST_WSIQ: + ot("__st.wsiq\t"); + outdec((int)imm_data); + outstr(", "); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ST_USIQ: + ot("__st.usiq\t"); + outdec((int)imm_data); + outstr(", "); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ST_WS: + ot("__st.ws\t\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ST_US: + ot("__st.us\t\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_INDEX_WR: + ot("__index.wr\t"); + out_type(type, data); + nl(); + break; + + case X_INDEX_UR: + ot("__index.ur\t"); + out_type(type, data); + nl(); + break; + + case X_ST_WAT: + ot("__st.wat\t"); + out_type(type, data); + nl(); + break; + + case X_ST_UAT: + ot("__st.uat\t"); + out_type(type, data); + nl(); + break; + +// case X_STWA_S: +// ot("__stwa_s\t"); +// outsymbol((SYMBOL *)imm_data); +// outstr(", "); +// outdec((int)data); +// nl(); +// break; +// +// case X_STBA_S: +// ot("__stba_s\t"); +// outsymbol((SYMBOL *)imm_data); +// outstr(", "); +// outdec((int)data); +// nl(); +// break; + + /* i-codes for extending a byte to a word */ + + case I_EXT_BR: + ol("__ext.br"); + break; + + case I_EXT_UR: + ol("__ext.ur"); + break; + + /* i-codes for math with the primary register */ + + case I_COM_WR: + ol("__com.wr"); + break; + + case I_NEG_WR: + ol("__neg.wr"); + break; + + case I_ADD_WT: + ol("__add.wt"); + break; + + case I_ADD_WI: + ot("__add.wi\t"); + out_type(type, data); + nl(); + break; + + case I_ADD_WM: + ot("__add.wm\t"); + out_addr(type, data); + nl(); + break; + + case I_ADD_UM: + ot("__add.um\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_WS: + ot("__add.ws\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ADD_US: + ot("__add.us\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case I_SUB_WT: + ol("__sub.wt"); + break; + + case I_SUB_WI: + ot("__sub.wi\t"); + out_type(type, data); + nl(); + break; + + case I_SUB_WM: + ot("__sub.wm\t"); + out_addr(type, data); + nl(); + break; + + case I_SUB_UM: + ot("__sub.um\t"); + out_addr(type, data); + nl(); + break; + + case I_ISUB_WI: + ot("__isub.wi\t"); + out_type(type, data); + nl(); + break; + + case I_AND_WT: + ol("__and.wt"); + break; + + case I_AND_WI: + ot("__and.wi\t"); + out_type(type, data); + nl(); + break; + + case I_AND_UIQ: + ot("__and.uiq\t"); + out_type(type, data); + nl(); + break; + + case I_AND_WM: + ot("__and.wm\t"); + out_addr(type, data); + nl(); + break; + + case I_AND_UM: + ot("__and.um\t"); + out_addr(type, data); + nl(); + break; + + case I_EOR_WT: + ol("__eor.wt"); + break; + + case I_EOR_WI: + ot("__eor.wi\t"); + out_type(type, data); + nl(); + break; + + case I_EOR_WM: + ot("__eor.wm\t"); + out_addr(type, data); + nl(); + break; + + case I_EOR_UM: + ot("__eor.um\t"); + out_addr(type, data); + nl(); + break; + + case I_OR_WT: + ol("__or.wt"); + break; + + case I_OR_WI: + ot("__or.wi\t\t"); + out_type(type, data); + nl(); + break; + + case I_OR_WM: + ot("__or.wm\t"); + out_addr(type, data); + nl(); + break; + + case I_OR_UM: + ot("__or.um\t"); + out_addr(type, data); + nl(); + break; + + case I_ASL_WT: + ol("__asl.wt"); + break; + + case I_ASL_WI: + ot("__asl.wi\t"); + out_type(type, data); + nl(); + break; + + case I_ASL_WR: + ol("__asl.wr"); + break; + + case I_ASR_WT: + ol("__asr.wt"); + break; + + case I_ASR_WI: + ot("__asr.wi\t"); + out_type(type, data); + nl(); + break; + + case I_LSR_WT: + ol("__lsr.wt"); + break; + + case I_LSR_WI: + ot("__lsr.wi\t"); + out_type(type, data); + nl(); + break; + + case I_LSR_UIQ: + ot("__lsr.uiq\t"); + out_type(type, data); + nl(); + break; + + case I_MUL_WT: + ol("__mul.wt"); + break; + + case I_MUL_WI: + ot("__mul.wi\t"); + out_type(type, data); + nl(); + break; + + case I_SDIV_WT: + ol("__sdiv.wt"); + break; + + case I_SDIV_WI: + ot("__sdiv.wi\t"); + out_type(type, data); + nl(); + break; + + case I_UDIV_WT: + ol("__udiv.wt"); + break; + + case I_UDIV_WI: + ot("__udiv.wi\t"); + out_type(type, data); + nl(); + break; + + case I_UDIV_UI: + ot("__udiv.ui\t"); + out_type(type, data); + nl(); + break; + + case I_SMOD_WT: + ol("__smod.wt"); + break; + + case I_SMOD_WI: + ot("__smod.wi\t"); + out_type(type, data); + nl(); + break; + + case I_UMOD_WT: + ol("__umod.wt"); + break; + + case I_UMOD_WI: + ot("__umod.wi\t"); + out_type(type, data); + nl(); + break; + + case I_UMOD_UI: + ot("__umod.ui\t"); + out_type(type, data); + nl(); + break; + + case I_DOUBLE: + ol("__double"); + break; + + default: + gen_asm(tmp); + break; + } +} + +/* ---- + * gen_asm() + * ---- + * generate optimizer asm code + * + */ +void gen_asm (INS *inst) +{ +// int type = inst->ins_type; +// intptr_t data = inst->ins_data; + + /* i-codes for 32-bit longs */ + + switch (inst->ins_code) { + + case X_LDD_I: + ot("__ldd_i\t\t"); + outdec((int)inst->ins_data); + outstr(", "); + prefix(); + outstr(inst->arg[0]); + outstr(", "); + prefix(); + outstr(inst->arg[1]); + nl(); + break; + + case X_LDD_W: + ot("__ldd_w\t\t"); + outsymbol((SYMBOL *)inst->ins_data); + outstr(", "); + prefix(); + outstr(inst->arg[0]); + outstr(", "); + prefix(); + outstr(inst->arg[1]); + nl(); + break; + + case X_LDD_B: + ot("__ldd_b\t\t"); + outsymbol((SYMBOL *)inst->ins_data); + outstr(", "); + prefix(); + outstr(inst->arg[0]); + outstr(", "); + prefix(); + outstr(inst->arg[1]); + nl(); + break; + + case X_LDD_S_W: + ot("__ldd_s_w\t"); + outdec((int)inst->ins_data); + outstr(", "); + prefix(); + outstr(inst->arg[0]); + outstr(", "); + prefix(); + outstr(inst->arg[1]); + nl(); + break; + + case X_LDD_S_B: + ot("__ldd_s_b\t"); + outdec((int)inst->ins_data); + outstr(", "); + prefix(); + outstr(inst->arg[0]); + outstr(", "); + prefix(); + outstr(inst->arg[1]); + nl(); + break; + + default: + error("internal error: invalid instruction"); + break; + } +} diff --git a/src/hucc/code.h b/src/hucc/code.h new file mode 100644 index 00000000..5f62b6ba --- /dev/null +++ b/src/hucc/code.h @@ -0,0 +1,30 @@ +/* File code.h: 2.2 (84/11/27,16:26:11) */ +/*% cc -O -c % + * + */ + +#ifndef _CODE_H +#define _CODE_H + +#include "defs.h" + +extern int segment; + +void gdata (void); +void gtext (void); +void header (void); +void inc_startup (void); +void asmdefines (void); +void defbyte (void); +void defstorage (void); +void defword (void); +void out_ins (int code, int type, intptr_t data); +void out_ins_ex (int code, int type, intptr_t data, int imm_type, intptr_t imm_data); +void out_ins_sym (int code, int type, intptr_t data, SYMBOL *sym); +void out_ins_cmp (int code, int type); +void gen_ins (INS *tmp); +void gen_code (INS *tmp); + +void dump_ins (INS *tmp); + +#endif diff --git a/src/hucc/const.c b/src/hucc/const.c new file mode 100644 index 00000000..c0f739bc --- /dev/null +++ b/src/hucc/const.c @@ -0,0 +1,402 @@ +/* File const.c: 2.1 (00/07/17,16:02:19) */ +/*% cc -O -c % + * + */ + +/* XXX: This passes the initializer more or less verbatim to the assembler, + which unsurprisingly does not care much for C semantics, breaking stuff + like pointer arithmetic, and probably many non-trivial expressions. + Needs a rewrite. */ + +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "const.h" +#include "error.h" +#include "io.h" +#include "lex.h" +#include "primary.h" +#include "sym.h" + +/* + * setup a new const array + * + */ +void new_const (void) +{ + const_ptr = &const_var[const_nb]; + const_val_idx = const_val_start; + const_data_idx = const_data_start; +} + + +/* + * add a const array + * + */ +void add_const (char typ) +{ + if ((const_data_idx >= MAX_CONST_DATA) || (const_val_idx >= MAX_CONST_VALUE)) + error("too much constant data (> 8KB)"); + if (const_nb >= MAX_CONST) + error("too much constant arrays"); + else { + const_ptr->sym = cptr; + const_ptr->typ = typ; + const_ptr->size = const_val_idx - const_val_start; + const_ptr->data = const_val_start; + const_val_start = const_val_idx; + const_data_start = const_data_idx; + const_nb++; + } +} + + +/* + * array initializer + * + */ +int array_initializer (char typ, char id, char stor, int k) +{ + int nb = 0; + int i; + + if (stor == CONST) + new_const(); + if (match("=")) { + if (stor != CONST) + error("can't initialize non-const arrays"); + if (!match("{")) { + error("syntax error"); + return (-1); + } + if (!match("}")) { + for (;;) { + if (match("}")) { + error("value missing"); + break; + } + if (match(",")) { + error("value missing"); + continue; + } + if ((ch() == '\"') && (id == POINTER)) + i = get_string_ptr(typ); + else + i = get_raw_value(','); + nb++; + blanks(); + if (const_val_idx < MAX_CONST_VALUE) + const_val[const_val_idx++] = i; + if ((ch() != ',') && (ch() != '}')) { + error("syntax error"); + return (-1); + } + if (match("}")) + break; + gch(); + } + } + if (k == 0) + k = nb; + if (nb > k) { + nb = k; + error("excess elements in array initializer"); + } + } + if (stor == CONST) { + while (nb < k) { + nb++; + if (const_val_idx < MAX_CONST_VALUE) + const_val[const_val_idx++] = -1; + } + } + return (k); +} + +/* + * scalar initializer + * + */ +int scalar_initializer (char typ, char id, char stor) +{ + int i; + + if (stor == CONST) + new_const(); + if (match("=")) { + if (stor != CONST) + error("can't initialize non-const scalars"); + blanks(); + if (ch() == ';') { + error("value missing"); + return (-1); + } + if (ch() == '\"' && id == POINTER) + i = get_string_ptr(typ); + else + i = get_raw_value(';'); + if (const_val_idx < MAX_CONST_VALUE) + const_val[const_val_idx++] = i; + blanks(); + if (ch() != ';') { + error("syntax error"); + return (-1); + } + } + return (1); +} + + +/* + * add a string to the literal pool and return a pointer (index) to it + * + */ +int get_string_ptr (char typ) +{ + int num; + + if (typ == CINT || typ == CUINT) + error("incompatible pointer type"); + if (qstr(&num)) + return (-(num + 1024)); + else + return (-1); +} + + +/* + * get value raw text + * + */ +int get_raw_value (char sep) +{ + char c; + char tmp[LINESIZE + 1]; + char *ptr; + int level; + int flag; + int start; + int is_address = 0; + int had_address = 0; + + flag = 0; + level = 0; + start = const_data_idx; + ptr = tmp; + + for (;;) { + c = ch(); + + /* discard blanks */ + if ((c == ' ') || (c == '\t')) { + gch(); + continue; + } + /* string */ + if (c == '\"') { + for (;;) { + gch(); + + /* add char */ + if (const_data_idx < MAX_CONST_DATA) + const_data[const_data_idx++] = c; + + /* next */ + c = ch(); + + if ((c == 0) || (c == '\"')) + break; + } + } + /* parenthesis */ + if (c == '(') + level++; + else if (c == ')') + level--; + /* comma separator */ + else if (c == sep) { + if (level == 0) + break; + } + /* end */ + else if ((c == 0) || (c == '}')) { + if (level) + error("syntax error"); + break; + } + + /* parse */ + if (alphanum(c)) { + flag = 1; + *ptr++ = c; + } + else { + /* add buffer */ + if (flag) { + flag = 0; + *ptr = '\0'; + ptr = tmp; + had_address += add_buffer(tmp, c, is_address); + is_address = 0; + if ((c == '+' || c == '-') && had_address) { + /* Initializers are passed almost + verbatim to the assembler, which + doesn't know anything about types + and thus doesn't know how to do + pointer arithmetic correctly, so + we don't allow it. */ + error("pointer arithmetic in initializers not supported"); + return (0); + } + } + + /* add char */ + if (c == '&') { + /* we want the succeeding identifier's address */ + is_address = 1; + /* we need to remember that we had an address + somewhere so we can barf if the identifier + contains arithmetic */ + had_address = 1; + } + else if (const_data_idx < MAX_CONST_DATA) + const_data[const_data_idx++] = c; + } + gch(); + } + /* add buffer */ + if (flag) { + *ptr = '\0'; + add_buffer(tmp, c, is_address); + } + /* close string */ + if (const_data_idx < MAX_CONST_DATA) + const_data[const_data_idx++] = '\0'; + + return (start); +} + + +/* + * add a string to the constant pool + * handle underscore + * + */ +int add_buffer (char *p, char c, int is_address) +{ + SYMBOL *s = 0; + + /* underscore */ + if (alpha(*p)) { + if (!is_address) { + s = findglb(p); + if (!s) { + error("undefined global"); + return (0); + } + /* Unless preceded by an address operator, we + need to get the value, and it better be + constant... */ + p = get_const(s); + if (!p) { + error("non-constant initializer"); + return (0); + } + } + else if (c != '(') { + /* If we want the address, we need an underscore + prefix. */ + if (const_data_idx < MAX_CONST_DATA) + const_data[const_data_idx++] = '_'; + } + } + + /* string */ + while (*p) { + if (const_data_idx < MAX_CONST_DATA) + const_data[const_data_idx++] = *p; + p++; + } + + /* tell the caller if there were any addresses involved */ + return ((s && s->identity == POINTER) || is_address); +} + +char *get_const (SYMBOL *s) +{ + int i; + struct const_array *const_ptr; + + if (const_nb) { + const_ptr = const_var; + + for (i = 0; i < const_nb; i++) { + if (const_ptr->sym == s) { + int j = const_val[const_ptr->data]; + if (j >= 0) + return (&const_data[j]); + else + return (0); + } + const_ptr++; + } + } + return (0); +} + +/* + * dump the constant pool + * + */ +void dump_const (void) +{ + int i, j, k; + int size; + + if (const_nb) { + const_ptr = const_var; + + for (i = 0; i < const_nb; i++) { + size = const_ptr->size; + cptr = const_ptr->sym; + cptr->storage = EXTERN; + prefix(); + outstr(cptr->name); + outstr(":"); + nl(); + j = const_ptr->data; + + while (size) { + k = const_val[j++]; + + if ((cptr->sym_type == CCHAR || cptr->sym_type == CUCHAR) && + cptr->identity != POINTER && + !(cptr->identity == ARRAY && cptr->ptr_order > 0)) { + defbyte(); + const_size += 1; + } + else { + defword(); + const_size += 2; + } + if ((k == -1) || (k >= MAX_CONST_DATA)) + outstr("0"); + else if (k <= -1024) { + k = (-k) - 1024; + outconst(litlab); + outbyte('+'); + outdec(k); + } + else + outstr(&const_data[k]); + nl(); + size--; + } + const_ptr++; + } + } +} diff --git a/src/hucc/const.h b/src/hucc/const.h new file mode 100644 index 00000000..045de38a --- /dev/null +++ b/src/hucc/const.h @@ -0,0 +1,19 @@ +/* File const.h: 2.1 (00/07/17,16:02:19) */ +/*% cc -O -c % + * + */ + +#ifndef _CONST_H +#define _CONST_H + +void new_const (void); +void add_const (char typ); +int array_initializer (char typ, char id, char stor, int k); +int scalar_initializer (char typ, char id, char stor); +int get_string_ptr (char typ); +int get_raw_value (char sep); +int add_buffer (char *p, char c, int is_address); +void dump_const (void); +char *get_const (SYMBOL *); + +#endif diff --git a/src/hucc/data.c b/src/hucc/data.c new file mode 100644 index 00000000..52948503 --- /dev/null +++ b/src/hucc/data.c @@ -0,0 +1,126 @@ +/* File data.c: 2.2 (84/11/27,16:26:13) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include "defs.h" + +/* constant arrays storage */ + +struct const_array *const_ptr; +struct const_array const_var[MAX_CONST]; +int const_val[MAX_CONST_VALUE]; +char const_data[MAX_CONST_DATA]; +int const_val_start; +int const_val_idx; +int const_data_start; +int const_data_idx; +int const_size; +int const_nb; + +/* storage words */ + +SYMBOL symtab[SYMTBSZ]; +int glbsym_index, rglbsym_index, locsym_index; + +int ws[WS_TOTAL]; +int *wsptr; + +int swstcase[SWST_COUNT]; +int swstlabel[SWST_COUNT]; +int swstp; +char litq[LITABSZ]; +char litq2[LITABSZ]; +int litptr; +struct macro macq[MACQSIZE]; +int macptr; +char line[LINESIZE]; +char mline[LINESIZE]; +int lptr, mptr; + +TAG_SYMBOL tag_table[NUMTAG]; // start of structure tag table +int tag_table_index; // ptr to next entry + +SYMBOL member_table[NUMMEMB]; // structure member table +int member_table_index; // ptr to next member + +char asmdefs[LITABSZ]; + +/* miscellaneous storage */ + +int nxtlab, + litlab, + stkp, + argstk, + ncmp, + errcnt, + glbflag, + indflg, + ctext, + cmode, + lastst, + overlayflag, + optimize, + globals_h_in_process; + +int top_level_stkp; + +FILE *input, *input2, *output; +FILE *inclstk[INCLSIZ]; + +char inclstk_name[INCLSIZ][FILENAMESIZE]; +char fname_copy[FILENAMESIZE]; +char user_outfile[FILENAMESIZE]; +int inclstk_line[INCLSIZ]; +int line_number; + +int inclsp; +char fname[FILENAMESIZE]; + +char quote[2]; +SYMBOL *cptr; +int *iptr; +int fexitlab; +int iflevel, skiplevel; +int errfile; +int debug; +int sflag; +int cdflag; +int acflag; +int sgflag; +int ted2flag; +int verboseflag; +int startup_incl; +int errs; + +int norecurse = 0; +#if ULI_NORECURSE +int local_offset; +#endif + +struct type_type *typedefs; +int typedef_ptr = 0; + +struct clabel *clabels; +int clabel_ptr = 0; + +struct enum_s *enums; +int enum_ptr = 0; +struct enum_type *enum_types; +int enum_type_ptr = 0; + +int user_short_enums = 1; +int user_signed_char = 0; + +int output_globdef; + +char **leaf_functions = 0; +int leaf_cnt = 0; +int leaf_size = 0; + +INITIALS initials_table[NUMGLBS]; +char initials_data_table[INITIALS_SIZE]; // 5kB space for initialisation data +int initials_idx = 0, initials_data_idx = 0; diff --git a/src/hucc/data.h b/src/hucc/data.h new file mode 100644 index 00000000..3d6243e4 --- /dev/null +++ b/src/hucc/data.h @@ -0,0 +1,122 @@ +/* File data.h: 2.2 (84/11/27,16:26:11) */ + +#include +#include +#include + +#include "defs.h" + +/* constant arrays storage */ + +extern struct const_array *const_ptr; +extern struct const_array const_var[MAX_CONST]; +extern int const_val[MAX_CONST_VALUE]; +extern char const_data[MAX_CONST_DATA]; +extern int const_val_start; +extern int const_val_idx; +extern int const_data_start; +extern int const_data_idx; +extern int const_size; +extern int const_nb; + +/* storage words */ + +extern SYMBOL symtab[]; +extern int glbsym_index, rglbsym_index, locsym_index; +extern int ws[]; +extern int *wsptr; +extern int swstcase[]; +extern int swstlabel[]; +extern int swstp; +extern char litq[]; +extern char litq2[]; +extern int litptr; +extern struct macro macq[]; +extern int macptr; +extern char line[]; +extern char mline[]; +extern int lptr, mptr; + +extern TAG_SYMBOL tag_table[NUMTAG]; // start of structure tag table +extern int tag_table_index; // ptr to next entry + +extern SYMBOL member_table[NUMMEMB]; // structure member table +extern int member_table_index; // ptr to next member< + +extern char asmdefs[]; + +/* miscellaneous storage */ + +extern int nxtlab, + litlab, + stkp, + argstk, + ncmp, + errcnt, + glbflag, + indflg, + ctext, + cmode, + lastst, + overlayflag, + optimize, + globals_h_in_process; + +extern FILE *input, *input2, *output; +extern FILE *inclstk[]; + +extern char inclstk_name[INCLSIZ][FILENAMESIZE]; +extern int inclstk_line[]; +extern char fname_copy[FILENAMESIZE]; +extern char user_outfile[FILENAMESIZE]; +extern int line_number; + +extern int inclsp; +extern char fname[]; + +extern char quote[]; +extern SYMBOL *cptr; +extern int *iptr; +extern int fexitlab; +extern int iflevel, skiplevel; +extern int errfile; +extern int debug; +extern int sflag; +extern int cdflag; +extern int acflag; +extern int sgflag; +extern int ted2flag; +extern int verboseflag; +extern int startup_incl; +extern int errs; + +extern int top_level_stkp; +extern int norecurse; +#if ULI_NORECURSE +extern int local_offset; +#endif +extern char current_fn[]; + +extern struct type_type *typedefs; +extern int typedef_ptr; + +extern struct clabel *clabels; +extern int clabel_ptr; + +extern struct enum_s *enums; +extern int enum_ptr; +extern struct enum_type *enum_types; +extern int enum_type_ptr; + +extern int user_short_enums; +extern int user_signed_char; + +extern int output_globdef; + +extern char **leaf_functions; +extern int leaf_cnt; +extern int leaf_size; + +extern INITIALS initials_table[NUMGLBS]; +extern char initials_data_table[INITIALS_SIZE]; // 5kB space for initialisation data +extern int initials_idx, initials_data_idx; diff --git a/src/hucc/defs.h b/src/hucc/defs.h new file mode 100644 index 00000000..78e099f3 --- /dev/null +++ b/src/hucc/defs.h @@ -0,0 +1,676 @@ +/* File defs.h: 2.1 (83/03/21,02:07:20) */ + +#ifndef INCLUDE_DEFS_H +#define INCLUDE_DEFS_H + +#define ULI_NORECURSE 1 + +/* + * i-code pseudo instructions + * + * N.B. this i-code enum list MUST be kept updated and in the same order + * as the table of i-code flag information in optimize.c + */ +enum ICODE { + /* i-code that retires the primary register contents */ + + I_FENCE = 1, + + /* i-code that declares a byte sized primary register */ + + I_SHORT, + + /* i-codes for handling farptr */ + + I_FARPTR, + I_FARPTR_I, + I_FARPTR_GET, + I_FGETW, + I_FGETB, + I_FGETUB, + + /* i-codes for interrupts */ + + I_SEI, + I_CLI, + + /* i-codes for calling functions */ + + I_MACRO, + I_CALL, + I_FUNCP_WR, + I_CALLP, + + /* i-codes for C functions and the C parameter stack */ + + I_ENTER, + I_RETURN, + I_GETACC, + I_SAVESP, + I_LOADSP, + I_MODSP, + I_PUSH_WR, + I_POP_WR, + I_SPUSH_WR, /* push and pop on the hw-stack */ + I_SPUSH_UR, /* to temporarily save data */ + I_SPOP_WR, + I_SPOP_UR, + + /* i-codes for handling boolean tests and branching */ + + I_SWITCH_WR, + I_SWITCH_UR, + I_CASE, + I_ENDCASE, + I_LABEL, + I_ALIAS, + I_BRA, + I_BFALSE, + I_BTRUE, + I_DEF, + + I_CMP_WT, + X_CMP_WI, + X_CMP_WM, + X_CMP_WS, + + X_CMP_UIQ, + X_CMP_UMQ, + X_CMP_USQ, + + I_NOT_WR, + X_NOT_WP, + X_NOT_WM, + X_NOT_WS, + X_NOT_WAR, + X_NOT_UP, + X_NOT_UM, + X_NOT_US, + X_NOT_UAR, + X_NOT_UAY, + + I_TST_WR, + X_TST_WP, + X_TST_WM, + X_TST_WS, + X_TST_WAR, + X_TST_UP, + X_TST_UM, + X_TST_US, + X_TST_UAR, + X_TST_UAY, + + X_NAND_WI, + X_TAND_WI, + + X_NOT_CF, + + I_BOOLEAN, + X_BOOLNOT_WR, + X_BOOLNOT_WP, + X_BOOLNOT_WM, + X_BOOLNOT_WS, + X_BOOLNOT_WAR, + X_BOOLNOT_UP, + X_BOOLNOT_UM, + X_BOOLNOT_US, + X_BOOLNOT_UAR, + X_BOOLNOT_UAY, + + /* i-codes for loading the primary register */ + + I_LD_WI, + X_LD_UIQ, + I_LEA_S, + + I_LD_WM, + I_LD_BM, + I_LD_UM, + + I_LD_WMQ, + I_LD_BMQ, + I_LD_UMQ, + + I_LDY_WMQ, + I_LDY_BMQ, + I_LDY_UMQ, + + I_LD_WP, + I_LD_BP, + I_LD_UP, + + X_LD_WAR, + X_LD_BAR, + X_LD_UAR, + + X_LD_BAY, + X_LD_UAY, + + X_LD_WS, + X_LD_BS, + X_LD_US, + + X_LD_WSQ, + X_LD_BSQ, + X_LD_USQ, + + X_LDY_WSQ, + X_LDY_BSQ, + X_LDY_USQ, + + X_LDP_WAR, + X_LDP_BAR, + X_LDP_UAR, + + X_LDP_BAY, + X_LDP_UAY, + + /* i-codes for pre- and post- increment and decrement */ + + X_INCLD_WM, + X_INCLD_BM, + X_INCLD_UM, + + X_DECLD_WM, + X_DECLD_BM, + X_DECLD_UM, + + X_LDINC_WM, + X_LDINC_BM, + X_LDINC_UM, + + X_LDDEC_WM, + X_LDDEC_BM, + X_LDDEC_UM, + + X_INC_WMQ, + X_INC_UMQ, + + X_DEC_WMQ, + X_DEC_UMQ, + + X_INCLD_WS, + X_INCLD_BS, + X_INCLD_US, + + X_DECLD_WS, + X_DECLD_BS, + X_DECLD_US, + + X_LDINC_WS, + X_LDINC_BS, + X_LDINC_US, + + X_LDDEC_WS, + X_LDDEC_BS, + X_LDDEC_US, + + X_INC_WSQ, + X_INC_USQ, + + X_DEC_WSQ, + X_DEC_USQ, + + X_INCLD_WAR, + X_LDINC_WAR, + X_DECLD_WAR, + X_LDDEC_WAR, + + X_INCLD_BAR, + X_INCLD_UAR, + X_LDINC_BAR, + X_LDINC_UAR, + X_DECLD_BAR, + X_DECLD_UAR, + X_LDDEC_BAR, + X_LDDEC_UAR, + + X_INCLD_BAY, + X_INCLD_UAY, + X_LDINC_BAY, + X_LDINC_UAY, + X_DECLD_BAY, + X_DECLD_UAY, + X_LDDEC_BAY, + X_LDDEC_UAY, + + X_INC_WARQ, + X_INC_UARQ, + X_INC_UAYQ, + + X_DEC_WARQ, + X_DEC_UARQ, + X_DEC_UAYQ, + + /* i-codes for saving the primary register */ + + I_ST_WMIQ, + I_ST_UMIQ, + I_ST_WPI, + I_ST_UPI, + I_ST_WM, + I_ST_UM, + I_ST_WP, + I_ST_UP, + I_ST_WPT, + I_ST_UPT, + X_ST_WSIQ, + X_ST_USIQ, + X_ST_WS, + X_ST_US, + + X_INDEX_WR, + X_INDEX_UR, + + X_ST_WAT, + X_ST_UAT, + + /* i-codes for extending the primary register */ + + I_EXT_BR, + I_EXT_UR, + + /* i-codes for math with the primary register */ + + I_COM_WR, + I_NEG_WR, + + I_ADD_WT, + I_ADD_WI, + I_ADD_WM, + I_ADD_UM, + X_ADD_WS, + X_ADD_US, + + I_SUB_WT, + I_SUB_WI, + I_SUB_WM, + I_SUB_UM, + + I_ISUB_WI, + + I_AND_WT, + I_AND_WI, + I_AND_UIQ, + I_AND_WM, + I_AND_UM, + + I_EOR_WT, + I_EOR_WI, + I_EOR_WM, + I_EOR_UM, + + I_OR_WT, + I_OR_WI, + I_OR_WM, + I_OR_UM, + + I_ASL_WT, + I_ASL_WI, + I_ASL_WR, + + I_ASR_WT, + I_ASR_WI, + + I_LSR_WT, + I_LSR_WI, + I_LSR_UIQ, + + I_MUL_WT, + I_MUL_WI, + + I_SDIV_WT, + I_SDIV_WI, + + I_UDIV_WT, + I_UDIV_WI, + I_UDIV_UI, + + I_SMOD_WT, + I_SMOD_WI, + + I_UMOD_WT, + I_UMOD_WI, + I_UMOD_UI, + + I_DOUBLE, + + /* i-codes for 32-bit longs */ + + X_LDD_I, + X_LDD_W, + X_LDD_B, + X_LDD_S_W, + X_LDD_S_B +}; + +/* + * boolean comparison operations + */ +enum ICOMPARE { + CMP_EQU, + CMP_NEQ, + CMP_SLT, + CMP_SLE, + CMP_SGT, + CMP_SGE, + CMP_ULT, + CMP_ULE, + CMP_UGT, + CMP_UGE +}; + +/* + * INTSIZE is the size of an integer in the target machine + * BYTEOFF is the offset of an byte within an integer on the + * target machine. (ie: 8080,pdp11 = 0, 6809 = 1, + * 360 = 3) + * This compiler assumes that an integer is the SAME length as + * a pointer - in fact, the compiler uses INTSIZE for both. + */ + +#define INTSIZE 2 +#define BYTEOFF 0 + +/* pseudo instruction arg types */ +#define T_NOP -1 +#define T_VALUE 1 +#define T_LABEL 2 +#define T_SYMBOL 3 +#define T_PTR 4 +#define T_STACK 5 +#define T_STRING 6 +#define T_SIZE 7 +#define T_BANK 8 +#define T_VRAM 9 +#define T_PAL 10 +#define T_LITERAL 11 + +#define FOREVER for (;;) +#define FALSE 0 +#define TRUE 1 +#define NO 0 +#define YES 1 + +/* miscellaneous */ + +#define EOS 0 +#define EOL 10 +#define BKSP 8 +#define CR 13 +#define FFEED 12 +#define TAB 9 + +#define FILENAMESIZE 256 + +/* symbol table parameters (locals are reset for every function) */ +#define SYMTBSZ 4096 +#define NUMGLBS (SYMTBSZ - 512) + +#define STARTGLB 0 +#define ENDGLB (NUMGLBS - 1) +#define STARTLOC (NUMGLBS) +#define ENDLOC (SYMTBSZ - 1) + +/* symbol table entry format */ +/* N.B. nasty hack to allow space beyond NAMEMAX (see "copysym") */ + +#define NAMESIZE 48 +#define NAMEMAX 47 +#define NAMEALLOC 64 + +typedef struct symbol { + char name[NAMEALLOC]; /* symbol name */ + struct symbol *linked; /* HuC: linked local and global symbols */ + int alloc_size; + char identity; /* variable, array, pointer, function */ + char sym_type; /* char, int, uchar, unit */ + char storage; /* public, auto, extern, static, lstatic, defauto*/ + char far; /* HuC: 1 if array of data in far memory */ + char ptr_order; /* HuC: 1 if array of data in far memory */ + char funcptr_type; /* HuC: return type if function pointer */ + char funcptr_order; /* HuC: return order if function pointer */ + char arg_count; /* HuC: #arguments for function or function pointer */ + short offset; /* offset*/ + short tagidx; /* index of struct in tag table*/ +} SYMBOL; + +/* Define the structure tag table parameters */ + +#define NUMTAG 64 + +struct tag_symbol { + char name[NAMESIZE]; /* structure tag name */ + int size; /* size of struct in bytes */ + int member_idx; /* index of first member */ + int number_of_members; /* number of tag members */ +}; +#define TAG_SYMBOL struct tag_symbol + +#define NULL_TAG 0 + +/* Define the structure member table parameters */ + +#define NUMMEMB 256 + +/* possible entries for "ident" */ + +#define VARIABLE 1 +#define ARRAY 2 +#define POINTER 3 +#define FUNCTION 4 + +/* possible entries for "type" for sym_type, val_type, type_type, init_type */ + +#define CCHAR 1 +#define CINT 2 +#define CVOID 3 +#define CSTRUCT 4 +#define CENUM 5 +#define CSIGNED 0 +#define CUNSIGNED 8 +#define CUINT (CINT | CUNSIGNED) +#define CUCHAR (CCHAR | CUNSIGNED) + +/* possible entries for storage */ + +#define PUBLIC 1 +#define AUTO 2 +#define EXTERN 3 +#define STATIC 4 +#define LSTATIC 5 +#define DEFAUTO 6 +#define CONST 7 + +#define STORAGE 15 /* bitmask for the storage type */ + +#define WASAUTO 64 +#define WRITTEN 128 + +/* "do"/"for"/"while"/"switch" statement stack */ + +#define WS_COUNT 7 /* number of ints per "while" entry */ +#define WS_TOTAL (20 * WS_COUNT) +#define WS_LIMIT (ws + WS_TOTAL - WS_COUNT) + +/* entry offsets in "do"/"for"/"while"/"switch" stack */ + +#define WS_LOCSYM_INDEX 0 /* locsym_index to restore at the end of the compound statement */ +#define WS_STACK_OFFSET 1 /* stack offset to restore at the end of the compound statement */ +#define WS_TYPE 2 +#define WS_CASE_INDEX 3 /* switch label stack index of first "case" */ +#define WS_TEST_LABEL 3 +#define WS_INCR_LABEL 4 +#define WS_DEFAULT_LABEL 4 +#define WS_BODY_LABEL 5 +#define WS_TABLE_LABEL 5 /* label for dumpswitch() data table */ +#define WS_EXIT_LABEL 6 + +/* possible entries for "WS_TYPE" */ + +#define WS_WHILE 0 +#define WS_FOR 1 +#define WS_DO 2 +#define WS_SWITCH 3 + +/* "switch" label stack size */ + +#define SWST_COUNT 256 + +/* literal pool */ + +#define LITABSZ 8192 +#define LITMAX LITABSZ - 1 + +/* input string */ + +#define LITMAX2 LITABSZ - 1 + +/* input line */ + +#define LINESIZE 384 +#define LINEMAX (LINESIZE - 1) +#define MPMAX LINEMAX + +/* macro (define) pool */ + +#define MACQSIZE 16384 +#define MACMAX (MACQSIZE - 1) + +struct macro { + char *name; + char **args; + int argc; + struct { + int arg; + int pos; + } *argpos; + char *def; +}; + +/* "include" stack */ + +#define INCLSIZ 3 + +/* statement types (tokens) */ + +#define STIF 1 +#define STWHILE 2 +#define STRETURN 3 +#define STBREAK 4 +#define STCONT 5 +#define STASM 6 +#define STEXP 7 +#define STDO 8 +#define STFOR 9 +#define STSWITCH 10 +#define STGOTO 11 + +/* pseudo instruction structure */ + +typedef struct { + enum ICODE ins_code; + enum ICOMPARE cmp_type; + int ins_type; + intptr_t ins_data; + int imm_type; + intptr_t imm_data; + const char *arg[3]; + SYMBOL *sym; +} INS; + +/* constant array struct */ + +#define MAX_CONST 1024 +#define MAX_CONST_VALUE 8192 +#define MAX_CONST_DATA 65536 + +struct const_array { + SYMBOL *sym; + int typ; + int size; + int data; +}; + +/* fastcall func struct */ + +#define MAX_FASTCALL_ARGS 16 +#define FASTCALL_EXTRA 0x01 // bitmask values +#define FASTCALL_XSAFE 0x02 // bitmask values +#define FASTCALL_NOP 0x04 // bitmask values +#define FASTCALL_MACRO 0x08 // bitmask values + +struct fastcall { + struct fastcall *next; + char fname[NAMESIZE]; + int nargs; + int flags; + char argtype[MAX_FASTCALL_ARGS]; + char argname[MAX_FASTCALL_ARGS][NAMESIZE]; +}; + +// initialisation of global variables + +#define INIT_TYPE NAMESIZE +#define INIT_LENGTH NAMESIZE + 1 +#define INITIALS_SIZE 5 * 1024 + +struct initials_table { + char name[NAMESIZE]; /* symbol name */ + int init_type; /* type */ + int dim; /* length of data (possibly an array) */ + int data_len; /* index of tag or zero */ +}; +#define INITIALS struct initials_table + +SYMBOL *find_member (TAG_SYMBOL *tag, char *sname); + +struct lvalue { + SYMBOL *symbol; /* symbol table address, or 0 for constant */ + int indirect; /* type of object pointed to by primary register, 0 for static object */ + int ptr_type; /* type of pointer or array, 0 for other idents */ + TAG_SYMBOL *tagsym; /* tag symbol address, 0 if not struct */ + SYMBOL *symbol2; /* HuC: */ + int ptr_order; /* HuC: allows for more than 1 level of indirection */ + int val_type; /* HuC: type of current value, if known */ +}; +#define LVALUE struct lvalue + +#define W_GENERAL 1 + +/* typedef struct */ + +struct type_type { + int type_type; /* char, int, uchar, unit */ + int type_ident; /* variable, array, pointer */ + int ptr_order; + int otag; + int flags; + char sname[NAMESIZE]; /* type name */ +}; + +#define F_REGISTER 1 +#define F_CONST 2 +#define F_VOLATILE 4 +#define F_STRUCT 8 /* set if CSTRUCT is struct, not union */ + +struct clabel { + char name[NAMESIZE]; + int stkp; + int label; +}; + +struct enum_s { + char name[NAMESIZE]; + int enum_value; +}; + +/* enum struct */ + +struct enum_type { + char name[NAMESIZE]; + int start; + int base; +}; + +#endif diff --git a/src/hucc/enum.c b/src/hucc/enum.c new file mode 100644 index 00000000..6f5313f5 --- /dev/null +++ b/src/hucc/enum.c @@ -0,0 +1,109 @@ +/* Copyright (c) 2014, Ulrich Hecht + All rights reserved. + See LICENSE for details on use and redistribution. */ + +#include +#include +#include +#include +#include "data.h" +#include "error.h" +#include "io.h" +#include "lex.h" +#include "primary.h" +#include "sym.h" + +int define_enum (char *sname, int storage) +{ + char n[NAMESIZE]; + int count, min, max; + int start = enum_ptr; + +// printf("defenum %s\n", sname); + needbracket("{"); + count = min = max = 0; + for (;;) { + if (!symname(n)) { + illname(); + return (-1); + } + /* Add to global table of enum values. */ + enums = realloc(enums, (enum_ptr + 1) * sizeof(*enums)); + strcpy(enums[enum_ptr].name, n); + /* optional initializer */ + if (match("=")) { + int num; + if (const_expr(&num, ",", "}")) + count = num; + } + /* Remember minima and maxima to find the shortest type. */ + if (count > max) max = count; + if (count < min) min = count; + enums[enum_ptr].enum_value = count++; + enum_ptr++; + if (match("}")) + break; + if (!match(",")) { + error("expected comma"); + return (-1); + } + if (match("}")) + break; + } + /* Add to table of enum types. */ + enum_types = realloc(enum_types, (enum_type_ptr + 1) * sizeof(*enum_types)); + struct enum_type *et = &enum_types[enum_type_ptr]; + if (sname) + strcpy(et->name, sname); + else + et->name[0] = 0; + et->start = start; + if (!user_short_enums) { + et->base = CINT; + if (min < -32768 || max > 32767) + warning(W_GENERAL, "enum range too large"); + } + else if (min < 0) { + if (min < -128 || max > 127) { + et->base = CINT; + if (min < -32768 || max > 32767) + warning(W_GENERAL, "enum range too large"); + } + else + et->base = CCHAR; + } + else { + if (max > 65535) + warning(W_GENERAL, "enum range too large"); + if (max > 127) + et->base = CUINT; + else + et->base = CUCHAR; + } +// printf("enum base type %d\n", et->base); + return (enum_type_ptr++); +} + +int find_enum_type (char *name) +{ + int i; + + for (i = 0; i < enum_type_ptr; i++) { + if (!strcmp(enum_types[i].name, name)) + return (i); + } + return (-1); +} + +int find_enum (char *sname, int *val) +{ + int i; + + for (i = 0; i < enum_ptr; i++) { + if (!strcmp(sname, enums[i].name)) { + *val = enums[i].enum_value; + return (1); + } + } + return (0); +} diff --git a/src/hucc/enum.h b/src/hucc/enum.h new file mode 100644 index 00000000..a2d95142 --- /dev/null +++ b/src/hucc/enum.h @@ -0,0 +1,3 @@ +int define_enum (char *sname, int storage); +int find_enum_type (char *name); +int find_enum (char *sname, int *val); diff --git a/src/hucc/error.c b/src/hucc/error.c new file mode 100644 index 00000000..84ad9c5f --- /dev/null +++ b/src/hucc/error.c @@ -0,0 +1,84 @@ +/* File error.c: 2.1 (83/03/20,16:02:00) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "error.h" +#include "io.h" + +void error (char *ptr) +{ + FILE *tempfile; + + if (output == NULL) { + fprintf(stderr, "%s\n", ptr); + exit(1); + } + + tempfile = output; + output = stderr; + doerror(ptr, 0); + output = tempfile; + errcnt++; + if (errcnt > 3) { + errcnt = 0; + error("too many errors, aborting"); + exit(1); + } +} + +void warning (int type, char *text) +{ + FILE *tfp; + + assert(type > 0); + tfp = output; + output = stderr; + doerror(text, type); + output = tfp; +} + +void doerror (char *ptr, int type) +{ + int k; + + comment(); + if (!type) + outstr("error: "); + else + outstr("warning: "); + if (inclsp) + outstr(inclstk_name[inclsp - 1]); + else + outstr(fname_copy); + outbyte('('); + outdec(line_number); + outbyte(')'); + nl(); + comment(); + outstr(line); + nl(); + comment(); + k = 0; + while (k < lptr) { + if (line[k] == 9) + tab(); + else + outbyte(' '); + k++; + } + outbyte('^'); + nl(); + comment(); + outstr("****** "); + outstr(ptr); + outstr(" ******"); + nl(); +} diff --git a/src/hucc/error.h b/src/hucc/error.h new file mode 100644 index 00000000..1bd4e119 --- /dev/null +++ b/src/hucc/error.h @@ -0,0 +1,9 @@ +#ifndef _INCLUDE_ERROR_H +#define _INCLUDE_ERROR_H + +void error (char *); +void warning (int, char *); + +void doerror (char *, int); + +#endif diff --git a/src/hucc/expr.c b/src/hucc/expr.c new file mode 100644 index 00000000..3b0b7696 --- /dev/null +++ b/src/hucc/expr.c @@ -0,0 +1,1127 @@ +/* File expr.c: 2.2 (83/06/21,11:24:26) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "error.h" +#include "expr.h" +#include "function.h" +#include "gen.h" +#include "io.h" +#include "lex.h" +#include "primary.h" +#include "sym.h" + +/* + * lval->symbol - symbol table address, else 0 for constant + * lval->indirect - type indirect object to fetch, else 0 for static object + * lval->ptr_type - type of pointer or array, else 0 + */ +void expression (int comma) +{ + LVALUE lval[1] = {{0}}; + + expression_ex(lval, comma, NO); +} + +int expression_ex (LVALUE *lval, int comma, int norval) +{ + int k; + + do { + if ((k = heir1(lval, comma)) && !norval) + rvalue(lval); + if (!comma) + return (k); + blanks(); + if (ch() == ',') + gfence(); + } while (match(",")); + + return (k); +} + +/* + * C11 section 6.3.1.8 "Usual arithmetic conversions" + * + * ..... sbyte sword ubyte uword + * ---------------------------------------- + * sbyte | sbyte sword sword uword + * sword | sword sword sword uword + * ubyte | sword sword ubyte uword + * uword | uword uword uword uword + */ + +static int is_unsigned (LVALUE *lval) +{ + /* C promotes operations on an unsigned char + to a signed int, not an unsigned int! */ + + /* if using a pointer, then the pointer itself is CUINT */ + if (lval->ptr_type) + return (1); + + /* handle result type or typecast (which overrides symbol) */ + if (lval->val_type) + return (lval->val_type == CUINT); + + /* handle a symbol reference */ + if (lval->symbol && lval->symbol->sym_type == CUINT) + return (1); + + return (0); +} + +static int is_ptrptr (LVALUE *lval) +{ + SYMBOL *s = lval->symbol; + + return (s && (s->ptr_order > 1 || (s->identity == ARRAY && s->ptr_order > 0))); +} + +static void gen_scale_right (LVALUE *lval, LVALUE *lval2) +{ + if (dbltest(lval, lval2)) { + if (lval->tagsym) { + TAG_SYMBOL *tag = (TAG_SYMBOL *)(lval->tagsym); + if (tag->size == 2) + gaslint(); + else if (tag->size > 1) + gmult_imm(tag->size); + } + else + gaslint(); + } +} + +static void void_value_error (LVALUE *lval) +{ + error("function is declared VOID and does not return a value"); + /* suppress further error messages about this return value */ + lval->val_type = 0; +} + +/* + * assignment operators + * @param lval + * @return + */ +int heir1 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + char fc; + + k = heir1a(lval, comma); + if (match("=")) { + if (k == 0) { + needlval(); + return (0); + } + if (lval->indirect) + gpush(); + if (heir1(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + store(lval); + return (0); + } + else { + fc = ch(); + if (match("-=") || + match("+=") || + match("*=") || + match("/=") || + match("%=") || + match(">>=") || + match("<<=") || + match("&=") || + match("^=") || + match("|=")) { + if (k == 0) { + needlval(); + return (0); + } + if (lval->indirect) + gpush(); + rvalue(lval); + gpush(); + if (heir1(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + switch (fc) { + case '-': { + gen_scale_right(lval, lval2); + gsub(); + result(lval, lval2); + break; + } + case '+': { + gen_scale_right(lval, lval2); + gadd(lval, lval2); + result(lval, lval2); + break; + } + case '*': gmult(is_unsigned(lval) || is_unsigned(lval2)); break; + case '/': gdiv(is_unsigned(lval) || is_unsigned(lval2)); break; + case '%': gmod(is_unsigned(lval) || is_unsigned(lval2)); break; + case '>': gasr(is_unsigned(lval)); break; + case '<': gasl(); break; + case '&': gand(); break; + case '^': gxor(); break; + case '|': gor(); break; + } + store(lval); + return (0); + } + else + return (k); + } +} + +/* + * processes ? : expression + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir1a (LVALUE *lval, int comma) +{ + int k, lab1, lab2; + + k = heir1b(lval, comma); + blanks(); + if (ch() != '?') + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER + if (match("?")) { + testjump(lab1 = getlabel(), FALSE); + if (heir1b(lval, comma)) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + jump(lab2 = getlabel()); + gnlabel(lab1); + blanks(); + if (!match(":")) { + error("missing colon"); + return (0); + } + if (heir1b(lval, comma)) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + gnlabel(lab2); + } + else + return (0); +} + +/* + * processes logical or || + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir1b (LVALUE *lval, int comma) +{ + int k, lab; + LVALUE lval2[1] = {{0}}; + + k = heir1c(lval, comma); + blanks(); + if (!sstreq("||")) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER + if (match("||")) { + testjump(lab = getlabel(), TRUE); + if (heir1c(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gtest(); + gnlabel(lab); + gbool(); + } + else + return (0); +} + +/* + * processes logical and && + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir1c (LVALUE *lval, int comma) +{ + int k, lab; + LVALUE lval2[1] = {{0}}; + + k = heir2(lval, comma); + blanks(); + if (!sstreq("&&")) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER + if (match("&&")) { + testjump(lab = getlabel(), FALSE); + if (heir2(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gtest(); + gnlabel(lab); + gbool(); + } + else + return (0); +} + +/* + * processes bitwise or | + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir2 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir3(lval, comma); + blanks(); + if ((ch() != '|') || (nch() == '|') || (nch() == '=')) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if ((ch() == '|') && (nch() != '|') && (nch() != '=')) { + inbyte(); + gpush(); + if (heir3(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gor(); + blanks(); + } + else + return (0); + } +} + +/* + * processes bitwise exclusive or + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir3 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir4(lval, comma); + blanks(); + if ((ch() != '^') || (nch() == '=')) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if ((ch() == '^') && (nch() != '=')) { + inbyte(); + gpush(); + if (heir4(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gxor(); + blanks(); + } + else + return (0); + } +} + +/* + * processes bitwise and & + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir4 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir5(lval, comma); + blanks(); + if ((ch() != '&') || (nch() == '|') || (nch() == '=')) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if ((ch() == '&') && (nch() != '&') && (nch() != '=')) { + inbyte(); + gpush(); + if (heir5(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gand(); + blanks(); + } + else + return (0); + } +} + +/* + * processes equal and not equal operators + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir5 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir6(lval, comma); + blanks(); + if ((!sstreq("==")) && + (!sstreq("!="))) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if (match("==")) { + gpush(); + if (heir6(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + geq(); + } + else if (match("!=")) { + gpush(); + if (heir6(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gne(); + } + else + return (0); + } +} + +/* + * comparison operators + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir6 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir7(lval, comma); + blanks(); + if (!sstreq("<") && + !sstreq("<=") && + !sstreq(">=") && + !sstreq(">")) + return (k); + + if (sstreq("<<") || sstreq(">>")) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if (match("<=")) { + gpush(); + if (heir7(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + if (lval->ptr_type || lval2->ptr_type || + is_unsigned(lval) || + is_unsigned(lval2) + ) { + gule(); + continue; + } + gle(); + } + else if (match(">=")) { + gpush(); + if (heir7(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + if (lval->ptr_type || lval2->ptr_type || + is_unsigned(lval) || + is_unsigned(lval2) + ) { + guge(); + continue; + } + gge(); + } + else if ((sstreq("<")) && + !sstreq("<<")) { + inbyte(); + gpush(); + if (heir7(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + if (lval->ptr_type || lval2->ptr_type || + is_unsigned(lval) || + is_unsigned(lval2) + ) { + gult(); + continue; + } + glt(); + } + else if ((sstreq(">")) && + !sstreq(">>")) { + inbyte(); + gpush(); + if (heir7(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + if (lval->ptr_type || lval2->ptr_type || + is_unsigned(lval) || + is_unsigned(lval2) + ) { + gugt(); + continue; + } + ggt(); + } + else + return (0); + + blanks(); + } +} + +/* + * bitwise left, right shift + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir7 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir8(lval, comma); + blanks(); + if ((!sstreq(">>") && !sstreq("<<")) || + sstreq(">>=") || sstreq("<<=")) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if (sstreq(">>") && !sstreq(">>=")) { + inbyte(); inbyte(); + gpush(); + if (heir8(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gasr(is_unsigned(lval)); + } + else if (sstreq("<<") && !sstreq("<<=")) { + inbyte(); inbyte(); + gpush(); + if (heir8(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gasl(); + } + else + return (0); + + blanks(); + } +} + +/* + * addition, subtraction + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir8 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir9(lval, comma); + blanks(); + if (((ch() != '+') && (ch() != '-')) || (nch() == '=')) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if (match("+")) { + gpush(); + if (heir9(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + /* if left is pointer and right is int, scale right */ + gen_scale_right(lval, lval2); + /* will scale left if right int pointer and left int */ + gadd(lval, lval2); + result(lval, lval2); + } + else if (match("-")) { + gpush(); + if (heir9(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + /* if dbl, can only be: pointer - int, or + pointer - pointer, thus, + in first case, int is scaled up, + in second, result is scaled down. */ + gen_scale_right(lval, lval2); + gsub(); + /* if both pointers, scale result */ + if ((lval->ptr_type == CINT || lval->ptr_type == CUINT || is_ptrptr(lval)) && + (lval2->ptr_type == CINT || lval2->ptr_type == CUINT || is_ptrptr(lval2))) + gasrint(); /* divide by intsize */ + else if (lval->ptr_type == CSTRUCT && lval2->ptr_type == CSTRUCT) { + TAG_SYMBOL *tag = lval->tagsym; + if (tag->size == 2) + gasrint(); + else if (tag->size > 1) + gdiv_imm(tag->size); + } + result(lval, lval2); + } + else + return (0); + } +} + +/* + * multiplication, division, modulus + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir9 (LVALUE *lval, int comma) +{ + int k; + LVALUE lval2[1] = {{0}}; + + k = heir10(lval, comma); + blanks(); + if (((ch() != '*') && (ch() != '/') && + (ch() != '%')) || (nch() == '=')) + return (k); + + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + FOREVER { + if (match("*")) { + gpush(); + if (heir10(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gmult(is_unsigned(lval) || is_unsigned(lval2)); + } + else if (match("/")) { + gpush(); + if (heir10(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gdiv(is_unsigned(lval) || is_unsigned(lval2)); + } + else if (match("%")) { + gpush(); + if (heir10(lval2, comma)) + rvalue(lval2); + if (lval2->val_type == CVOID) + void_value_error(lval2); + gmod(is_unsigned(lval) || is_unsigned(lval2)); + } + else + return (0); + } +} + +/* + * increment, decrement, unary operators and pointer dereferencing + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir10 (LVALUE *lval, int comma) +{ + int k; + SYMBOL *ptr; + + if (match("++")) { + indflg = 0; + if ((k = heir10(lval, comma)) == 0) { + if (lval->val_type == CVOID) + void_value_error(lval); + else + needlval(); + return (0); + } + if (lval->indirect) + gpush(); + rvalue(lval); + ginc(lval); + store(lval); + return (0); + } + else if (match("--")) { + indflg = 0; + if ((k = heir10(lval, comma)) == 0) { + if (lval->val_type == CVOID) + void_value_error(lval); + else + needlval(); + return (0); + } + if (lval->indirect) + gpush(); + rvalue(lval); + gdec(lval); + store(lval); + return (0); + } + else if (match("-")) { + indflg = 0; + k = heir10(lval, comma); + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + gneg(); + return (0); + } + else if (match("~")) { + indflg = 0; + k = heir10(lval, comma); + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + gcom(); + return (0); + } + else if (match("!")) { + indflg = 0; + k = heir10(lval, comma); + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + gnot(); + return (0); + } + else if (ch() == '*' && nch() != '=') { + inbyte(); + indflg = 1; + k = heir10(lval, comma); + indflg = 0; + ptr = lval->symbol; + if (ptr && ptr->funcptr_type && lval->ptr_order == 0) { + /* ignore optional dereference of a function pointer */ + return (k); + } + if (k) + rvalue(lval); + if (lval->val_type == CVOID) + void_value_error(lval); + if (lval->ptr_order > 1) { + lval->indirect = CUINT; + lval->ptr_order--; + } else { + if (lval->ptr_type == 0) + error("not a pointer"); + lval->indirect = lval->ptr_type; + lval->ptr_type = 0; /* flag as not pointer or array */ + lval->ptr_order = 0; + } + return (1); + } + else if (ch() == '&' && nch() != '&' && nch() != '=') { + indflg = 0; + inbyte(); + k = heir10(lval, comma); + if (lval->val_type == CVOID) { + void_value_error(lval); + return (0); + } + if (k == 0) { + /* allow "&function" in function pointer assignment */ + if (lval->symbol == NULL || lval->symbol->identity != FUNCTION) + error("illegal address"); + return (0); + } + if (lval->symbol) { + ptr = lval->symbol; + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + } + lval->ptr_order++; + if (lval->indirect) + return (0); + + /* global and non-array */ + ptr = lval->symbol; + immed(T_SYMBOL, (intptr_t)ptr); + lval->indirect = ptr->sym_type; + return (0); + } + else { + k = heir11(lval, comma); + ptr = lval->symbol; + if (match("++")) { + if (k == 0) { + if (lval->val_type == CVOID) + void_value_error(lval); + else + needlval(); + return (0); + } + if (lval->indirect) + gpush(); + rvalue(lval); + ginc(lval); + store(lval); + gdec(lval); + return (0); + } + else if (match("--")) { + if (k == 0) { + if (lval->val_type == CVOID) + void_value_error(lval); + else + needlval(); + return (0); + } + if (lval->indirect) + gpush(); + rvalue(lval); + gdec(lval); + store(lval); + ginc(lval); + return (0); + } + else + return (k); + } +} + +/* + * array subscripting + * function calls + * structure members + * @param lval + * @return 0 or 1, fetch or no fetch + */ +int heir11 (LVALUE *lval, int comma) +{ + int direct, k; + SYMBOL *ptr; + bool deferred = false; + char sname[NAMESIZE]; + + k = primary(lval, comma, &deferred); + ptr = lval->symbol; + blanks(); + for (;;) { + if (match("[")) { + if (lval->val_type == CVOID) + void_value_error(lval); + if (ptr == 0) { + if (lval->ptr_type && lval->ptr_order == 1) { + /* subscription of anonymous array which is currently + only supported for a string literal, primarily for + the testsuite, such as "921218-1.c". */ + if (lval->ptr_type != ((user_signed_char) ? CCHAR : CUCHAR)) + error("internal error: cannot subscript non-character literals"); + /* Primary contains literal pointer, add subscript. */ + gpush(); + expression(YES); + needbracket("]"); + gadd(NULL, NULL); + /* Dereference final pointer. */ + lval->symbol = lval->symbol2 = 0; + lval->indirect = lval->ptr_type; + if (lval->ptr_order > 1) + lval->ptr_order--; + else { + lval->ptr_type = 0; + lval->ptr_order = 0; + } + k = 1; + continue; + } + else { + error("can't subscript"); + junk(); + needbracket("]"); + return (0); + } + } + else if (ptr->identity != POINTER && ptr->identity != ARRAY) { + error("can't subscript"); + k = 0; + } + if (k) + rvalue(lval); + if (!deferred && !ptr->far) + gpush(); + expression(YES); + needbracket("]"); + if (ptr->sym_type == CINT || ptr->sym_type == CUINT || + lval->ptr_order > ((ptr->identity == ARRAY) ? 0 : 1)) + gaslint(); + else if (ptr->sym_type == CSTRUCT) { + int size = tag_table[ptr->tagidx].size; + if (size == 2) + gaslint(); + else if (size > 1) + gmult_imm(size); + } + if (deferred) { +#if ULI_NORECURSE + if ((ptr->storage & STORAGE) == AUTO && norecurse && glint(ptr) < 0) { + /* XXX: bit of a memory leak, but whatever... */ + SYMBOL * locsym = copysym(ptr); + if (NAMEALLOC <= + sprintf(locsym->name, "_%s_end - %d", current_fn, -glint(ptr))) + error("norecurse local name too long"); + locsym->linked = ptr; + out_ins(I_ADD_WI, T_SYMBOL, (intptr_t)locsym); + } + else +#endif + if ((ptr->storage & STORAGE) == LSTATIC) + out_ins(I_ADD_WI, T_SYMBOL, (intptr_t)(ptr->linked)); + else + out_ins(I_ADD_WI, T_SYMBOL, (intptr_t)ptr); + deferred = false; + } + else + if (!ptr->far) + gadd(NULL, NULL); + if (lval->ptr_order > ((ptr->identity == ARRAY) ? 0 : 1)) { + lval->indirect = CUINT; + lval->ptr_order--; + } + else { + lval->indirect = lval->ptr_type; + lval->ptr_type = 0; + lval->ptr_order = 0; + blanks(); + if (ch() == '[') { + /* force an error in the next subscript attempt */ + lval->symbol = NULL; + } + } + lval->symbol2 = ptr->far ? ptr : NULL; + k = 1; + } + else if (match("(")) { + if (lval->val_type == CVOID) + void_value_error(lval); + if (ptr == 0) { + error("invalid or unsupported function call"); + junk(); + return (0); + } + else + if (ptr->identity == FUNCTION) { + callfunction(ptr); + if (ptr->ptr_order) { + lval->val_type = 0; + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + } else { + lval->val_type = ptr->sym_type; + lval->ptr_type = 0; + lval->ptr_order = 0; + } + if (ptr->sym_type == CSTRUCT) + lval->tagsym = &tag_table[ptr->tagidx]; + } + else { + if (ptr->funcptr_type == 0 || lval->ptr_order != 0) + error("not a function pointer"); + if (k) + rvalue(lval); + callfunction(ptr); + if (ptr->funcptr_order) { + lval->val_type = 0; + lval->ptr_type = ptr->funcptr_type; + lval->ptr_order = ptr->funcptr_order; + } else { + lval->val_type = ptr->funcptr_type; + lval->ptr_type = 0; + lval->ptr_order = 0; + } + if (ptr->funcptr_type == CSTRUCT) + lval->tagsym = &tag_table[ptr->tagidx]; + } + k = 0; + lval->symbol = 0; + } + else if ((direct = match(".")) || match("->")) { + if (lval->val_type == CVOID) + void_value_error(lval); + if (lval->tagsym == 0) { + error("can't take member"); + junk(); + return (0); + } + if (symname(sname) == 0 || + ((ptr = find_member(lval->tagsym, sname)) == 0)) { + error("unknown member"); + junk(); + return (0); + } + if (k && direct == 0) + rvalue(lval); + if (ptr->offset) + out_ins(I_ADD_WI, T_VALUE, ptr->offset); // move pointer from struct begin to struct member + lval->symbol = ptr; + lval->indirect = ptr->sym_type; // lval->indirect = lval->val_type = ptr->sym_type + lval->ptr_type = 0; + lval->ptr_order = 0; + lval->tagsym = NULL_TAG; + if (ptr->sym_type == CSTRUCT) + lval->tagsym = &tag_table[ptr->tagidx]; + if (ptr->identity == POINTER) { + lval->indirect = CUINT; + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + // lval->val_type = CINT; + } + if (ptr->identity == ARRAY || + (ptr->sym_type == CSTRUCT && ptr->identity == VARIABLE)) { + // array or struct + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + // lval->val_type = CINT; + k = 0; + } + else k = 1; + } + else + return (k); + } + if (ptr == 0) + return (k); + + if (ptr->identity == FUNCTION) { + immed(T_SYMBOL, (intptr_t)ptr); + return (0); + } + return (k); +} + +void store (LVALUE *lval) +{ + if (lval->symbol2) { + /* far arrays */ + error("const arrays can't be written"); + gpop(); + } + else { + /* other */ + if (lval->indirect != 0) { + if (lval->indirect == CVOID) + error("cannot dereference a VOID pointer"); + putstk(lval->indirect); + } + else { + if (lval->symbol) { + putmem(lval->symbol); + } + else { +// /* write to a memory addresses given as an immediate value */ +// out_ins(I_ST_WM, T_VALUE, lval->value); + error("cannot write to a string constant or literal value"); + } + } + } +} + +void rvalue (LVALUE *lval) +{ + if ((lval->symbol != 0) && (lval->indirect == 0)) { + getmem(lval->symbol); + } + else { + if (lval->symbol2 == 0) { + if (lval->indirect == CVOID) + error("cannot dereference a VOID pointer"); + indirect(lval->indirect); + } + else { + /* far arrays */ + farpeek(lval->symbol2); + } + } +} + +void needlval (void) +{ + error("must be lvalue"); +} diff --git a/src/hucc/expr.h b/src/hucc/expr.h new file mode 100644 index 00000000..1930d3ee --- /dev/null +++ b/src/hucc/expr.h @@ -0,0 +1,29 @@ +/* File expr.c: 2.2 (83/06/21,11:24:26) */ +/*% cc -O -c % + * + */ + +#ifndef _EXPR_H +#define _EXPR_H + +void expression (int comma); +int expression_ex (LVALUE *lval, int comma, int norval); +int heir1 (LVALUE *lval, int comma); +int heir1a (LVALUE *lval, int comma); +int heir1b (LVALUE *lval, int comma); +int heir1c (LVALUE *lval, int comma); +int heir2 (LVALUE *lval, int comma); +int heir3 (LVALUE *lval, int comma); +int heir4 (LVALUE *lval, int comma); +int heir5 (LVALUE *lval, int comma); +int heir6 (LVALUE *lval, int comma); +int heir7 (LVALUE *lval, int comma); +int heir8 (LVALUE *lval, int comma); +int heir9 (LVALUE *lval, int comma); +int heir10 (LVALUE *lval, int comma); +int heir11 (LVALUE *lval, int comma); +void store (LVALUE *lval); +void rvalue (LVALUE *lval); +void needlval (void); + +#endif diff --git a/src/hucc/fastcall.h b/src/hucc/fastcall.h new file mode 100644 index 00000000..5dd9b3a5 --- /dev/null +++ b/src/hucc/fastcall.h @@ -0,0 +1,10 @@ +/* defines */ +#define TYPE_BYTEACC 0x00 +#define TYPE_WORDACC 0x01 +#define TYPE_BYTE 0x02 +#define TYPE_WORD 0x03 +#define TYPE_FARPTR 0x04 +#define TYPE_DWORD 0x05 + +extern struct fastcall ftemp; +extern struct fastcall *fastcall_tbl[256]; diff --git a/src/hucc/function.c b/src/hucc/function.c new file mode 100644 index 00000000..8434cc90 --- /dev/null +++ b/src/hucc/function.c @@ -0,0 +1,1206 @@ +/* File function.c: 2.1 (83/03/20,16:02:04) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "error.h" +#include "expr.h" +#include "fastcall.h" +#include "function.h" +#include "gen.h" +#include "io.h" +#include "lex.h" +#include "optimize.h" +#include "pragma.h" +#include "primary.h" +#include "pseudo.h" +#include "stmt.h" +#include "sym.h" +#include "struct.h" + +/* locals */ +static INS ins_stack[1024]; +static int ins_stack_idx; +static int arg_list[32][2]; +static int arg_idx; +static int func_call_stack; + +/* globals */ +int arg_stack_flag; +int argtop; + +/* protos */ +void arg_flush (int arg, int adj); +void arg_to_fptr (struct fastcall *fast, int i, int arg, int adj); +void arg_to_dword (struct fastcall *fast, int i, int arg, int adj); + +/* function declaration styles */ +#define KR 0 +#define ANSI 1 + +/* argument address pointers for ANSI arguments */ +short *fixup[32]; +char current_fn[NAMESIZE]; + +static int is_leaf_function; + +/* + * begin a function + * + * called from "parse", this routine tries to make a function out + * of what follows + * modified version. p.l. woods + * + */ +void newfunc (const char *sname, int ret_ptr_order, int ret_type, int ret_otag, int is_fastcall) +{ + char n[NAMESIZE]; + SYMBOL *ptr; + int nbarg = 0; + int save_norecurse = norecurse; + struct fastcall *fc; + int hash; + int fc_args; + + is_leaf_function = 1; + + if (sname) { + /* At the opening parenthesis, declglb() found out that this + is a function declaration and called us. The function + name has therefore already been parsed. */ + strcpy(current_fn, sname); + strcpy(n, sname); + } + else { + /* The function name has not been parsed yet. This can happen + in two cases: + - No return type: We were called from parse(). + - fastcall: declglb() found the __fastcall attribute after + the type and called us. */ + if (is_fastcall) { + fc = &ftemp; + /* fc->nargs is the number of declared arguments; + fc_args is the number of arguments passed when + calling the function, which can be higher than + fc->nargs if types larger than 16 bits are used. */ + fc->nargs = 0; + fc_args = 0; + fc->flags = 0; + if (match("__xsafe")) + fc->flags |= FASTCALL_XSAFE; + if (match("__nop")) + fc->flags |= FASTCALL_NOP; + else + if (match("__macro")) + fc->flags |= FASTCALL_MACRO; + } + else { + /* No explicit return type. */ + ret_type = CINT; + } + if (!symname(n)) { + error("illegal function or declaration"); + kill(); + return; + } + strcpy(current_fn, n); + + if (!match("(")) + error("missing open paren"); + + if (is_fastcall) + strcpy(fc->fname, n); + } + + locsym_index = STARTLOC; + argstk = 0; + argtop = 0; + nbarg = 0; + memset(fixup, 0, sizeof(fixup)); + while (!match(")")) { + /* check if we have an ANSI argument */ + struct type_type t; + if (match_type(&t, NO, NO)) { + int ptr_order; + + if (t.type_type == CVOID) { + if (match(")")) + break; + } + + if (is_fastcall) { + if (match("__far") || match("far")) + fc->argtype[fc_args] = TYPE_FARPTR; + else { + if (t.type_type == CINT || t.type_type == CUINT) + fc->argtype[fc_args] = TYPE_WORD; + else + fc->argtype[fc_args] = TYPE_BYTE; + /* We'll change this to TYPE_WORD later + if it turns out to be a pointer. */ + } + } + + ptr_order = getarg(t.type_type, ANSI, t.otag, is_fastcall); + + if (is_fastcall) { + if (fc->argtype[fc_args] == TYPE_FARPTR) { + if (ptr_order < 1) { + error("far attribute to non-pointer type"); + return; + } + } + else if (ptr_order) + fc->argtype[fc_args] = TYPE_WORD; + + /* Parse the destination fastcall register + in angle brackets. */ + if (!match("<")) { + error("missing fastcall register"); + kill(); + return; + } + if (!symname(fc->argname[fc_args])) { + error("illegal fastcall register"); + kill(); + return; + } + if (fc->argtype[fc_args] == TYPE_FARPTR) { + /* We have the far pointer bank + register, expecting ":". */ + if (!match(":")) { + error("missing far pointer offset"); + kill(); + return; + } + + /* Far pointers are handled as two + arguments internally. */ + fc_args++; + if (fc_args >= MAX_FASTCALL_ARGS) { + error("too many fastcall arguments"); + kill(); + return; + } + + /* Far pointer offset register. */ + if (!symname(fc->argname[fc_args])) { + error("illegal far pointer offset register"); + return; + } + fc->argtype[fc_args] = TYPE_WORD; + } + if (!match(">")) { + error("missing closing angle bracket"); + return; + } + + if (!strcmp(fc->argname[fc_args], "acc")) + fc->argtype[fc_args] = + (fc->argtype[fc_args] == TYPE_BYTE) ? TYPE_BYTEACC : TYPE_WORDACC; + } + nbarg++; + if (is_fastcall) { + fc->nargs++; + fc_args++; + if (fc_args >= MAX_FASTCALL_ARGS) { + error("too many fastcall arguments"); + kill(); + return; + } + } + } + else { + if (is_fastcall) { + error("fastcall argument without type"); + kill(); + return; + } + /* no valid type, assuming K&R argument */ + if (symname(n)) { + if (findloc(n)) + multidef(n); + else { + addloc(n, 0, 0, argstk, AUTO, INTSIZE); + argstk = argstk + INTSIZE; + nbarg++; + } + } + else { + error("illegal argument name"); + junk(); + } + } + blanks(); + if (!streq(line + lptr, ")")) { + if (!match(",")) + error("expected comma"); + } + if (endst()) + break; + } + + for (;;) { + if (amatch("__norecurse", 14)) { + norecurse = 1; + continue; + } + else if (amatch("__recurse", 9)) { + norecurse = 0; + continue; + } + break; + } + + /* is this a declaration instead of a definition */ + if (match(";")) { + /* check if it was already registered by a declaration or previous usage */ + ptr = findglb(current_fn); + + /* check the argument count if it isn't a __fastcall which can have varying arguments */ + if (ptr && !is_fastcall) { + /* confirm arg_count, but do NOT check ret_type! */ + if (ptr->identity != FUNCTION) { + multidef(current_fn); + return; + } + else + if (ptr->arg_count >= 0 && ptr->arg_count != nbarg) { + error("function already declared with a different parameter count"); + return; + } + } + + /* overwrite the previous declaration, if there was one */ + ptr = addglb(current_fn, FUNCTION, ret_type, 0, EXTERN, ptr); + ptr->arg_count = nbarg; + norecurse = save_norecurse; + + if (is_fastcall) { + /* XXX: pragma code sets flag 0x02 if there are + memory arguments, but that's not used + anywhere... */ + + int i; + for (i = 0; i < fc_args - 1; i++) { + if (fc->argtype[i] == TYPE_WORDACC || fc->argtype[i] == TYPE_BYTEACC) { + error("fastcall accumulator argument must come last"); + kill(); + return; + } + } + + if (fastcall_look(n, fc->nargs, NULL)) { + error("fastcall already defined"); + return; + } + +// printf("Registered __fastcall %s with %d arguments.\n", n, fc->nargs); + + /* insert function into fastcall table */ + fc = (void *)malloc(sizeof(struct fastcall)); + if (!fc) { + error("out of memory"); + return; + } + *fc = ftemp; + hash = symhash(n); + fc->next = fastcall_tbl[hash]; + fastcall_tbl[hash] = fc; + } + + return; + } + else if (is_fastcall) { + error("__fastcall can only be used in prototypes"); + return; + } + + if (fastcall_look(n, nbarg, NULL)) { + error("functions declared as __fastcall cannot be implemented in C code"); + return; + } + + stkp = 0; + clabel_ptr = 0; + argtop = argstk; + while (argstk) { + /* We only know the final argument offset once we have parsed + all of them. That means that for ANSI arguments we have + to fix up the addresses for the locations generated in + getarg() here. */ + if (fixup[argstk / INTSIZE - 1]) { + argstk -= INTSIZE; + *fixup[argstk / INTSIZE] += argtop; + } + else { + /* expect K&R style argument definition */ + struct type_type t; + if (match_type(&t, NO, NO)) { + getarg(t.type_type, KR, t.otag, is_fastcall); + needsemicolon(); + } + else { + error("K&R argument definition missing"); + break; + } + } + } + + fexitlab = getlabel(); + + /* check if it was already registered by a declaration or previous usage */ + if ((ptr = findglb(current_fn))) { + if (ptr->identity != FUNCTION) + multidef(current_fn); + else if (ptr->offset == FUNCTION) + multidef(current_fn); + else + /* signal that the function has been defined and not just declared */ + ptr->offset = FUNCTION; + + if (ptr->arg_count >= 0 && ptr->arg_count != nbarg) + error("function already declared with a different parameter count"); + } else { + ptr = addglb(current_fn, FUNCTION, ret_type, FUNCTION, PUBLIC, 0); + } + ptr->arg_count = nbarg; + ptr->ptr_order = ret_ptr_order; + ptr->sym_type = ret_type; + ptr->tagidx = ret_otag; + + flush_ins(); /* David, .proc directive support */ + gtext(); + comment(); + outstr("*******\n\n"); + ol(".hucc"); + ot(".proc\t\t"); + prefix(); + outstr(current_fn); + nl(); + + /* generate the function prolog */ + out_ins(I_ENTER, T_SYMBOL, (intptr_t)ptr); + +#if ULI_NORECURSE + /* When using fixed-address locals, local_offset is used to + keep track of their memory offset instead of stkp, so + we have to reset it before producing code. */ + if (norecurse) + local_offset = 0; +#endif + + /* generate all the code for the function */ + statement(YES); + + /* generate the function epilog */ + gtext(); + gnlabel(fexitlab); + modstk(nbarg * INTSIZE); + if (ret_ptr_order == 0) { + if (ret_type == CCHAR) + out_ins(I_EXT_BR, 0, 0); + else + if (ret_type == CUCHAR) + out_ins(I_EXT_UR, 0, 0); + } + out_ins(I_RETURN, T_VALUE, ret_type != CVOID || ret_ptr_order != 0); /* generate the return statement */ + flush_ins(); /* David, optimize.c related */ + + ol(".endp"); /* David, .endp directive support */ + +#if ULI_NORECURSE + /* Add space for fixed-address locals to .bss section. */ + if (norecurse && local_offset < 0) { + if (is_leaf_function) { + leaf_functions = realloc(leaf_functions, (leaf_cnt + 1) * sizeof(*leaf_functions)); + leaf_functions[leaf_cnt++] = strdup(current_fn); + if (-local_offset > leaf_size) + leaf_size = -local_offset; + } + else { + ot(".data"); nl(); + ot(".bss"); nl(); + outstr("__"); outstr(current_fn); outstr("_loc:\n\t.ds\t\t"); + outdec(-local_offset); nl(); + outstr("__"); outstr(current_fn); outstr("_end:"); nl(); + ot(".code"); nl(); + } + } +#endif + + /* Signal that we're not in a function anymore. */ + fexitlab = 0; + + ol(".pceas"); + nl(); + stkp = 0; + locsym_index = STARTLOC; + norecurse = save_norecurse; +} + +/* + * declare argument types + * + * called from "newfunc", this routine add an entry in the local + * symbol table for each named argument + * completely rewritten version. p.l. woods + * + */ +int getarg (int t, int syntax, int otag, int is_fastcall) +{ + int j, legalname, address; + char n[NAMESIZE]; + SYMBOL *argptr; + int ptr_order = 0; + +/* char c; */ + + FOREVER { + if (syntax == KR && argstk == 0) + return (ptr_order); + + j = VARIABLE; + while (match("*")) { + j = POINTER; + ptr_order++; + } + + if (t == CSTRUCT && j != POINTER) + error("passing structures as arguments by value not implemented yet"); + + if (t == CVOID) { + if (j != POINTER) + error("illegal argument type \"void\""); + else + t = CUINT; + } + + if (!(legalname = symname(n))) { + if (syntax == ANSI && (ch() == ',' || ch() == ')')) + sprintf(n, "__anon_%d\n", (int) -argstk); + else { + illname(); + junk(); + } + } + if (match("[")) { + while (inbyte() != ']') + if (endst()) + break; + j = POINTER; + ptr_order++; + } + if (legalname) { + if (syntax == ANSI) { + if (findloc(n)) + multidef(n); + else { + addloc(n, 0, 0, argstk, AUTO, INTSIZE); + argstk = argstk + INTSIZE; + } + } + if ((argptr = findloc(n))) { + argptr->identity = j; + argptr->sym_type = t; + address = argtop - glint(argptr) - 2; + if ((t == CCHAR || t == CUCHAR) && j == VARIABLE) + address = address + BYTEOFF; + argptr->offset = address; + argptr->tagidx = otag; + argptr->ptr_order = ptr_order; + if (syntax == ANSI) + fixup[argstk / INTSIZE - 1] = &argptr->offset; + } + else + error("expecting argument name"); + } + if (syntax == KR) { + argstk = argstk - INTSIZE; + if (endst()) + return (ptr_order); + + if (!match(",")) + error("expected comma"); + } + else { + blanks(); + if (streq(line + lptr, ")") || + streq(line + lptr, ",") || + (is_fastcall && streq(line + lptr, "<")) + ) + return (ptr_order); + else + error("expected comma, closing bracket, or fastcall register"); + } + } + return (ptr_order); +} + +/* + * perform a function call + * + * called from "heir11", this routine will either call the named + * function, or if the supplied ptr is zero, will call the contents + * of HL + * + */ +#define SPILLB(a) { \ + spilled_args[sparg_idx] = (a); \ + spilled_arg_sizes[sparg_idx++] = 1; \ + out_ins(I_SPUSH_UR, 0, 0); \ +} + +#define SPILLW(a) { \ + spilled_args[sparg_idx] = (a); \ + spilled_arg_sizes[sparg_idx++] = 2; \ + out_ins(I_SPUSH_WR, 0, 0); \ +} + +void callfunction (SYMBOL *ptr) +{ + struct fastcall *fast = NULL; + int is_fc = 0; + int argcnt = 0; + int argsiz = 0; + int call_stack_ref; + int i, j; + int adj; + int max_fc_arg = 0; /* highest arg with a fastcall inside */ + /* args spilled to the native stack */ + const char *spilled_args[MAX_FASTCALL_ARGS]; + /* byte sizes of spilled args */ + int spilled_arg_sizes[MAX_FASTCALL_ARGS]; + int sparg_idx = 0; /* index into spilled_args[] */ + int uses_acc = 0; /* does callee use acc? */ + + is_leaf_function = 0; + + call_stack_ref = ++func_call_stack; + + /* skip blanks */ + blanks(); + + /* check if it's a special function, + * if yes handle it externaly + */ + if (!strcmp(ptr->name, "bank")) { + do_asm_func(T_BANK); return; + } + else + if (!strcmp(ptr->name, "vram")) { + do_asm_func(T_VRAM); return; + } + else + if (!strcmp(ptr->name, "pal")) { + do_asm_func(T_PAL); return; + } + +// flush_ins(); +// ot("__calling\n"); + + if (ptr->identity == FUNCTION) { + /* fastcall check, but don't know how many parameters */ + is_fc = fastcall_look(ptr->name, -1, NULL); + } else { +// /* save indirect call function-ptr on the hardware-stack */ +// out_ins(I_SPUSH_WR, 0, 0); + out_ins(I_FUNCP_WR, 0, 0); + } + + /* calling regular functions in fastcall arguments is OK */ + if (is_fc) + flush_ins(); + else + --func_call_stack; + + /* get args */ + while (!streq(line + lptr, ")")) { + if (endst()) + break; + /* fastcall func */ + if (is_fc) { + int nfc = func_call_stack; + + arg_stack(arg_idx++); + expression(NO); + flush_ins(); + stkp = stkp - INTSIZE; + + /* Check if we had a fastcall in our argument. */ + if (nfc < func_call_stack) { + /* Remember the last argument with an FC. */ + if (max_fc_arg < arg_idx - 1) + max_fc_arg = arg_idx - 1; + } + } + /* standard func */ + else { + expression(NO); + gpusharg(INTSIZE); + gfence(); + } + argsiz = argsiz + INTSIZE; + argcnt++; + if (!match(",")) + break; + } + + /* adjust arg stack */ + if (is_fc) { + if (argcnt) { + arg_list[arg_idx - 1][1] = ins_stack_idx; + arg_idx -= argcnt; + } + if (argcnt && arg_idx) + ins_stack_idx = arg_list[arg_idx - 1][1]; + else { + ins_stack_idx = 0; + arg_stack_flag = 0; + } + } + + /* fastcall func */ + if (is_fc) { + is_fc = fastcall_look(ptr->name, argcnt, &fast); + + /* flush arg instruction stacks */ + if (is_fc) { + /* fastcall */ + for (i = 0, j = 0, adj = 0; i < argcnt; i++) { + /* flush arg stack (except for farptr and dword args) */ + if ((fast->argtype[j] != TYPE_FARPTR) && + (fast->argtype[j] != TYPE_DWORD)) + arg_flush(arg_idx + i, adj); + + /* Either store the argument in its designated + location, or save it on the hardware-stack + if there is another fastcall ahead. */ + switch (fast->argtype[j]) { + case TYPE_BYTE: + if (i < max_fc_arg) + SPILLB(fast->argname[j]) + else { + out_ins(I_ST_UM, T_LITERAL, (intptr_t)fast->argname[j]); + gfence(); + } + break; + case TYPE_WORD: + if (i < max_fc_arg) + SPILLW(fast->argname[j]) + else { + out_ins(I_ST_WM, T_LITERAL, (intptr_t)fast->argname[j]); + gfence(); + } + break; + case TYPE_FARPTR: + arg_to_fptr(fast, j, arg_idx + i, adj); + if (i < max_fc_arg) { + out_ins(I_LD_UM, T_LITERAL, (intptr_t)fast->argname[j]); + SPILLB(fast->argname[j]) + out_ins(I_LD_WM, T_LITERAL, (intptr_t)fast->argname[j + 1]); + SPILLW(fast->argname[j + 1]) + } + j += 1; + break; + case TYPE_DWORD: + arg_to_dword(fast, j, arg_idx + i, adj); + if (i < max_fc_arg) { + out_ins(I_LD_WM, T_LITERAL, (intptr_t)fast->argname[j]); + SPILLW(fast->argname[j]) + out_ins(I_LD_WM, T_LITERAL, (intptr_t)fast->argname[j + 1]); + SPILLW(fast->argname[j + 1]) + out_ins(I_LD_WM, T_LITERAL, (intptr_t)fast->argname[j + 2]); + SPILLW(fast->argname[j + 2]) + } + j += 2; + break; + case TYPE_WORDACC: + if (i < max_fc_arg) + SPILLW(0) + uses_acc = 1; + break; + case TYPE_BYTEACC: + if (i < max_fc_arg) + SPILLW(0) + else + gshort(); + uses_acc = 1; + break; + default: + error("fastcall internal error"); + break; + } + + /* next */ + adj += INTSIZE; + j++; + } + } + else { + /* not really a fastcall after all! */ + for (i = 0; i < argcnt; i++) { + arg_flush(arg_idx + i, 0); + gpusharg(0); + gfence(); + } + error("__fastcall function was declared with a different parameter count"); + } + } + else + if (ptr->identity == FUNCTION || ptr->funcptr_type) { + /* check for function usage with differing numbers of parameters */ + if (ptr->arg_count < 0) { + /* function was automatically declared in primary() */ + ptr->arg_count = argcnt; + } + else + if (ptr->arg_count != argcnt) { + if (ptr->identity == FUNCTION) + error("function was declared with a different parameter count"); + else + error("function pointer was declared with a different parameter count"); + } + } + + /* reset func call stack */ + if (call_stack_ref == 1) + func_call_stack = 0; + + /* close */ + needbracket(")"); + + /* call function */ + /* Reload fastcall arguments spilled to the hardware-stack. */ + if (sparg_idx) { + /* Reloading corrupts acc, so we need to save it if it + is used by the callee. */ + if (uses_acc) { + out_ins(I_ST_WM, T_LITERAL, (intptr_t)"__temp"); + gfence(); + } + + for (i = sparg_idx - 1; i > -1; i--) { + if (spilled_arg_sizes[i] == 1) { + out_ins(I_SPOP_UR, 0, 0); + if (spilled_args[i]) { + out_ins(I_ST_UM, T_LITERAL, (intptr_t)spilled_args[i]); + gfence(); + } + } + else { + out_ins(I_SPOP_WR, 0, 0); + if (spilled_args[i]) { + out_ins(I_ST_WM, T_LITERAL, (intptr_t)spilled_args[i]); + gfence(); + } + } + } + + if (uses_acc) + out_ins(I_LD_WM, T_LITERAL, (intptr_t)"__temp"); + } + + if (ptr->identity == FUNCTION) { + if (fast && !(fast->flags & FASTCALL_XSAFE)) + out_ins(I_SAVESP, 0, 0); + if (fast && (fast->flags & (FASTCALL_NOP | FASTCALL_MACRO))) { + + // Only macro fastcalls get a name generated + if (fast->flags & FASTCALL_MACRO) { + if (is_fc) + gmacro(ptr->name, argcnt); + else + gmacro(ptr->name, 0); + } + } + // Else not a NOP or MACRO fastcall + else if (is_fc) + gcall(ptr->name, argcnt); + else + gcall(ptr->name, 0); + if (fast && !(fast->flags & FASTCALL_XSAFE)) + out_ins(I_LOADSP, 0, 0); + } else { +// /* restore indirect call function-ptr from the hardware-stack */ +// out_ins(I_SPOP_WR, 0, 0); + out_ins(I_CALLP, 0, 0); + } + +// flush_ins(); +// ot("__called\n"); + + /* adjust stack */ + if (argsiz) { + stkp = stkp + argsiz; + /* this is put into the instruction stream to balance the stack */ + /* calculations during the peephole optimization phase, but the */ + /* T_NOP stops the code-output from writing it to the .S file. */ + /* The function that is called is actually the one responsible */ + /* for removing the arguments from the stack. */ + out_ins(I_MODSP, T_NOP, argsiz); + } + + /* load acc.l if this a standard func returning a value */ + if (!is_fc) { + if (ptr->identity == FUNCTION) { + if (ptr->sym_type != CVOID || ptr->ptr_order != 0) + out_ins(I_GETACC, 0, 0); + } + else { + if (ptr->funcptr_type != CVOID || ptr->funcptr_order != 0) + out_ins(I_GETACC, 0, 0); + } + } +} + +/* + * start arg instruction stacking + * + */ +void arg_stack (int arg) +{ + if (arg > 31) + error("too many args"); + else { + /* close previous stack */ + if (arg) + arg_list[arg - 1][1] = ins_stack_idx; + + /* init new stack */ + ins_stack_idx += 4; + arg_list[arg][0] = ins_stack_idx; + arg_list[arg][1] = -1; + arg_stack_flag = 1; + } +} + +/* + * put instructions in a temporary stack (one for each func arg) + * + */ +void arg_push_ins (INS *ptr) +{ + if (ins_stack_idx < 1024) + ins_stack[ins_stack_idx++] = *ptr; + else { + if (ins_stack_idx < 1025) { + ins_stack_idx++; + error("arg stack full"); + } + } +} + +/* + * flush arg instruction stacks + * + */ +void arg_flush (int arg, int adj) +{ + INS *ins; + int idx; + int nb; + int i; + + if (arg > 31) + return; + + idx = arg_list[arg][0]; + nb = arg_list[arg][1] - arg_list[arg][0]; + + for (i = 0; i < nb;) { + /* adjust stack refs */ + i++; + ins = &ins_stack[idx]; + + if ((ins->ins_type == T_STACK) && (ins->ins_code == I_LD_WM)) { +printf("Can this ever occur?\n"); +abort(); + if (i < nb) { + ins = &ins_stack[idx + 1]; + if ((ins->ins_code == I_ADD_WI) && (ins->ins_type == T_VALUE)) + ins->ins_data -= adj; + } + } + else { + if (icode_flags[ins->ins_code] & IS_SPREL) + ins->ins_data -= adj; + } + + /* flush */ + gen_ins(&ins_stack[idx++]); + } +} + +/* + * convert a function argument into a farptr + * + */ +void arg_to_fptr (struct fastcall *fast, int i, int arg, int adj) +{ + INS *ins, tmp; + SYMBOL *sym; + int idx; + int err; + int nb; + + if (arg > 31) + return; + + idx = arg_list[arg][0]; + nb = arg_list[arg][1] - arg_list[arg][0]; + ins = &ins_stack[idx]; + err = 0; + + /* check arg */ + /* this code can be fooled, but it should catch most common errors */ + err = 1; + if (nb == 1) { + if (ins->ins_type == T_SYMBOL) { + /* allow either "function", "array", or "array+const" */ + sym = (SYMBOL *)ins->ins_data; + switch (sym->identity) { + case FUNCTION: + case ARRAY: + if (ins->ins_code == I_LD_WI) + err = 0; + break; + case POINTER: + if (ins->ins_code == I_LD_WM) + err = 0; + break; + } + } + } + else if (nb > 1) { + /* search the complex expression for the base symbol */ + for (idx = 0; idx < nb; ++idx, ++ins) { + if (ins->ins_type == T_SYMBOL) { + sym = (SYMBOL *)ins->ins_data; + switch (sym->identity) { + /* for the first "array", or "array+const" */ + case ARRAY: + if ((ins->ins_code == I_LD_WI) || + (ins->ins_code == I_ADD_WI)) + err = 0; + break; + /* or the first pointer */ + case POINTER: + if (ins->ins_code == I_LD_WM) + err = 0; + break; + } + } + /* break when a qualifying symbol is found */ + if (err == 0) break; + } + + /* check if last instruction is a pointer dereference */ + switch (ins_stack[ arg_list[arg][0] + nb - 1 ].ins_code) { + case I_LD_UP: + case I_LD_WP: + err = 1; + break; + default: + break; + } + } + + if (err) { + error("can't get farptr"); + return; + } + + /* ok */ + if (nb == 1) { + ins->ins_code = I_FARPTR; + ins->arg[0] = fast->argname[i]; + ins->arg[1] = fast->argname[i + 1]; + gen_ins(ins); + } + else { + sym = (SYMBOL *)ins->ins_data; + + /* check symbol type */ + if (sym->far) { + tmp.ins_code = I_FARPTR_I; + tmp.ins_type = T_SYMBOL; + tmp.ins_data = ins->ins_data; + tmp.arg[0] = fast->argname[i]; + tmp.arg[1] = fast->argname[i + 1]; + /* this nukes the symbol from the I_LD_WI or I_ADD_WI */ + ins->ins_type = T_VALUE; + ins->ins_data = 0; + } + else { + /* a pointer or an array of pointers */ + if (((sym->identity == ARRAY) || + (sym->identity == POINTER)) && + (sym->sym_type == CINT || sym->sym_type == CUINT)) { + tmp.ins_code = I_FARPTR_GET; + tmp.ins_type = 0; + tmp.ins_data = 0; + tmp.arg[0] = fast->argname[i]; + tmp.arg[1] = fast->argname[i + 1]; + } + else { + error("can't get farptr"); + return; + } + } + arg_flush(arg, adj); + gen_ins(&tmp); + } +} + +/* + * + */ +void arg_to_dword (struct fastcall *fast, int i, int arg, int adj) +{ + INS *ins, *ptr, tmp; + SYMBOL *sym; + int idx; + int gen; + int err; + int nb; + + if (arg > 31) + return; + + idx = arg_list[arg][0]; + nb = arg_list[arg][1] - arg_list[arg][0]; + ins = &ins_stack[idx]; + gen = 0; + err = 1; + + /* check arg */ + if (nb == 1) { + /* immediate value */ + if ((ins->ins_code == I_LD_WI) && (ins->ins_type == T_VALUE)) { + ins->ins_code = X_LDD_I; + ins->arg[0] = fast->argname[i + 1]; + ins->arg[1] = fast->argname[i + 2]; + gen = 1; + } + + /* var/ptr */ + else if ((((ins->ins_code == I_LD_WM) || (ins->ins_code == I_LD_BM) || (ins->ins_code == I_LD_UM)) + && (ins->ins_type == T_SYMBOL)) || (ins->ins_type == T_LABEL)) { + /* check special cases */ + if (ins->ins_type == T_LABEL) { + error("dword arg can't be a static var"); + return; + } + + /* get symbol */ + sym = (SYMBOL *)ins->ins_data; + + /* check type */ + if (sym->identity == POINTER) + gen = 1; + else if (sym->identity == VARIABLE) { + if (ins->ins_code == I_LD_WM) + ins->ins_code = X_LDD_W; + else + ins->ins_code = X_LDD_B; + + ins->ins_type = T_SYMBOL; + ins->ins_data = (intptr_t)sym; + ins->arg[0] = fast->argname[i + 1]; + ins->arg[1] = fast->argname[i + 2]; + gen = 1; + } + } + + /* var/ptr */ + else if ((ins->ins_code == X_LD_WS) || (ins->ins_code == X_LD_BS) || ins->ins_code == X_LD_US) { + /* get symbol */ + sym = ins->sym; + + /* check type */ + if (sym) { + if (sym->identity == POINTER) + gen = 1; + else if (sym->identity == VARIABLE) { + if (ins->ins_code == X_LD_WS) + ins->ins_code = X_LDD_S_W; + else + ins->ins_code = X_LDD_S_B; + + ins->ins_data -= adj; + ins->arg[0] = fast->argname[i + 1]; + ins->arg[1] = fast->argname[i + 2]; + gen = 1; + } + } + } + + /* array */ + else if (ins->ins_code == I_LEA_S) { + sym = ins->sym; + + if (sym && (sym->identity == ARRAY)) { + ins->ins_data -= adj; + gen = 1; + } + } + + /* array */ + else if ((ins->ins_code == I_LD_WI) && (ins->ins_type == T_SYMBOL)) { + /* get symbol */ + sym = (SYMBOL *)ins->ins_data; + + /* check type */ + if (sym->identity == ARRAY) + gen = 1; + } + } + else if (nb == 2) { + /* array */ + if ((ins->ins_code == I_LD_WI) && (ins->ins_type == T_SYMBOL)) { + /* get symbol */ + sym = (SYMBOL *)ins->ins_data; + + /* check type */ + if (sym->identity == ARRAY) { + ptr = ins; + ins = &ins_stack[idx + 1]; + + if ((ins->ins_code == I_ADD_WI) && (ins->ins_type == T_VALUE)) { + gen_ins(ptr); + gen = 1; + } + } + } + } + + /* gen code */ + if (gen) { + gen_ins(ins); + err = 0; + + if (strcmp(fast->argname[i], "#acc") != 0) { + tmp.ins_code = I_ST_WM; + tmp.ins_type = T_SYMBOL; + tmp.ins_data = (intptr_t)fast->argname[i]; + gen_ins(&tmp); + } + } + + /* errors */ + if (err) { + if (optimize < 1) + error("dword arg support works only with optimization enabled"); + else + error("invalid or too complex dword arg syntax"); + } +} diff --git a/src/hucc/function.h b/src/hucc/function.h new file mode 100644 index 00000000..bfa440ad --- /dev/null +++ b/src/hucc/function.h @@ -0,0 +1,18 @@ +/* File function.c: 2.1 (83/03/20,16:02:04) */ +/*% cc -O -c % + * + */ + +#ifndef _FUNCTION_H +#define _FUNCTION_H + +void newfunc (const char *sname, int ret_ptr_order, int ret_type, int ret_otag, int is_fastcall); +int getarg (int t, int syntax, int otag, int is_fastcall); +void callfunction (SYMBOL *ptr); +void arg_stack (int arg); +void arg_push_ins (INS *ptr); +void arg_flush (int arg, int adj); +void arg_to_fptr (struct fastcall *fast, int i, int arg, int adj); +void arg_to_dword (struct fastcall *fast, int i, int arg, int adj); + +#endif diff --git a/src/hucc/gen.c b/src/hucc/gen.c new file mode 100644 index 00000000..97d1ad50 --- /dev/null +++ b/src/hucc/gen.c @@ -0,0 +1,679 @@ +/* File gen.c: 2.1 (83/03/20,16:02:06) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "primary.h" +#include "sym.h" +#include "gen.h" +#include "expr.h" +#include "const.h" +#include "error.h" +#include "io.h" + +/* + * return next available internal label number + * + */ +int getlabel (void) +{ + return (nxtlab++); +} + +/* + * fetch a static memory cell into the primary register + */ +void getmem (SYMBOL *sym) +{ + char *data; + + if ((sym->identity != POINTER) && (sym->sym_type == CCHAR || sym->sym_type == CUCHAR)) { + int op = (sym->sym_type & CUNSIGNED) ? I_LD_UM : I_LD_BM; + if ((sym->storage & STORAGE) == LSTATIC) + out_ins(op, T_SYMBOL, (intptr_t)(sym->linked)); + else + out_ins(op, T_SYMBOL, (intptr_t)sym); + } + else { + if ((sym->storage & STORAGE) == LSTATIC) + out_ins(I_LD_WM, T_SYMBOL, (intptr_t)(sym->linked)); + else if ((sym->storage & STORAGE) == CONST && (data = get_const(sym))) + out_ins(I_LD_WI, T_LITERAL, (intptr_t)data); + else + out_ins(I_LD_WM, T_SYMBOL, (intptr_t)sym); + } +} + +/* + * fetch the address of the specified symbol into the primary register + * + */ +void getloc (SYMBOL *sym) +{ + int value; + + if ((sym->storage & STORAGE) == LSTATIC) + out_ins(I_LD_WI, T_SYMBOL, (intptr_t)(sym->linked)); + else { +#if ULI_NORECURSE + value = glint(sym); + if (norecurse && value < 0) { + /* XXX: bit of a memory leak, but whatever... */ + SYMBOL * locsym = copysym(sym); + if (NAMEALLOC <= + sprintf(locsym->name, "_%s_end - %d", current_fn, -value)) + error("norecurse local name too long"); + locsym->linked = sym; + out_ins(I_LD_WI, T_SYMBOL, (intptr_t)locsym); + } + else { + value -= stkp; + out_ins_sym(I_LEA_S, T_STACK, value, sym); + } +#else + value = glint(sym) - stkp; + out_ins_sym(I_LEA_S, T_STACK, value, sym); +#endif + } +} + +/* + * store the primary register into the specified static memory cell + * + */ +void putmem (SYMBOL *sym) +{ + int code; + + /* XXX: What about 1-byte structs? */ + if ((sym->identity != POINTER) & (sym->sym_type == CCHAR || sym->sym_type == CUCHAR)) + code = I_ST_UM; + else + code = I_ST_WM; + + if ((sym->storage & STORAGE) == LSTATIC) + out_ins(code, T_SYMBOL, (intptr_t)(sym->linked)); + else + out_ins(code, T_SYMBOL, (intptr_t)sym); +} + +/* + * store the specified object type in the primary register + * at the address on the top of the stack + * + */ +void putstk (char typeobj) +{ + if (typeobj == CCHAR || typeobj == CUCHAR) + out_ins(I_ST_UPT, 0, 0); + else + out_ins(I_ST_WPT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * fetch the specified object type indirect through the primary + * register into the primary register + * + */ +void indirect (char typeobj) +{ + out_ins(I_ST_WM, T_PTR, 0); + if (typeobj == CCHAR) + out_ins(I_LD_BP, T_PTR, 0); + else + if (typeobj == CUCHAR) + out_ins(I_LD_UP, T_PTR, 0); + else + out_ins(I_LD_WP, T_PTR, 0); +} + +void farpeek (SYMBOL *ptr) +{ + if (ptr->sym_type == CCHAR) + out_ins(I_FGETB, T_SYMBOL, (intptr_t)ptr); + else if (ptr->sym_type == CUCHAR) + out_ins(I_FGETUB, T_SYMBOL, (intptr_t)ptr); + else + out_ins(I_FGETW, T_SYMBOL, (intptr_t)ptr); +} + +/* + * print partial instruction to get an immediate value into + * the primary register + * + */ +void immed (int type, intptr_t data) +{ + if (type == T_VALUE && (data < -32768 || data > 65535)) + warning(W_GENERAL, "large integer truncated"); + if (type == T_SYMBOL) { + SYMBOL *sym = (SYMBOL *)data; + if ((sym->storage & STORAGE) == LSTATIC) + out_ins(I_LD_WI, T_SYMBOL, (intptr_t)(sym->linked)); + else + out_ins(I_LD_WI, T_SYMBOL, data); + } else { + out_ins(I_LD_WI, type, data); + } +} + +/* + * push the primary register onto the stack + * + */ +void gpush (void) +{ + out_ins(I_PUSH_WR, T_VALUE, INTSIZE); + stkp = stkp - INTSIZE; +} + +/* + * push the primary register onto the stack + * + */ +void gpusharg (int size) +{ + out_ins(I_PUSH_WR, T_SIZE, size); + stkp = stkp - size; +} + +/* + * pop the top of the stack into the secondary register + * + */ +void gpop (void) +{ + out_ins(I_POP_WR, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * call the specified subroutine name + * + */ +void gcall (char *sname, int nargs) +{ + out_ins_ex(I_CALL, T_LITERAL, (intptr_t)sname, T_VALUE, nargs); +} + +/* + * call the specified macro name + * + */ +void gmacro (char *sname, int nargs) +{ + out_ins_ex(I_MACRO, T_LITERAL, (intptr_t)sname, T_VALUE, nargs); +} + +/* + * jump to specified internal label number + * + */ +void jump (int label) +{ + out_ins(I_BRA, T_LABEL, label); +} + +/* + * test the primary register and jump if false to label + * + */ +void testjump (int label, int ft) +{ + out_ins(I_TST_WR, 0, 0); + if (ft) + out_ins(I_BTRUE, T_LABEL, label); + else + out_ins(I_BFALSE, T_LABEL, label); +} + +/* + * modify the stack pointer to the new value indicated + * Is it there that we decrease the value of the stack to add local vars ? + */ +int modstk (int newstkp) +{ + int k; + +// k = galign(newstkp - stkp); + k = newstkp - stkp; + if (k) { + gtext(); + out_ins(I_MODSP, T_STACK, k); + } + return (newstkp); +} + +/* + * multiply the primary register by INTSIZE + */ +void gaslint (void) +{ + out_ins(I_ASL_WR, 0, 0); +} + +/* + * divide the primary register by INTSIZE + */ +void gasrint (void) +{ + out_ins(I_ASR_WI, T_VALUE, 1); +} + +/* + * execute optimized "switch" library routine + */ +void gswitch (int nlab) +{ + out_ins(I_SWITCH_WR, T_LABEL, nlab); +} + +/* + * mark the start of a case or default statement + */ +void gcase (int nlab, int value) +{ + out_ins(I_ENDCASE, 0, 0); + gnlabel(nlab); + if (value == INT_MAX) + out_ins(I_CASE, 0, 0); + else + out_ins(I_CASE, T_VALUE, value); +} + +/* + * add the primary and secondary registers + * if lval2 is int pointer and lval is int, scale lval + */ +void gadd (LVALUE *lval, LVALUE *lval2) +{ + /* XXX: isn't this done in expr.c already? */ + /* Nope, it is used when calculating a pointer variable address into a word array */ + if (dbltest(lval2, lval)) + out_ins(I_DOUBLE, 0, 0); + out_ins(I_ADD_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * subtract the primary register from the secondary + * + */ +void gsub (void) +{ + out_ins(I_SUB_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * multiply the primary and secondary registers + * (result in primary) + * + */ +void gmult (int is_unsigned) +{ + /* the bottom 16-bits of a signed and unsigned 16-bit multiply are identical! */ + if (is_unsigned) + out_ins(I_MUL_WT, 0, 0); + else + out_ins(I_MUL_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +void gmult_imm (int value) +{ + out_ins(I_MUL_WI, T_VALUE, (intptr_t)value); +} + +/* + * divide the secondary register by the primary + * (quotient in primary, remainder in secondary) + * + */ +void gdiv (int is_unsigned) +{ + if (is_unsigned) + out_ins(I_UDIV_WT, 0, 0); + else + out_ins(I_SDIV_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +void gdiv_imm (int value) +{ + gpush(); + immed(T_VALUE, value); + gdiv(1); +} + +/* + * compute the remainder (mod) of the secondary register + * divided by the primary register + * (remainder in primary, quotient in secondary) + * + */ +void gmod (int is_unsigned) +{ + if (is_unsigned) + out_ins(I_UMOD_WT, 0, 0); + else + out_ins(I_SMOD_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * inclusive 'or' the primary and secondary registers + * + */ +void gor (void) +{ + out_ins(I_OR_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * exclusive 'or' the primary and secondary registers + * + */ +void gxor (void) +{ + out_ins(I_EOR_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * 'and' the primary and secondary registers + * + */ +void gand (void) +{ + out_ins(I_AND_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * arithmetic shift right the secondary register the number of + * times in the primary register + * (results in primary register) + * + */ +void gasr (int is_unsigned) +{ + if (is_unsigned) + out_ins(I_LSR_WT, 0, 0); + else + out_ins(I_ASR_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * arithmetic shift left the secondary register the number of + * times in the primary register + * (results in primary register) + * + */ +void gasl (void) +{ + out_ins(I_ASL_WT, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * two's complement of primary register + * + */ +void gneg (void) +{ + out_ins(I_NEG_WR, 0, 0); +} + +/* + * one's complement of primary register + * + */ +void gcom (void) +{ + out_ins(I_COM_WR, 0, 0); +} + +/* + * convert primary register into logical value + * + */ +void gbool (void) +{ + out_ins(I_BOOLEAN, 0, 0); +} + +/* + * boolean logical test of primary register + * + */ +void gtest (void) +{ + out_ins(I_TST_WR, 0, 0); +} + +/* + * boolean logical complement of primary register + * + */ +void gnot (void) +{ + out_ins(I_NOT_WR, 0, 0); + out_ins(I_BOOLEAN, 0, 0); +} + +/* + * increment the primary register by 1 if char, INTSIZE if int + */ +void ginc (LVALUE *lval) +{ + SYMBOL *sym = lval->symbol; + + if (lval->ptr_type == CINT || lval->ptr_type == CUINT || + (sym && (sym->ptr_order > 1 || (sym->identity == ARRAY && sym->ptr_order > 0)))) + out_ins(I_ADD_WI, T_VALUE, 2); + else if (lval->ptr_type == CSTRUCT) + out_ins(I_ADD_WI, T_VALUE, lval->tagsym->size); + else + out_ins(I_ADD_WI, T_VALUE, 1); +} + +/* + * decrement the primary register by one if char, INTSIZE if int + */ +void gdec (LVALUE *lval) +{ + SYMBOL *sym = lval->symbol; + + if (lval->ptr_type == CINT || lval->ptr_type == CUINT || + (sym && (sym->ptr_order > 1 || (sym->identity == ARRAY && sym->ptr_order > 0)))) + out_ins(I_SUB_WI, T_VALUE, 2); + else if (lval->ptr_type == CSTRUCT) + out_ins(I_SUB_WI, T_VALUE, lval->tagsym->size); + else + out_ins(I_SUB_WI, T_VALUE, 1); +} + +/* + * following are the conditional operators. + * they compare the secondary register against the primary register + * and put a literl 1 in the primary if the condition is true, + * otherwise they clear the primary register + * + */ + +/* + * equal + * + */ + +void geq (void) +{ + out_ins_cmp(I_CMP_WT, CMP_EQU); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * not equal + * + */ +void gne (void) +{ + out_ins_cmp(I_CMP_WT, CMP_NEQ); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * less than (signed) + * + */ +void glt (void) +{ + out_ins_cmp(I_CMP_WT, CMP_SLT); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * less than or equal (signed) + * + */ +void gle (void) +{ + out_ins_cmp(I_CMP_WT, CMP_SLE); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * greater than (signed) + * + */ +void ggt (void) +{ + out_ins_cmp(I_CMP_WT, CMP_SGT); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * greater than or equal (signed) + * + */ +void gge (void) +{ + out_ins_cmp(I_CMP_WT, CMP_SGE); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * less than (unsigned) + * + */ +void gult (void) +{ + out_ins_cmp(I_CMP_WT, CMP_ULT); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * less than or equal (unsigned) + * + */ +void gule (void) +{ + out_ins_cmp(I_CMP_WT, CMP_ULE); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * greater than (unsigned) + * + */ +void gugt (void) +{ + out_ins_cmp(I_CMP_WT, CMP_UGT); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +/* + * greater than or equal (unsigned) + * + */ +void guge (void) +{ + out_ins_cmp(I_CMP_WT, CMP_UGE); + out_ins(I_BOOLEAN, 0, 0); + stkp = stkp + INTSIZE; +} + +void scale_const (int type, int otag, int *size) +{ + switch (type) { + case CINT: + case CUINT: + *size += *size; + break; + case CSTRUCT: + *size *= tag_table[otag].size; + break; + default: + break; + } +} + +void gcast (int type) +{ + switch (type) { + case CCHAR: + out_ins(I_EXT_BR, 0, 0); + break; + case CUCHAR: + out_ins(I_EXT_UR, 0, 0); + break; + case CINT: + case CUINT: + case CVOID: + break; + default: + abort(); + } + ; +} + +void gsei (void) +{ + out_ins(I_SEI, 0, 0); +} +void gcli (void) +{ + out_ins(I_CLI, 0, 0); +} +void gfence (void) +{ + out_ins(I_FENCE, 0, 0); +} +void gshort (void) +{ + out_ins(I_SHORT, 0, 0); +} diff --git a/src/hucc/gen.h b/src/hucc/gen.h new file mode 100644 index 00000000..2a1ecaff --- /dev/null +++ b/src/hucc/gen.h @@ -0,0 +1,61 @@ +#ifndef _GEN_H +#define _GEN_H + +int getlabel (void); +void getmem (SYMBOL *sym); +void getloc (SYMBOL *sym); +void putmem (SYMBOL *sym); +void putstk (char typeobj); +void indirect (char typeobj); +void farpeek (SYMBOL *ptr); +void immed (int type, intptr_t data); +void gpush (void); +void gpusharg (int size); +void gpop (void); +void gcall (char *sname, int nargs); +void gmacro (char *sname, int nargs); +void jump (int label); +void testjump (int label, int ft); +int modstk (int newstkp); +void gaslint (void); +void gasrint (void); +void gswitch (int nlab); +void gcase (int nlab, int value); +void gadd (LVALUE *lval, LVALUE *lval2); +void gsub (void); +void gmult (int is_unsigned); +void gmult_imm (int value); +void gdiv (int is_unsigned); +void gdiv_imm (int value); +void gmod (int is_unsigned); +void gor (void); +void gxor (void); +void gand (void); +void gasr (int is_unsigned); +void gasl (void); +void gneg (void); +void gcom (void); +void gbool (void); +void gtest (void); +void gnot (void); +void ginc (LVALUE *lval); +void gdec (LVALUE *lval); +void geq (void); +void gne (void); +void glt (void); +void gle (void); +void ggt (void); +void gge (void); +void gult (void); +void gule (void); +void gugt (void); +void guge (void); +void gcast (int type); +void gsei (void); +void gcli (void); +void gfence (void); +void gshort (void); + +void scale_const (int type, int otag, int *size); + +#endif diff --git a/src/hucc/initials.c b/src/hucc/initials.c new file mode 100644 index 00000000..6a0df4de --- /dev/null +++ b/src/hucc/initials.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "error.h" +#include "lex.h" + +/** + * erase the data storage + */ +void create_initials() { + /*int i; + for (i=0; i= NUMGLBS) + error("initials table overrun"); + if (astreq(symbol_name, initials_table[initials_idx].name, NAMEMAX) != 0) { + result = 1; + break; + } + else { + // move to next symbol + // count position in data array + initials_data_idx += initials_table[initials_idx].data_len; + } + } + return (result); +} + +/** + * add data to table for given symbol + * @param symbol_name + * @param type + * @param value + * @param tag + */ +void add_data_initials (char *symbol_name, int type, int value, TAG_SYMBOL *tag) +{ + int position; + + if (find_symbol_initials(symbol_name) == 0) + add_symbol_initials(symbol_name, tag == 0 ? type : CSTRUCT); + if (tag != 0) { + // find number of members, dim is total number of values added + int index = initials_table[initials_idx].dim % tag->number_of_members; + int member_type = member_table[tag->member_idx + index].sym_type; + // add it recursively + add_data_initials(symbol_name, member_type, value, 0); + } + else { + position = initials_table[initials_idx].data_len; + if (type == CCHAR || type == CUCHAR) { + initials_data_table[initials_data_idx + position] = 0xff & value; + initials_table[initials_idx].data_len += 1; + } + else { + initials_data_table[initials_data_idx + position] = (0xff00 & value) >> 8; + initials_data_table[initials_data_idx + position + 1] = 0xff & value; + initials_table[initials_idx].data_len += INTSIZE; + } + initials_table[initials_idx].dim += 1; + } +} + +/** + * get number of data items for given symbol + * @param symbol_name + * @return + */ +int get_size (char *symbol_name) +{ + int result = 0; + + if (find_symbol_initials(symbol_name) != 0) + result = initials_table[initials_idx].dim; + return (result); +} + +/** + * get item at position + * @param symbol_name + * @param position + * @param itag index of tag in tag table + * @return + */ +int get_item_at (char *symbol_name, int position, TAG_SYMBOL *tag) +{ + int result = 0, i, type; + + if (find_symbol_initials(symbol_name) != 0) { + if ((initials_table[initials_idx].init_type & ~CUNSIGNED) == CCHAR) + result = initials_data_table[initials_data_idx + position]; + else if ((initials_table[initials_idx].init_type & ~CUNSIGNED) == CINT) { + position *= INTSIZE; + result = (initials_data_table[initials_data_idx + position] << 8) + + (unsigned char)initials_data_table[initials_data_idx + position + 1]; + } + else if (initials_table[initials_idx].init_type == CSTRUCT) { + // find number of members + int number_of_members = tag->number_of_members; + // point behind the last full struct + int index = (position / number_of_members) * tag->size; + // move to required member + for (i = 0; i < (position % number_of_members); i++) { + type = member_table[tag->member_idx + i].sym_type; + if (type == CCHAR || type == CUCHAR) + index += 1; + else + index += INTSIZE; + } + // get value + type = member_table[tag->member_idx + i].sym_type; + if (type == CCHAR || type == CUCHAR) + result = initials_data_table[initials_data_idx + index]; + else { + result = (initials_data_table[initials_data_idx + index] << 8) + + (unsigned char)initials_data_table[initials_data_idx + index + 1]; + } + } + } + return (result); +} diff --git a/src/hucc/initials.h b/src/hucc/initials.h new file mode 100644 index 00000000..810dff18 --- /dev/null +++ b/src/hucc/initials.h @@ -0,0 +1,5 @@ +#include "defs.h" +void add_data_initials (char *symbol_name, int type, int value, TAG_SYMBOL *tag); +int get_item_at (char *symbol_name, int position, TAG_SYMBOL *tag); +int get_size (char *symbol_name); +int find_symbol_initials (char *symbol_name); diff --git a/src/hucc/io.c b/src/hucc/io.c new file mode 100644 index 00000000..d9707c0b --- /dev/null +++ b/src/hucc/io.c @@ -0,0 +1,648 @@ +/* File io.c: 2.1 (83/03/20,16:02:07) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "io.h" +#include "optimize.h" +#include "preproc.h" +#include "main.h" +#include "code.h" +#include "sym.h" + +/* + * open input file + * Input : char* p + * Output : int error code + * + * Try to open the file whose filename is p, return YES if opened, else NO + * Updates fname with the actual opened name + * input is the handle of the opened file + * + */ +int openin (char *p) +{ + strcpy(fname, p); + strcpy(fname_copy, fname); + fixname(fname); + if (!checkname(fname)) { + fprintf(stderr, "%s: unknown file type\n", fname); + return (NO); + } + if ((input = fopen(fname, "r")) == NULL) { + perror(fname); + return (NO); + } + kill(); + return (YES); +} + +/* + * open output file + * Input : nothing but uses global fname + * Output : nothing but fname contain the name of the out file now + * + * Guess the name of the outfile thanks to the input one and try to open it + * In case of succes returns YES and output is the handle of the opened file + * else returns NO + * + */ +int openout (void) +{ + if (user_outfile[0]) + output = fopen(user_outfile, "w"); + else { + outfname(fname); + output = fopen(fname, "w"); + } + if (output == NULL) { + pl("Open failure : "); + if (user_outfile[0]) + pl(user_outfile); + else + pl(fname); + pl("\n"); + return (NO); + } + kill(); + return (YES); +} + +/* + * change input filename to output filename + * Input : char* s + * Output : char* s is updated + * + * Simply replace the last letter of s by 's' + * Used to return "file.s" from "file.c" + * + */ +void outfname (char *s) +{ + while (*s) + s++; + *--s = 's'; +} + +/* + * remove NL from filenames + * Input : char* s + * Output : char* s is updated + * + * if any, remove the trailing newline char from the s string + * + */ +void fixname (char *s) +{ + while (*s && *s++ != EOL) ; + if (!*s) return; + + *(--s) = 0; +} + +/* + * check that filename is "*.c" + * Input : char* s + * Output : int + * + * verify that the 2 last letter of s are ".c", returns YES in this case, + * else NO + * + */ +int checkname (char *s) +{ + while (*s) + s++; + if (*--s != 'c' && *s != 'C') + return (NO); + + if (*--s != '.') + return (NO); + + return (YES); +} + +/* + * kill + * Input : nothing + * Output : nothing but updates lptr and line[lptr] + * + * lptr and line[lptr] are set to zero what appears to clear the current + * input line + * + */ +void kill (void) +{ + lptr = 0; + line[lptr] = 0; +} + +/* + * unget_line + * Input : # of characters to kill preceding what we see in line[lptr] + * Output : nothing + * + * This function looks at line and lptr variables with a line of text + * and moves the file pointer back as though the line was never read + * then kills line/lptr + * + * Only use this function for operations at the top level (ie. the + * file pointer 'fp') + * + */ +void unget_line (void) +{ + int i; + + i = (int)strlen(line); + if (i > 0) { + fseek(input, 0 - i - CR_LEN, SEEK_CUR); + line_number--; + } + + kill(); +} + + +/* + * readline + * Input : nothing + * Output : nothing + * + * This function seems to fill line and lptr variables with a line of text + * coming either form an included file or the main one + * + */ +void readline (void) +{ + int k; + FILE *unit; + + FOREVER { + if (!input || feof(input)) + return; + + if ((unit = input2) == NULL) + unit = input; + kill(); + while ((k = fgetc(unit)) != EOF) { + if ((k == '\r') | (k == EOL) | (lptr >= LINEMAX)) + break; + line[lptr++] = k; + } + line_number++; + line[lptr] = 0; + if (k <= 0) + if (input2 != NULL) { + if (globals_h_in_process) { + /* Add special treatment to ensure globals.h stuff appears at the beginning */ + gdata(); + outstr("huc_globals:\n"); + dumpglbs(); + outstr("huc_globals_end:\n"); + gtext(); + globals_h_in_process = 0; + } + input2 = inclstk[--inclsp]; + line_number = inclstk_line[inclsp]; + fclose(unit); + } + if (lptr) { + if ((ctext) & (cmode)) { + flush_ins(); + comment(); + tab(); + tab(); + tab(); + tab(); + tab(); + tab(); + outstr(line); + nl(); + } + lptr = 0; + return; + } + } +} + +/* + * inbyte + * Input : nothing + * Output : int, (actualy char) + * + * Uses the preprocessor as much as possible to get readable data + * then read the next char and make lptr points to the next one + * + */ +int inbyte (void) +{ + while (ch() == 0) { + if (feof(input)) + return (0); + + preprocess(); + } + return (gch()); +} + +/* + * inchar + * Input : nothing + * Output : int, (actualy char) + * + * Returns the current char, making lptr points to the next one + * If the buffer if empty, fill it with next line from input + * + */ +int inchar (void) +{ + if (ch() == 0) + readline(); + if (feof(input)) + return (0); + + return (gch()); +} + +/* + * gch + * Input : nothing + * Output : int, (actualy char) + * + * If the pointed char (by line and lptr) is 0, return this value + * else return the current pointed char and advance the lptr to point + * on the following char + * + */ +int gch (void) +{ + if (ch() == 0) + return (0); + else + return (line[lptr++] & 127); +} + +/* + * nch + * Input : nothing + * Output : int, (actualy char) + * + * If called when the pointed char is at the end of the line, return 0 + * else return the following char + * Doesn't change line nor lptr variable + * + */ +int nch (void) +{ + if (ch() == 0) + return (0); + else + return (line[lptr + 1] & 127); +} + +/* + * ch + * + * Input : nothing but use global line and lptr variables + * Output : int, (actually char), corresponding to the current pointed char + * during the parsing + * + * Appears to be the major function used during the parsing. + * The global variables line and lptr aren't changed + * + */ +int ch (void) +{ + return (line[lptr] & 127); +} + +/* + * print a carriage return and a string only to console + * + */ +void pl (char *str) +/*char *str; */ +{ + int k; + + k = 0; + putchar(EOL); + while (str[k]) + putchar(str[k++]); +} + +/* + * glabel - generate label + */ +void glabel (char *lab) +/*char *lab;*/ +{ + flush_ins(); /* David - optimize.c related */ + prefix(); + outstr(lab); + col(); + nl(); +} + +/* + * gnlabel - generate numeric label + */ +void gnlabel (int nlab) +{ + out_ins(I_LABEL, T_VALUE, nlab); +} + +/* + * Output internal generated label prefix + */ +void olprfix (void) +{ + outstr("LL"); +} + +/* + * Output a label definition terminator + */ +void col (void) +{ + outstr(":\n"); +} + +/* + * begin a comment line for the assembler + * + */ +void comment (void) +{ + outbyte(';'); +} + +/* + * Output a prefix in front of user labels + */ +void prefix (void) +{ + outbyte('_'); +} + +/* + * tab + * Input : nothing + * Output : nothing + * + * Write a tab charater in the assembler file + * + */ +void tab (void) +{ + outbyte(9); +} + +/* + * ol + * Input : char* ptr + * Output : nothing + * + * Writes the string ptr to the assembler file, preceded by a tab, ended by + * a newline + * + */ +void ol (char *ptr) +/*char ptr[]; */ +{ + ot(ptr); + nl(); +} + +/* + * ot + * Input : char* ptr + * Output : nothing + * + * Writes the string ptr to the assembler file, preceded by a tab + * + */ +void ot (char *ptr) +/*char ptr[]; */ +{ + tab(); + outstr(ptr); +} + +/* + * nl + * Input : nothing + * Output : nothing + * + * Display a newline in the assembler file + * + */ +void nl (void) +{ + outbyte(EOL); +} + +/* + * outsymbol + * Input : char* ptr + * Output : nothing + * + * Writes the string ptr preceded with the result of the function prefix + * + */ +void outsymbol (SYMBOL *ptr) +{ + if ((ptr->storage & STORAGE) == LSTATIC) { + outstr(ptr->name); + } else { + prefix(); + outstr(ptr->name); + } + if (ptr->linked) { + outstr(" /* "); + outstr(ptr->linked->name); + outstr(" */"); + } +} + +/* + * print specified number as label + */ +void outconst (int label) +{ + outstr("__const"); + outdec(label); +} + +/* + * print specified number as label + */ +void outlabel (int label) +{ + olprfix(); + outdec(label); +} + +/* + * Output a decimal number to the assembler file + */ +/* + void outdec (int number) + { + int k, zs; + char c; + + if (number == -32768) { + outstr ("-32768"); + return; + } + zs = 0; + k = 10000; + if (number < 0) { + number = (-number); + outbyte ('-'); + } + while (k >= 1) { + c = number / k + '0'; + if ((c != '0' | (k == 1) | zs)) { + zs = 1; + outbyte (c); + } + number = number % k; + k = k / 10; + } + } + */ + +/* Newer version, shorter and certainly faster */ +void outdec (int number) +{ + char s[16]; + int i = 0; + + sprintf(s, "%d", number); + + while (s[i]) + outbyte(s[i++]); +} + +/* + * Output an hexadecimal unsigned number to the assembler file + */ + +/* + void outhex (int number) + { + int k, zs; + char c; + + zs = 0; + k = 0x10000000; + + outbyte('$'); + + while (k >= 1) { + c = number / k; + if (c <= 9) + c += '0'; + else + c += 'A' - 10; + + outbyte (c); + + number = number % k; + k = k / 16; + } + } + */ + +/* Newer version, shorter and certainly faster */ +void outhex (int number) +{ + int i = 0; + char s[10]; + + outbyte('$'); + + sprintf(s, "%0X", (int)number); + + while (s[i]) + outbyte(s[i++]); +} + +/* + * Output an hexadecimal number with a certain number of digits + */ +void outhexfix (int number, int length) +{ + int i = 0; + char s[10]; + char format[10]; + + outbyte('$'); + + sprintf(format, "%%0%dX", (int)length); + + sprintf(s, format, number); + + while (s[i]) + outbyte(s[i++]); +} + + +/* + * outbyte + * Input : char c + * Output : same as input, c + * + * if c is different of zero, write it to the output file + * + */ +char outbyte (char c) +{ + if (c == 0) + return (0); + + fputc(c, output); + return (c); +} + +/* + * outstr + * Input : char*, ptr + * Output : nothing + * + * Send the input char* to the assembler file + * + */ +void outstr (const char *ptr) +{ + int k; + + k = 0; + while (outbyte(ptr[k++])) ; +} + +/* + * outlocal + * Input : char* ptr + * Output : nothing + * + * Writes the variable name as a comment + * + */ +void outlocal (SYMBOL *ptr) +{ + if (ptr) { + outstr(" /* "); + outstr(ptr->name); + outstr(" */"); + } +} diff --git a/src/hucc/io.h b/src/hucc/io.h new file mode 100644 index 00000000..a4695698 --- /dev/null +++ b/src/hucc/io.h @@ -0,0 +1,58 @@ +/* File io.h: 2.1 (83/03/20,16:02:07) */ +/*% cc -O -c % + * + */ + +#ifndef _IO_H +#define _IO_H + +#if defined(WIN32) +#define CR_LEN 2 +#else +#define CR_LEN 1 +#endif + + +int openin (char *p); +int openout (void); +void outfname (char *s); +void fixname (char *s); +int checkname (char *s); +#if defined(__APPLE__) || defined(__CYGWIN__) +void _kill (void); +#define kill _kill +#else +void kill (void); +#endif +void unget_line (void); +void readline (void); + +/* could otherwise be char */ +int inbyte (void); +int inchar (void); +int gch (void); +int nch (void); +int ch (void); + +void pl (char *str); +void glabel (char *lab); +void gnlabel (int nlab); +void olprfix (void); +void col (void); +void comment (void); +void prefix (void); +void tab (void); +void ol (char *ptr); +void ot (char *ptr); +void nl (void); +void outlocal (SYMBOL *ptr); +void outsymbol (SYMBOL *ptr); +void outconst (int label); +void outlabel (int label); +void outdec (int number); +void outhex (int number); +void outhexfix (int number, int length); +char outbyte (char c); +void outstr (const char *ptr); + +#endif diff --git a/src/hucc/lex.c b/src/hucc/lex.c new file mode 100644 index 00000000..c3c7118e --- /dev/null +++ b/src/hucc/lex.c @@ -0,0 +1,176 @@ +/* File lex.c: 2.1 (83/03/20,16:02:09) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "error.h" +#include "io.h" +#include "lex.h" +#include "preproc.h" + +/* + * semicolon enforcer + * + * called whenever syntax requires a semicolon + * + */ +void needsemicolon (void) +{ + if (!match(";")) + error("missing semicolon"); +} + +void junk (void) +{ + if (alphanum(inbyte())) + while (alphanum(ch())) + gch(); + else + while (alphanum(ch())) { + if (ch() == 0) + break; + gch(); + } + blanks(); +} + +int endst (void) +{ + blanks(); + return ((streq(line + lptr, ";") | (ch() == 0))); +} + +void needbracket (const char *str) +{ + if (!match(str)) { + error("missing bracket"); + comment(); + outstr(str); + nl(); + } +} + +/* + * test if given character is alpha + * + */ +int alpha (char c) +{ + c = c & 127; + return (((c >= 'a') && (c <= 'z')) | + ((c >= 'A') && (c <= 'Z')) | + (c == '_')); +} + +/* + * test if given character is numeric + * + */ +int numeric (char c) +{ + c = c & 127; + return ((c >= '0') && (c <= '9')); +} + +/* + * test if given character is alphanumeric + * + */ +int alphanum (char c) +{ + return ((alpha(c)) | (numeric(c))); +} + +int sstreq (const char *str1) +{ + return (streq(line + lptr, str1)); +} + +int streq (const char *str1, const char *str2) +{ + int k; + + k = 0; + while (str2[k]) { + if ((str1[k] != str2[k])) + return (0); + + k++; + } + return (k); +} + +int astreq (const char *str1, const char *str2, int len) +{ + int k; + + k = 0; + while (k < len) { + if ((str1[k] != str2[k])) + break; + if (str1[k] == 0) + break; + if (str2[k] == 0) + break; + k++; + } + if (alphanum(str1[k])) + return (0); + + if (alphanum(str2[k])) + return (0); + + return (k); +} + +int match (const char *lit) +{ + int k; + + blanks(); + k = streq(line + lptr, lit); + if (k) { + lptr = lptr + k; + return (1); + } + return (0); +} + +int amatch (const char *lit, int len) +{ + int k; + + blanks(); + k = astreq(line + lptr, lit, len); + if (k) { + lptr = lptr + k; + while (alphanum(ch())) + inbyte(); + return (1); + } + return (0); +} + +int lex_stop_at_eol = 0; + +void blanks (void) +{ + FOREVER { + while (ch() == 0 && !lex_stop_at_eol) { + preprocess(); + if (!input || feof(input)) + break; + } + if (ch() == ' ') + gch(); + else if (ch() == 9) + gch(); + else + return; + } +} diff --git a/src/hucc/lex.h b/src/hucc/lex.h new file mode 100644 index 00000000..9ba26089 --- /dev/null +++ b/src/hucc/lex.h @@ -0,0 +1,32 @@ +#ifndef _INCLUDE_LEX_H +#define _INCLUDE_LEX_H + +void needsemicolon (void); + +void junk (void); + +int endst (void); + +void needbracket (const char *str); + +int alpha (char c); + +int numeric (char c); + +int alphanum (char c); + +int sstreq (const char *str1); + +int streq (const char *str1, const char *str2); + +int astreq (const char *str1, const char *str2, int len); + +int match (const char *lit); + +int amatch (const char *lit, int len); + +void blanks (void); + +extern int lex_stop_at_eol; + +#endif diff --git a/src/hucc/main.c b/src/hucc/main.c new file mode 100644 index 00000000..cc89b31a --- /dev/null +++ b/src/hucc/main.c @@ -0,0 +1,1177 @@ +/* File main.c: 2.7 (84/11/28,10:14:56) + * + * PC Engine C Compiler + * based on Small-C Compiler by Ron Cain, James E. Hendrix, and others + * hacked to work on PC Engine by David Michel + * work resumed by Zeograd + * work resumed again by Ulrich Hecht + * work resumed again by John Brandwood + * + * 00/02/22 : added oldargv variable to show real exe name in usage function + */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "const.h" +#include "enum.h" +#include "error.h" +#include "function.h" +#include "gen.h" +#include "initials.h" +#include "io.h" +#include "lex.h" +#include "main.h" +#include "optimize.h" +#include "pragma.h" +#include "preproc.h" +#include "primary.h" +#include "pseudo.h" +#include "sym.h" +#include "struct.h" + +static char **link_libs = 0; +static int link_lib_ptr; +static char **infiles = 0; +static int infile_ptr; + +static int user_norecurse = 0; + +#if 0 +#if !((__STDC_VERSION__ >= 201112L) || (_MSC_VER >= 1910)) +# if !defined(HAVE_STRCAT_S) +static int strcat_s(char* dst, size_t len, const char* src) { + size_t i; + if (!dst || !len) { + return EINVAL; + } + if (src) { + for (i = 0; i < len; i++) { + if (dst[i] == '\0') { + size_t j; + for (j = 0; (i+j) < len; j++) { + if ((dst[i+j] = src[j]) == '\0') { + return 0; + } + } + } + } + } + dst[0] = '\0'; + return EINVAL; +} +# endif // !HAVE_STRCAT_S + +# if !defined(HAVE_STRCPY_S) +static int strcpy_s(char* dst, size_t len, const char* src) { + if (!dst || !len) { + return EINVAL; + } + if (src) { + size_t i; + for (i = 0; i < len; i++) { + if ((dst[i] = src[i]) == '\0') { + return 0; + } + } + } + dst[0] = '\0'; + return EINVAL; +} +# endif // !HAVE_STRCPY_S +#endif +#endif + +static char *lib_to_file (char *lib) +{ + int i; + static char libfile[FILENAMESIZE]; + char **incd = include_dirs(); + + for (i = 0; incd[i]; i++) { + struct stat st; + sprintf(libfile, "%s/%s.c", incd[i], lib); + if (!stat(libfile, &st)) + return (libfile); + } + return (0); +} +static void dumpfinal (void); + +int main (int argc, char *argv[]) +{ + char *p, *pp, *bp; + char **oldargv = argv; + char **link_lib; + int smacptr; + int first = 1; + char *asmdefs_global_end; + + macptr = 0; + ctext = 0; + argc--; argv++; + errs = 0; + sflag = 0; + cdflag = 0; + verboseflag = 0; + startup_incl = 0; + optimize = 2; /* -O2 by default */ + overlayflag = 0; + asmdefs[0] = '\0'; + + while ((p = *argv++)) { + if (*p == '-') { + /* Allow GNU style "--" long options */ + if (p[1] == '-') ++p; + while (*++p) switch (*p) { + /* defines to pass to assembler */ + case 'a': + if (strncmp(p, "acd", 3) == 0) { + cdflag = 2; /* pass '--scd' to assembler */ + acflag = 1; + strcat(asmdefs, "_ACD\t\t=\t1\n"); + p += 2; + break; + } + /* fallthrough */ + case 'A': + bp = ++p; + if (!*p) usage(oldargv[0]); + while (*p && *p != '=') p++; + strncat(asmdefs, bp, (p - bp)); +/* if (*p == '=') *p = '\t'; */ + bp = ++p; + strcat(asmdefs, "\t= "); + if (*bp == '\0') + strcat(asmdefs, "1\n"); + else { + strcat(asmdefs, bp); + strcat(asmdefs, "\n"); + } + break; + + case 'c': + if (*(p + 1) == 'd') { + cdflag = 1; /* pass '-cd' to assembler */ + p++; + break; + } + else { + usage(oldargv[0]); + break; + } + + case 'd': + case 'D': + bp = ++p; + if (!*p) usage(oldargv[0]); + while (*p && *p != '=') p++; + if (*p == '=') *p = '\t'; + while (*p) p++; + p--; + defmac(bp); + break; + + case 'f': + p++; + if (!strcmp(p, "no-recursive")) { + user_norecurse = 1; + p += 11; + } + else if (!strcmp(p, "recursive")) { + user_norecurse = 0; + p += 8; + } + else if (!strcmp(p, "no-short-enums")) { + user_short_enums = 0; + p += 13; + } + else if (!strcmp(p, "short-enums")) { + user_short_enums = 1; + p += 10; + } + else if (!strcmp(p, "signed-char")) { + user_signed_char = 1; + p += 10; + } + else if (!strcmp(p, "unsigned-char")) { + user_signed_char = 0; + p += 12; + } + else + goto unknown_option; + break; + + case 'g': + debug = 1; + strcat(asmdefs, "_DEBUG\t\t=\t1\n"); + break; + + case 'l': + bp = ++p; + while (*p && *p != ' ' && *p != '\t') + p++; + link_libs = realloc(link_libs, (link_lib_ptr + 2) * sizeof(*link_libs)); + link_libs[link_lib_ptr] = malloc(p - bp + 1); + memcpy(link_libs[link_lib_ptr], bp, p - bp); + link_libs[link_lib_ptr][p - bp] = 0; + strcat(asmdefs, "LINK_"); + strcat(asmdefs, link_libs[link_lib_ptr]); + strcat(asmdefs, "\t= 1\n"); + link_libs[++link_lib_ptr] = 0; + p--; + break; + + case 'm': + if (!strcmp(p + 1, "small")) { + /* accept this but ignore it */ + p += 5; + } + else { +unknown_option: + fprintf(stderr, "unknown option %s\n", p); + exit(1); + } + break; + + case 'o': + if (strncmp(p, "over", 4) == 0) { + overlayflag = 1; + if (strncmp(p, "overlay", 7) == 0) + p += 6; + else + p += 3; + } + else { + bp = ++p; + while (*p && *p != ' ' && *p != '\t') + p++; + memcpy(user_outfile, bp, p - bp); + user_outfile[p - bp] = 0; + p--; + } + break; + case 'O': + /* David, made -O equal to -O2 + * I'm too lazy to tape -O2 each time :) + */ + if (!p[1]) optimize = 2; + else optimize = atoi(++p); + break; + + case 's': + if (strncmp(p, "scd", 3) == 0) { + cdflag = 2; /* pass '-scd' to assembler */ + p += 2; + break; + } + else if (strncmp(p, "sgx", 3) == 0) { + sgflag = 1; + strcat(asmdefs, "_SGX\t\t=\t1\n"); + p += 2; + break; + } + /* fallthrough */ + case 'S': + sflag = 1; + break; + + case 't': + if (strncmp(p, "ted2", 4) == 0) { + ted2flag = 1; + strcat(asmdefs, "_TED2\t\t=\t1\n"); + p += 3; + break; + } + /* fallthrough */ + case 'T': + ctext = 1; + fprintf(stderr, "\nwarning: Outputting C source to the listing file disables some optimizations!\n\n"); + break; + + case 'v': + verboseflag = 1; + break; + + default: + usage(oldargv[0]); + } + } + else { + infiles = realloc(infiles, (infile_ptr + 2) * sizeof(*infiles)); + infiles[infile_ptr++] = p; + infiles[infile_ptr] = 0; + } + } + + smacptr = macptr; + if (!infiles) + usage(oldargv[0]); + printf(HUC_VERSION); + printf("\n"); + init_path(); + /* Remember the first file, it will be used as the base for the + output file name unless there is a user-specified outfile. */ + p = pp = infiles[0]; + /* Labels count is not reset for each file because labels are + global and conflicts would arise. */ + nxtlab = 1; + link_lib = link_libs; + infile_ptr = 1; + /* Remember where the global assembler defines end so we can + reset to that point for each file. */ + /* XXX: Even if we don't repeat the local asm defines, they + are still defined because we compile everything into one + assembly file. */ + asmdefs_global_end = asmdefs + strlen(asmdefs); + while (p) { + errfile = 0; + /* Truncate asm defines to the point where global + defines end. */ + asmdefs_global_end[0] = 0; + if (extension(p) == 'c' || extension(p) == 'C') { + glbsym_index = STARTGLB; + locsym_index = STARTLOC; + wsptr = ws; + inclsp = + iflevel = + skiplevel = + swstp = + litptr = + stkp = + errcnt = + ncmp = + lastst = + quote[1] = + const_nb = + line_number = 0; + macptr = smacptr; + input2 = NULL; + quote[0] = '"'; + cmode = 1; + glbflag = 1; + litlab = getlabel(); + member_table_index = 0; + memset(member_table, 0, sizeof(member_table)); + tag_table_index = 0; + norecurse = user_norecurse; + typedef_ptr = 0; + enum_ptr = 0; + enum_type_ptr = 0; + memset(fastcall_tbl, 0, sizeof(fastcall_tbl)); + defpragma(); + + /* Macros and globals have to be reset for each + file, so we have to define the defaults all over + each time. */ + defmac("__end\t__memory"); + addglb("__memory", ARRAY, CCHAR, 0, EXTERN, 0); + addglb("stack", ARRAY, CCHAR, 0, EXTERN, 0); + rglbsym_index = glbsym_index; + addglb("etext", ARRAY, CCHAR, 0, EXTERN, 0); + addglb("edata", ARRAY, CCHAR, 0, EXTERN, 0); + /* PCE specific externs */ + addglb("font_base", VARIABLE, CINT, 0, EXTERN, 0); + /* end specific externs */ + + /* deprecated ident macros */ + defmac("huc6280\t1"); + defmac("huc\t1"); + /* modern ident macros */ + defmac("__HUC__\t1"); + defmac("__HUCC__\t1"); + + if (debug) + defmac("_DEBUG\t1"); + + if (cdflag == 1) + defmac("_CD\t1"); + else if (cdflag == 2) + defmac("_SCD\t1"); + else + defmac("_ROM\t1"); + + if (overlayflag == 1) + defmac("_OVERLAY\t1"); + + if (acflag) + defmac("_ACD\t1"); + if (sgflag) + defmac("_SGX\t1"); + if (ted2flag) + defmac("_TED2\t1"); + +// initmac(); + /* + * compiler body + */ + if (!openin(p)) + exit(1); + if (first && !openout()) + exit(1); + if (first) + header(); + asmdefines(); +// gtext (); + parse(); + fclose(input); +// gdata (); + dumplits(); + dumpglbs(); + errorsummary(); +// trailer (); + pl(""); + errs = errs || errfile; + } + else { + fputs("Don't understand file ", stderr); + fputs(p, stderr); + fputc('\n', stderr); + exit(1); + } + p = infiles[infile_ptr]; + if (!p && link_lib && *link_lib) { + /* No more command-line files, continue with + libraries. */ + p = lib_to_file(*link_lib); + if (!p) { + fprintf(stderr, "cannot find library %s\n", *link_lib); + exit(1); + } + link_lib++; + } + else + infile_ptr++; + first = 0; + } + dumpfinal(); + fclose(output); + if (!errs && !sflag) { + if (user_outfile[0]) + errs = errs || assemble(user_outfile); + else + errs = errs || assemble(pp); + } + exit(errs != 0); +} + +void FEvers (void) +{ + outstr("\tFront End (2.7,84/11/28)"); +} + +void usage (char *exename) +{ + fprintf(stderr, HUC_VERSION); + fprintf(stderr, "\n\n"); + fprintf(stderr, "USAGE: %s [-options] infile\n", exename); + fprintf(stderr, "\nCompiler options:\n"); + fprintf(stderr, "-Dsym[=val] define symbol 'sym' when compiling\n"); + fprintf(stderr, "-O[val] invoke optimization (level )\n"); + fprintf(stderr, "-fno-recursive optimize assuming non-recursive code\n"); + fprintf(stderr, "-fno-short-enums always use signed int for enums\n"); + fprintf(stderr, "-funsigned-char make \"char\" unsigned (the default)\n"); + fprintf(stderr, "-fsigned-char make \"char\" signed\n"); + fprintf(stderr, "\nOutput options:\n"); + fprintf(stderr, "-s/-S create asm output only (do not invoke assembler)\n"); + fprintf(stderr, "\nLinker options:\n"); + fprintf(stderr, "-lname add library 'name.c' from include path\n"); + fprintf(stderr, "--cd create CD-ROM output\n"); + fprintf(stderr, "--scd create Super CD-ROM output\n"); + fprintf(stderr, "--acd create Arcade Card CD output\n"); + fprintf(stderr, "--sgx enable SuperGrafx support\n"); + fprintf(stderr, "--ted2 enable Turbo Everdrive2 support\n"); + fprintf(stderr, "--over(lay) create CD-ROM overlay section\n"); + fprintf(stderr, "\nAssembler options:\n"); + fprintf(stderr, "-Asym[=val] define symbol 'sym' to assembler\n"); + fprintf(stderr, "\nDebugging options:\n"); + fprintf(stderr, "-g enable extra debugging checks in output code\n"); + fprintf(stderr, "-t/-T include C source code in assembler output/listings\n"); + fprintf(stderr, "-v/-V increase verbosity of output files\n\n"); + exit(1); +} + +/* + * process all input text + * + * at this level, only static declarations, defines, includes, + * and function definitions are legal. + * + */ +void parse (void) +{ + if (!startup_incl) { + inc_startup(); + incl_huc_h(); + incl_globals_h(); + } + + while (1) { + blanks(); + if (feof(input)) + break; +// Note: +// At beginning of 'parse' call, the header has been output to '.s' +// file, as well as all the -Asym=val operands from command line. +// +// But initial '#include "startup.asm"' statement was not yet output +// (allowing for additional asm define's to be parsed and output first. +// +// We can parse some trivial tokens first (including the asmdef...), +// but the #include "startup.asm" line must be output before actual code +// (And only once...) +// + if (amatch("#asmdef", 7)) { + doasmdef(); + continue; + } + + if (amatch("extern", 6)) + dodcls(EXTERN, NULL_TAG, 0); + else if (amatch("static", 6)) { + if (amatch("const", 5)) { + /* XXX: what about the static part? */ + dodcls(CONST, NULL_TAG, 0); + } + else + dodcls(STATIC, NULL_TAG, 0); + } + else if (amatch("const", 5)) + dodcls(CONST, NULL_TAG, 0); + else if (amatch("typedef", 7)) + dotypedef(); + else if (dodcls(PUBLIC, NULL_TAG, 0)) ; + else if (match("#asm")) + doasm(); + else if (match("#include")) + doinclude(); + else if (match("#inc")) + dopsdinc(); + else if (match("#def")) + dopsddef(); + else + newfunc(NULL, 0, 0, 0, 0); + } + if (optimize) + flush_ins(); +} + +/* + * parse top level declarations + */ +int dodcls (int stclass, TAG_SYMBOL *mtag, int is_struct) +{ + int err; + struct type_type t; + + blanks(); + + if (match_type(&t, NO, YES)) { + if (t.type_type == CSTRUCT && t.otag == -1) + t.otag = define_struct(t.sname, stclass, !!(t.flags & F_STRUCT)); + else if (t.type_type == CENUM) { + if (t.otag == -1) + t.otag = define_enum(t.sname, stclass); + t.type_type = enum_types[t.otag].base; + } + err = declglb(t.type_type, stclass, mtag, t.otag, is_struct); + } + else if (stclass == PUBLIC) + return (0); + else + err = declglb(CINT, stclass, mtag, NULL_TAG, is_struct); + + if (err == 2) /* function */ + return (1); + else if (err) { + kill(); + return (0); + } + else + needsemicolon(); + return (1); +} + +void dotypedef (void) +{ + struct type_type t; + + if (!match_type(&t, YES, NO)) { + error("unknown type"); + kill(); + return; + } + if (t.type_type == CENUM) { + if (t.otag == -1) { + if (user_short_enums) + warning(W_GENERAL, + "typedef to undefined enum; " + "assuming base type int"); + t.type_type = CINT; + } + else + t.type_type = enum_types[t.otag].base; + } + if (!symname(t.sname)) { + error("invalid type name"); + kill(); + return; + } + typedefs = realloc(typedefs, (typedef_ptr + 1) * sizeof(struct type_type)); + typedefs[typedef_ptr++] = t; + needsemicolon(); +} + +/* + * dump the literal pool + */ +void dumplits (void) +{ + int j, k; + + if ((litptr == 0) && (const_nb == 0)) + return; + + outstr("\t.data\n"); + outstr("\t.bank CONST_BANK\n"); + if (litptr) { + outconst(litlab); + col(); + k = 0; + while (k < litptr) { + defbyte(); + j = 8; + while (j--) { + outdec(litq[k++] & 0xFF); + if ((j == 0) | (k >= litptr)) { + nl(); + break; + } + outbyte(','); + } + } + } + if (const_nb) + dump_const(); +} + +/** + * dump struct data + * @param symbol struct variable + * @param position position of the struct in the array, or zero + */ +int dump_struct (SYMBOL *symbol, int position) +{ + int dumped_bytes = 0; + int i, number_of_members, value; + + number_of_members = tag_table[symbol->tagidx].number_of_members; + for (i = 0; i < number_of_members; i++) { + // i is the index of current member, get type + int member_type = member_table[tag_table[symbol->tagidx].member_idx + i].sym_type; + if (member_type == CCHAR || member_type == CUCHAR) { + defbyte(); + dumped_bytes += 1; + } + else { + /* XXX: compound types? */ + defword(); + dumped_bytes += 2; + } + if (position < get_size(symbol->name)) { + // dump data + value = get_item_at(symbol->name, position * number_of_members + i, &tag_table[symbol->tagidx]); + outdec(value); + } + else { + // dump zero, no more data available + outdec(0); + } + nl(); + } + return (dumped_bytes); +} + +static int have_init_data = 0; +/* Initialized data must be kept in one contiguous block; pceas does not + provide segments for that, so we keep the definitions and data in + separate buffers and dump them all together after the last input file. + */ +#define DATABUFSIZE 65536 +char data_buffer[DATABUFSIZE+256]; +int data_offset = 0; +char rodata_buffer[DATABUFSIZE+256]; +int rodata_offset = 0; + +char *current_buffer = NULL; +int current_offset = 0; + +/* + * buffered print symbol prefix character + * + */ +void prefixBuffer(void) +{ + current_buffer[current_offset++] = '_'; +} + +/* + * buffered print string + * + */ +void outstrBuffer (char *ptr) +{ + int i = 0; + + if (current_offset >= DATABUFSIZE) { + printf("HuC compiler overrun detected, DATABUFSIZE is too small!\n"); + exit(-1); + } + + while (ptr[i]) + current_buffer[current_offset++] = ptr[i++]; +} + +/* + * buffered print character + * + */ +char outbyteBuffer (char c) +{ + if (c == 0) + return (0); + + current_buffer[current_offset++] = c; + + return (c); +} + +/* + * buffered print decimal number + * + */ +void outdecBuffer (int number) +{ + if (current_offset >= DATABUFSIZE) { + printf("HuC compiler overrun detected, DATABUFSIZE is too small!\n"); + exit(-1); + } + + current_offset += sprintf(current_buffer + current_offset, "%ld", (long) number); +} + +/* + * buffered print pseudo-op to define a byte + * + */ +void nlBuffer (void) +{ + current_buffer[current_offset++] = EOL; +} + +/* + * buffered print pseudo-op to define a byte + * + */ +void defbyteBuffer (void) +{ + outstrBuffer(".db\t"); +} + +/* + * buffered print pseudo-op to define storage + * + */ +void defstorageBuffer (void) +{ + outstrBuffer(".ds\t"); +} + +/* + * buffered print pseudo-op to define a word + * + */ +void defwordBuffer (void) +{ + outstrBuffer(".dw\t"); +} + +/** + * buffered dump struct data + * @param symbol struct variable + * @param position position of the struct in the array, or zero + */ +int dump_structBuffer (SYMBOL *symbol, int position) +{ + int dumped_bytes = 0; + int i, number_of_members, value; + + number_of_members = tag_table[symbol->tagidx].number_of_members; + for (i = 0; i < number_of_members; i++) { + // i is the index of current member, get type + int member_type = member_table[tag_table[symbol->tagidx].member_idx + i].sym_type; + if (member_type == CCHAR || member_type == CUCHAR) { + defbyteBuffer(); + dumped_bytes += 1; + } + else { + /* XXX: compound types? */ + defwordBuffer(); + dumped_bytes += 2; + } + if (position < get_size(symbol->name)) { + // dump data + value = get_item_at(symbol->name, position * number_of_members + i, &tag_table[symbol->tagidx]); + outdecBuffer(value); + } + else { + // dump zero, no more data available + outdecBuffer(0); + } + nlBuffer(); + } + return (dumped_bytes); +} + +/* + * dump all static variables + */ +void dumpglbs (void) +{ + int i = 1; + int dim, list_size, line_count; + int j; + FILE *save = output; + + /* This is done in several passes: + Pass 0: Dump initialization data into const bank. + Pass 1: Define space for uninitialized data. + Pass 2: Define space for initialized data. + */ + if (glbflag) { + int pass = 0; +next: + i = 1; + for (cptr = (symtab + rglbsym_index); cptr < (symtab + glbsym_index); cptr++) { + if (cptr->identity != FUNCTION) { +// ppubext(cptr); + if ((cptr->storage & WRITTEN) == 0 && /* Not yet written to file */ + (cptr->storage & STORAGE) != EXTERN) { + dim = cptr->offset; + if (find_symbol_initials(cptr->name)) { + // has initials + /* dump initialization data */ + if (pass == 1) /* initialized data not handled in pass 1 */ + continue; + else if (pass == 2) { + /* define space for initialized data */ + current_buffer = data_buffer; + current_offset = data_offset; + if ((cptr->storage & STORAGE) != LSTATIC) + prefixBuffer(); + outstrBuffer(cptr->name); + outstrBuffer(":\n"); + defstorageBuffer(); + outdecBuffer(cptr->alloc_size); + nlBuffer(); + cptr->storage |= WRITTEN; + data_offset = current_offset; + current_buffer = NULL; + current_offset = 0; + continue; + } + /* output initialization data into const bank */ + current_buffer = rodata_buffer; + current_offset = rodata_offset; + have_init_data = 1; + list_size = 0; + line_count = 0; + list_size = get_size(cptr->name); + if (cptr->sym_type == CSTRUCT) + list_size /= tag_table[cptr->tagidx].number_of_members; + if (dim == -1) + dim = list_size; + int item; + /* dim is an item count for non-compound types and a byte size + for compound types; dump_struct() wants an item number, so + we have to count both to get the right members out. */ + for (j = item = 0; j < dim; j++, item++) { + if (cptr->sym_type == CSTRUCT) + j += dump_structBuffer(cptr, item) - 1; + else { + if (line_count % 10 == 0) { + nlBuffer(); + if (cptr->sym_type == CCHAR || cptr->sym_type == CUCHAR) + defbyteBuffer(); + else + defwordBuffer(); + } + if (j < list_size) { + // dump data + int value = get_item_at(cptr->name, j, &tag_table[cptr->tagidx]); + outdecBuffer(value); + } + else { + // dump zero, no more data available + outdecBuffer(0); + } + line_count++; + if (line_count % 10 == 0) + line_count = 0; + else { + if (j < dim - 1) + outbyteBuffer(','); + } + } + } + nlBuffer(); + rodata_offset = current_offset; + current_buffer = NULL; + current_offset = 0; + } + else { + if (pass == 0) + continue; + /* define space in bss */ + if (i) { + i = 0; + nl(); + gdata(); + } + if ((cptr->storage & STORAGE) != LSTATIC) + prefix(); + outstr(cptr->name); + outstr(":\n"); + defstorage(); + outdec(cptr->alloc_size); + nl(); + cptr->storage |= WRITTEN; + } + } + } + else { +// fpubext(cptr); + } + } + if (++pass < 3) + goto next; + } + if (i) { + nl(); + gdata(); + } + output = save; +} + +static void dumpfinal (void) +{ + int i; + + if (leaf_cnt) { + outstr("leaf_loc:\n\t.ds\t\t"); + outdec(leaf_size); + nl(); + for (i = 0; i < leaf_cnt; i++) { + outstr("__"); + outstr(leaf_functions[i]); + outstr("_end:\n"); + } + } + if (rodata_offset == 0) { + outstr("huc_rodata:\n"); + outstr("__huc_rodata:\n"); + outstr("huc_rodata_end:\n"); + outstr("__huc_rodata_end:\n"); + } + outstr("huc_data:\n"); + outstr("__huc_data:\n"); + if (data_offset != 0) { + data_buffer[data_offset] = '\0'; + outstr(data_buffer); + } + outstr("huc_data_end:\n"); + outstr("__huc_data_end:\n"); + if (globals_h_in_process != 1) + outstr("__heap_start:\n"); + if (rodata_offset != 0) { + rodata_buffer[rodata_offset] = '\0'; + ol(".data"); + ol(".bank CONST_BANK"); + outstr("huc_rodata:\n"); + outstr("__huc_rodata:\n"); + outstr(rodata_buffer); + outstr("huc_rodata_end:\n"); + outstr("__huc_rodata_end:\n"); + } + fseek(output, output_globdef, SEEK_SET); + if (have_init_data) + outstr("HAVE_INIT = 1\n"); +} + +/* + * report errors + */ +void errorsummary (void) +{ + if (ncmp) + error("missing closing bracket"); + nl(); + comment(); + outdec(errcnt); + if (errcnt) errfile = YES; + outstr(" error(s) in compilation"); + nl(); + comment(); + ot("literal pool:"); + outdec(litptr); + nl(); + comment(); + ot("constant pool:"); + outdec(const_size); + nl(); + comment(); + ot("global pool:"); + outdec(glbsym_index - rglbsym_index); + nl(); + comment(); + ot("Macro pool:"); + outdec(macptr); + nl(); + pl(errcnt ? "Error(s)" : "No errors"); +} + +char extension (char *s) +{ + s += strlen(s) - 2; + if (*s == '.') + return (*(s + 1)); + + return (' '); +} + +#ifndef _WIN32 +#include +#endif + +int assemble (char *s) +{ +#if defined(_WIN32) + + char *exe; + char buf[512]; + char* p; + + exe = getenv("PCE_PCEAS"); + if (!exe) { + exe = "pceas.exe"; + } + + strcpy_s(buf, sizeof(buf), exe); + strcat_s(buf, sizeof(buf), " "); + for (p = buf; (p = strchr(p, '/')) != NULL; *p++ = '\\'); + + switch (cdflag) { + case 1: + strcat_s(buf, sizeof(buf), "--cd "); + break; + + case 2: + strcat_s(buf, sizeof(buf), "--scd "); + break; + + default: + strcat_s(buf, sizeof(buf), "--raw --pad "); + break; + } + + if (overlayflag) + strcat_s(buf, sizeof(buf), "--over "); + + if (verboseflag) { + strcat_s(buf, sizeof(buf), "-S -l 3 -m "); + } + + strcat_s(buf, sizeof(buf), "--hucc "); + + strcat_s(buf, sizeof(buf), "\""); + strcat_s(buf, sizeof(buf), s); + buf[strlen(buf) - 1] = 's'; + strcat_s(buf, sizeof(buf), "\""); + +// Comment this out later... +// printf("invoking pceas:\n"); +// printf("%s\n", buf); + + return (system(buf)); + +#elif defined(__unix__) || defined(__APPLE__) + + char *exe; + char buf[512]; + char *opts[16]; + int i = 0; + + exe = getenv("PCE_PCEAS"); + if (!exe) { + exe = "pceas"; + } + opts[i++] = exe; + switch (cdflag) { + case 1: + opts[i++] = "--cd"; + break; + + case 2: + opts[i++] = "--scd"; + break; + + default: + opts[i++] = "--raw"; + opts[i++] = "--pad"; + break; + } + + if (overlayflag) + opts[i++] = "--over"; /* compile as overlay */ + + if (verboseflag) { + opts[i++] = "-S"; /* asm: display full segment map */ + opts[i++] = "-l 3"; /* top listing output */ + opts[i++] = "-m"; /* force macros also */ + } + else + opts[i++] = "-l 0"; + + opts[i++] = "--hucc"; /* --newproc --strip -O and more! */ + + strcpy(buf, s); + buf[strlen(buf) - 1] = 's'; + opts[i++] = buf; + + opts[i++] = 0; + +// Comment this out later... +// { +// int j; +// printf("invoking pceas:\n"); +// for (j = 0; j < i; j++) +// printf("arg[%d] = %s\n", j, opts[j]); +// } + + return (execvp(exe, (char *const *)opts)); + +#else +#error Add calling sequence depending on your OS +#endif +} diff --git a/src/hucc/main.h b/src/hucc/main.h new file mode 100644 index 00000000..97f55a63 --- /dev/null +++ b/src/hucc/main.h @@ -0,0 +1,32 @@ +/* File main.c: 2.7 (84/11/28,10:14:56) + * + * PC Engine C Compiler + * Made by , hacked to work on Pc Engine by David Michel + * resumed work by Zeograd + * + * 00/02/22 : added oldargv variable to show real exe name in usage function + */ +/*% cc -O -c % + * + */ + +#ifndef _MAIN_H +#define _MAIN_H + +#include "version.h" + +#define HUC_VERSION "HuCC (" GIT_VERSION ", " GIT_DATE ")" + +void FEvers (void); +void usage (char *exename); +void parse (void); +int dodcls (int stclass, TAG_SYMBOL *mtag, int is_struct); +void dumplits (void); +void dumpglbs (void); +void errorsummary (void); +char extension (char *s); +int assemble (char *s); + +void dotypedef (void); + +#endif diff --git a/src/hucc/msbuild/hucc.sln b/src/hucc/msbuild/hucc.sln new file mode 100644 index 00000000..4cf175c1 --- /dev/null +++ b/src/hucc/msbuild/hucc.sln @@ -0,0 +1,28 @@ +īģŋ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.34601.136 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hucc", "hucc.vcxproj", "{E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Debug|Win32.ActiveCfg = Debug|Win32 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Debug|Win32.Build.0 = Debug|Win32 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Debug|x64.ActiveCfg = Debug|x64 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Debug|x64.Build.0 = Debug|x64 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Release|Win32.ActiveCfg = Release|Win32 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Release|Win32.Build.0 = Release|Win32 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Release|x64.ActiveCfg = Release|x64 + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/hucc/msbuild/hucc.vcxproj b/src/hucc/msbuild/hucc.vcxproj new file mode 100644 index 00000000..4d961f6f --- /dev/null +++ b/src/hucc/msbuild/hucc.vcxproj @@ -0,0 +1,306 @@ +īģŋ + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {E65AC2A5-0CE0-48D3-BD26-6AD84E36EBA2} + 10.0 + + + + Application + false + NotSet + v142 + false + + + Application + false + NotSet + v142 + false + + + Application + false + NotSet + v142 + true + + + Application + false + NotSet + v142 + true + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + ..\..\..\bin\ + ..\..\..\bin\ + ..\..\..\bin\ + ..\..\..\bin\ + .x86\$(Configuration)\ + .x86\$(Configuration)\ + .x64\$(Configuration)\ + .x64\$(Configuration)\ + false + false + false + false + + + + hucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)hucc.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + true + stdcpp17 + stdc17 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)hucc.pdb + Console + false + + + MachineX86 + + + true + hucc.bsc + + + + + hucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)hucc.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + true + stdcpp17 + stdc17 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)hucc.pdb + Console + false + + + + + true + hucc.bsc + + + + + hucc.tlb + + + + + Disabled + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)hucc.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + true + stdcpp17 + stdc17 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + true + $(OutDir)hucc.pdb + Console + false + + + MachineX86 + + + true + hucc.bsc + + + + + hucc.tlb + + + + + Disabled + %(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)hucc.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + true + stdcpp17 + stdc17 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + true + $(OutDir)hucc.pdb + Console + false + + + + + true + hucc.bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/hucc/msbuild/hucc.vcxproj.filters b/src/hucc/msbuild/hucc.vcxproj.filters new file mode 100644 index 00000000..a8dfcdab --- /dev/null +++ b/src/hucc/msbuild/hucc.vcxproj.filters @@ -0,0 +1,51 @@ +īģŋ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/hucc/optimize.c b/src/hucc/optimize.c new file mode 100644 index 00000000..cbbbab73 --- /dev/null +++ b/src/hucc/optimize.c @@ -0,0 +1,3582 @@ +/* File opt.c: 2.1 (83/03/20,16:02:09) */ +/*% cc -O -c % + * + */ + +// #define DEBUG_OPTIMIZER + +#define OPT_ARRAY_RD 1 +#define OPT_ARRAY_WR 1 + +#ifdef DEBUG_OPTIMIZER +#define ODEBUG(...) printf( __VA_ARGS__ ) +#else +#define ODEBUG(...) +#endif + +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "sym.h" +#include "code.h" +#include "function.h" +#include "optimize.h" +#include "io.h" +#include "error.h" + +#ifdef _MSC_VER + #include + #define __builtin_popcount __popcnt + #define __builtin_ctz _tzcnt_u32 +#endif + +#ifdef __GNUC__ + /* GCC doesn't like "strcmp((char *)p[0]->ins_data,"! */ + #pragma GCC diagnostic ignored "-Wstringop-overread" +#endif + +/* flag information for each of the i-code instructions */ +/* + * N.B. this table MUST be kept updated and in the same order as the i-code + * enum list in defs.h + */ +unsigned char icode_flags[] = { + 0, + + // i-code that retires the primary register contents + + /* I_FENCE */ 0, + + /* i-code that declares a byte sized primary register */ + + /* I_SHORT */ 0, + + // i-codes for handling farptr + + /* I_FARPTR */ 0, + /* I_FARPTR_I */ 0, + /* I_FARPTR_GET */ 0, + /* I_FGETW */ 0, + /* I_FGETB */ 0, + /* I_FGETUB */ 0, + + // i-codes for interrupts + + /* I_SEI */ 0, + /* I_CLI */ 0, + + // i-codes for calling functions + + /* I_MACRO */ 0, + /* I_CALL */ 0, + /* I_FUNCP_WR */ 0, + /* I_CALLP */ 0, + + // i-codes for C functions and the C parameter stack + + /* I_ENTER */ 0, + /* I_RETURN */ 0, + /* I_GETACC */ 0, + /* I_SAVESP */ 0, + /* I_LOADSP */ 0, + /* I_MODSP */ 0, + /* I_PUSH_WR */ IS_USEPR, + /* I_POP_WR */ 0, + /* I_SPUSH_WR */ IS_USEPR, + /* I_SPUSH_UR */ IS_USEPR, + /* I_SPOP_WR */ 0, + /* I_SPOP_UR */ 0, + + // i-codes for handling boolean tests and branching + + /* I_SWITCH_WR */ IS_USEPR, + /* I_SWITCH_UR */ IS_USEPR, + /* I_CASE */ 0, + /* I_ENDCASE */ 0, + /* I_LABEL */ 0, + /* I_ALIAS */ 0, + /* I_BRA */ 0, + /* I_BFALSE */ 0, + /* I_BTRUE */ 0, + /* I_DEF */ 0, + + /* I_CMP_WT */ IS_USEPR, + /* X_CMP_WI */ IS_USEPR, + /* X_CMP_WM */ IS_USEPR, + /* X_CMP_WS */ IS_USEPR + IS_SPREL, + + /* X_CMP_UIQ */ IS_USEPR + IS_UBYTE, + /* X_CMP_UMQ */ IS_USEPR + IS_UBYTE, + /* X_CMP_USQ */ IS_USEPR + IS_SPREL + IS_UBYTE, + + /* I_NOT_WR */ IS_USEPR, + /* X_NOT_WP */ 0, + /* X_NOT_WM */ 0, + /* X_NOT_WS */ IS_SPREL, + /* X_NOT_WAR */ 0, + /* X_NOT_UP */ 0, + /* X_NOT_UM */ 0, + /* X_NOT_US */ IS_SPREL, + /* X_NOT_UAR */ 0, + /* X_NOT_UAY */ 0, + + /* I_TST_WR */ IS_USEPR, + /* X_TST_WP */ 0, + /* X_TST_WM */ 0, + /* X_TST_WS */ IS_SPREL, + /* X_TST_WAR */ 0, + /* X_TST_UP */ 0, + /* X_TST_UM */ 0, + /* X_TST_US */ IS_SPREL, + /* X_TST_UAR */ 0, + /* X_TST_UAY */ 0, + + /* X_NAND_WI */ IS_USEPR, + /* X_TAND_WI */ IS_USEPR, + + /* X_NOT_CF */ 0, + + /* I_BOOLEAN */ 0, + /* X_BOOLNOT_WR */ IS_USEPR, + /* X_BOOLNOT_WP */ 0, + /* X_BOOLNOT_WM */ 0, + /* X_BOOLNOT_WS */ IS_SPREL, + /* X_BOOLNOT_WAR */ 0, + /* X_BOOLNOT_UP */ 0, + /* X_BOOLNOT_UM */ 0, + /* X_BOOLNOT_US */ IS_SPREL, + /* X_BOOLNOT_UAR */ 0, + /* X_BOOLNOT_UAY */ 0, + + // i-codes for loading the primary register + + /* I_LD_WI */ 0, + /* X_LD_UIQ */ IS_SHORT, + /* I_LEA_S */ IS_SPREL, + + /* I_LD_WM */ 0, + /* I_LD_BM */ IS_SBYTE, + /* I_LD_UM */ IS_UBYTE, + + /* I_LD_WMQ */ 0, + /* I_LD_BMQ */ IS_SBYTE, + /* I_LD_UMQ */ IS_UBYTE, + + /* I_LDY_WMQ */ 0, + /* I_LDY_BMQ */ IS_SBYTE, + /* I_LDY_UMQ */ IS_UBYTE, + + /* I_LD_WP */ 0, + /* I_LD_BP */ IS_SBYTE, + /* I_LD_UP */ IS_UBYTE, + + /* X_LD_WAR */ 0, + /* X_LD_BAR */ IS_SBYTE, + /* X_LD_UAR */ IS_UBYTE, + + /* X_LD_BAY */ IS_SBYTE, + /* X_LD_UAY */ IS_UBYTE, + + /* X_LD_WS */ IS_SPREL, + /* X_LD_BS */ IS_SBYTE + IS_SPREL, + /* X_LD_US */ IS_UBYTE + IS_SPREL, + + /* X_LD_WSQ */ IS_SPREL, + /* X_LD_BSQ */ IS_SBYTE + IS_SPREL, + /* X_LD_USQ */ IS_UBYTE + IS_SPREL, + + /* X_LDY_WSQ */ IS_SPREL, + /* X_LDY_BSQ */ IS_SBYTE + IS_SPREL, + /* X_LDY_USQ */ IS_UBYTE + IS_SPREL, + + /* X_LDP_WAR */ 0, + /* X_LDP_BAR */ IS_SBYTE, + /* X_LDP_UAR */ IS_UBYTE, + + /* X_LDP_BAY */ IS_SBYTE, + /* X_LDP_UAY */ IS_UBYTE, + + // i-codes for pre- and post- increment and decrement + + /* X_INCLD_WM */ 0, + /* X_INCLD_BM */ IS_SBYTE, + /* X_INCLD_UM */ IS_UBYTE, + + /* X_DECLD_WM */ 0, + /* X_DECLD_BM */ IS_SBYTE, + /* X_DECLD_UM */ IS_UBYTE, + + /* X_LDINC_WM */ 0, + /* X_LDINC_BM */ IS_SBYTE, + /* X_LDINC_UM */ IS_UBYTE, + + /* X_LDDEC_WM */ 0, + /* X_LDDEC_BM */ IS_SBYTE, + /* X_LDDEC_UM */ IS_UBYTE, + + /* X_INC_WMQ */ 0, + /* X_INC_UMQ */ 0, + + /* X_DEC_WMQ */ 0, + /* X_DEC_UMQ */ 0, + + /* X_INCLD_WS */ IS_SPREL, + /* X_INCLD_BS */ IS_SBYTE + IS_SPREL, + /* X_INCLD_US */ IS_UBYTE + IS_SPREL, + + /* X_DECLD_WS */ IS_SPREL, + /* X_DECLD_BS */ IS_SBYTE + IS_SPREL, + /* X_DECLD_US */ IS_UBYTE + IS_SPREL, + + /* X_LDINC_WS */ IS_SPREL, + /* X_LDINC_BS */ IS_SBYTE + IS_SPREL, + /* X_LDINC_US */ IS_UBYTE + IS_SPREL, + + /* X_LDDEC_WS */ IS_SPREL, + /* X_LDDEC_BS */ IS_SBYTE + IS_SPREL, + /* X_LDDEC_US */ IS_UBYTE + IS_SPREL, + + /* X_INC_WSQ */ IS_SPREL, + /* X_INC_USQ */ IS_SPREL, + + /* X_DEC_WSQ */ IS_SPREL, + /* X_DEC_USQ */ IS_SPREL, + + /* X_INCLD_WAR */ 0, + /* X_LDINC_WAR */ 0, + /* X_DECLD_WAR */ 0, + /* X_LDDEC_WAR */ 0, + + /* X_INCLD_BAR */ IS_SBYTE, + /* X_INCLD_UAR */ IS_UBYTE, + /* X_LDINC_BAR */ IS_SBYTE, + /* X_LDINC_UAR */ IS_UBYTE, + /* X_DECLD_BAR */ IS_SBYTE, + /* X_DECLD_UAR */ IS_UBYTE, + /* X_LDDEC_BAR */ IS_SBYTE, + /* X_LDDEC_UAR */ IS_UBYTE, + + /* X_INCLD_BAY */ IS_SBYTE, + /* X_INCLD_UAY */ IS_UBYTE, + /* X_LDINC_BAY */ IS_SBYTE, + /* X_LDINC_UAY */ IS_UBYTE, + /* X_DECLD_BAY */ IS_SBYTE, + /* X_DECLD_UAY */ IS_UBYTE, + /* X_LDDEC_BAY */ IS_SBYTE, + /* X_LDDEC_UAY */ IS_UBYTE, + + /* X_INC_WARQ */ 0, + /* X_INC_UARQ */ 0, + /* X_INC_UAYQ */ 0, + + /* X_DEC_WARQ */ 0, + /* X_DEC_UARQ */ 0, + /* X_DEC_UAYQ */ 0, + + // i-codes for saving the primary register + + /* I_ST_WMIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_ST_UMIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_ST_WPI */ IS_USEPR + IS_STORE, + /* I_ST_UPI */ IS_USEPR + IS_STORE, + /* I_ST_WM */ IS_USEPR + IS_STORE, + /* I_ST_UM */ IS_USEPR + IS_STORE, + /* I_ST_WP */ IS_USEPR + IS_STORE, + /* I_ST_UP */ IS_USEPR + IS_STORE, + /* I_ST_WPT */ IS_USEPR + IS_STORE, + /* I_ST_UPT */ IS_USEPR + IS_STORE, + /* X_ST_WSIQ */ IS_USEPR + IS_STORE + IS_SHORT + IS_SPREL, + /* X_ST_USIQ */ IS_USEPR + IS_STORE + IS_SHORT + IS_SPREL, + /* X_ST_WS */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_ST_US */ IS_USEPR + IS_STORE + IS_SPREL, + + /* X_INDEX_WR */ IS_USEPR, + /* X_INDEX_UR */ IS_USEPR, + + /* X_ST_WAT */ IS_USEPR + IS_STORE, + /* X_ST_UAT */ IS_USEPR + IS_STORE, + + // i-codes for extending the primary register + + /* I_EXT_BR */ IS_USEPR, + /* I_EXT_UR */ IS_USEPR, + + // i-codes for math with the primary register + + /* I_COM_WR */ IS_USEPR, + /* I_NEG_WR */ IS_USEPR, + + /* I_ADD_WT */ IS_USEPR, + /* I_ADD_WI */ IS_USEPR, + /* I_ADD_WM */ IS_USEPR, + /* I_ADD_UM */ IS_USEPR, + /* X_ADD_WS */ IS_USEPR + IS_SPREL, + /* X_ADD_US */ IS_USEPR + IS_SPREL, + + /* I_SUB_WT */ IS_USEPR, + /* I_SUB_WI */ IS_USEPR, + /* I_SUB_WM */ IS_USEPR, + /* I_SUB_UM */ IS_USEPR, + + /* I_ISUB_WI */ IS_USEPR, + + /* I_AND_WT */ IS_USEPR, + /* I_AND_WI */ IS_USEPR, + /* I_AND_UIQ */ IS_USEPR + IS_UBYTE, + /* I_AND_WM */ IS_USEPR, + /* I_AND_UM */ IS_USEPR, + + /* I_EOR_WT */ IS_USEPR, + /* I_EOR_WI */ IS_USEPR, + /* I_EOR_WM */ IS_USEPR, + /* I_EOR_UM */ IS_USEPR, + + /* I_OR_WT */ IS_USEPR, + /* I_OR_WI */ IS_USEPR, + /* I_OR_WM */ IS_USEPR, + /* I_OR_UM */ IS_USEPR, + + /* I_ASL_WT */ IS_USEPR, + /* I_ASL_WI */ IS_USEPR, + /* I_ASL_WR */ IS_USEPR, + + /* I_ASR_WT */ IS_USEPR, + /* I_ASR_WI */ IS_USEPR, + + /* I_LSR_WT */ IS_USEPR, + /* I_LSR_WI */ IS_USEPR, + /* I_LSR_UIQ */ IS_USEPR + IS_UBYTE + IS_SHORT, + + /* I_MUL_WT */ IS_USEPR, + /* I_MUL_WI */ IS_USEPR, + + /* I_SDIV_WT */ IS_USEPR, + /* I_SDIV_WI */ IS_USEPR, + + /* I_UDIV_WT */ IS_USEPR, + /* I_UDIV_WI */ IS_USEPR, + /* I_UDIV_UI */ IS_USEPR + IS_UBYTE, + + /* I_SMOD_WT */ IS_USEPR, + /* I_SMOD_WI */ IS_USEPR, + + /* I_UMOD_WT */ IS_USEPR, + /* I_UMOD_WI */ IS_USEPR, + /* I_UMOD_UI */ IS_USEPR + IS_UBYTE, + + /* I_DOUBLE */ 0, + + // i-codes for 32-bit longs + + /* X_LDD_I */ 0, + /* X_LDD_W */ 0, + /* X_LDD_B */ 0, + /* X_LDD_S_W */ IS_SPREL, + /* X_LDD_S_B */ IS_SPREL +}; + +/* invert comparison operation */ +int compare2not [] = { + CMP_NEQ, // CMP_EQU + CMP_EQU, // CMP_NEQ + CMP_SGE, // CMP_SLT + CMP_SGT, // CMP_SLE + CMP_SLE, // CMP_SGT + CMP_SLT, // CMP_SGE + CMP_UGE, // CMP_ULT + CMP_UGT, // CMP_ULE + CMP_ULE, // CMP_UGT + CMP_ULT // CMP_UGE +}; + +/* optimize comparison between unsigned chars */ +/* C promotes an unsigned char to a signed int for comparison */ +int compare2uchar [] = { + CMP_EQU, // CMP_EQU + CMP_NEQ, // CMP_NEQ + CMP_ULT, // CMP_SLT + CMP_ULE, // CMP_SLE + CMP_UGT, // CMP_SGT + CMP_UGE, // CMP_SGE + CMP_ULT, // CMP_ULT + CMP_ULE, // CMP_ULE + CMP_UGT, // CMP_UGT + CMP_UGE // CMP_UGE +}; + +/* defines */ +#define Q_SIZE 16 + +/* locals */ +static INS q_ins[Q_SIZE]; +static int q_rd; +static int q_wr; +static int q_nb; + +/* externs */ +extern int arg_stack_flag; + + +int cmp_operands (INS *p1, INS *p2) +{ +#ifdef DEBUG_OPTIMIZER + printf("cmp"); dump_ins(p1); dump_ins(p2); +#endif + if (p1->ins_type != p2->ins_type) + return (0); + + if (p1->ins_type == T_SYMBOL) { + if (strcmp(((SYMBOL *)p1->ins_data)->name, ((SYMBOL *)p2->ins_data)->name) != 0) + return (0); + } + else { + if (p1->ins_data != p2->ins_data) + return (0); + } + return (1); +} + +inline bool is_sprel (INS *i) +{ + return (icode_flags[i->ins_code] & IS_SPREL); +} + +inline bool is_ubyte (INS *i) +{ + return (icode_flags[i->ins_code] & IS_UBYTE); +} + +inline bool is_sbyte (INS *i) +{ + return (icode_flags[i->ins_code] & IS_SBYTE); +} + +inline bool is_usepr (INS *i) +{ + return (icode_flags[i->ins_code] & IS_USEPR); +} + +inline bool is_small_array (SYMBOL *sym) +{ + return (sym->identity == ARRAY && sym->alloc_size > 0 && sym->alloc_size <= 256); +} + +/* ---- + * push_ins() + * ---- + * + */ +void push_ins (INS *ins) +{ +#ifdef DEBUG_OPTIMIZER + printf("\npush "); dump_ins(ins); +#endif + /* check queue size */ + if (q_nb == Q_SIZE) { + /* queue is full - flush the last instruction */ + if (arg_stack_flag) + arg_push_ins(&q_ins[q_rd]); + else + gen_code(&q_ins[q_rd]); + + /* advance queue read pointer */ + q_rd++; + q_nb--; + + if (q_rd == Q_SIZE) + q_rd = 0; + } + + /* push new instruction */ + q_wr++; + q_nb++; + + if (q_wr == Q_SIZE) + q_wr = 0; + + q_ins[q_wr] = *ins; + + /* optimization level 1 - simple peephole optimizer, + * replace known instruction patterns by highly + * optimized asm code + */ + if (optimize >= 1) { + INS *p[Q_SIZE]; + int i, j; + int nb; + +lv1_loop: + + + /* precalculate pointers to instructions */ + if (q_nb > 10) + nb = 10; + else + nb = q_nb; +#ifdef DEBUG_OPTIMIZER + printf("\nlv1_loop:\n"); +#endif + i = 0; + j = q_wr; + while (i < nb) { + /* save pointer */ + p[i] = &q_ins[j]; +#ifdef DEBUG_OPTIMIZER + printf("%d ", i); dump_ins(p[i]); +#endif + /* next */ + j -= 1; + if (j < 0) + j += Q_SIZE; + + ++i; + } + + /* LEVEL 1 - FUN STUFF STARTS HERE */ + nb = 0; + + /* ********************************************************* */ + /* ********************************************************* */ + + /* first check for I_FENCE, and remove it ASAP */ + if (q_nb >= 1 && p[0]->ins_code == I_FENCE) { + /* remove I_FENCE after it has been checked */ + nb = 1; + + /* + * __ld.wi i --> __st.{w/u}miq symbol, i + * __st.{w/u}m symbol + * __fence + * + * __ld.wi i --> __st.{w/u}siq n, 1 + * __st.{w/u}s n + * __fence + */ + if + ((q_nb >= 3) && + (p[1]->ins_code == I_ST_WM || + p[1]->ins_code == I_ST_UM || + p[1]->ins_code == X_ST_WS || + p[1]->ins_code == X_ST_US) && + (p[2]->ins_code == I_LD_WI) && + (p[2]->ins_type == T_VALUE) + ) { + /* replace code */ + intptr_t data = p[2]->ins_data; + *p[2] = *p[1]; + switch (p[1]->ins_code) { + case I_ST_WM: p[2]->ins_code = I_ST_WMIQ; break; + case I_ST_UM: p[2]->ins_code = I_ST_UMIQ; break; + case X_ST_WS: p[2]->ins_code = X_ST_WSIQ; break; + case X_ST_US: p[2]->ins_code = X_ST_USIQ; break; + default: abort(); + } + p[2]->imm_type = T_VALUE; + p[2]->imm_data = data; + nb = 2; + } + + /* + * __getacc --> + * __fence + * + * __add.wi / __sub.wi --> + * __fence + */ + else if + ((q_nb >= 2) && + (p[1]->ins_code == I_ADD_WI || + p[1]->ins_code == I_SUB_WI || + p[1]->ins_code == I_GETACC) + ) { + nb = 2; + } + + /* + * __ldinc.wm / __incld.wm --> __inc.wm + * __fence + * + * __lddec.wm / __decld.wm --> __dec.wm + * __fence + * + * unused pre-increment or post-increment value + * unused pre-decrement or post-decrement value + */ + else if + ((q_nb >= 2) && + (p[1]->ins_code == X_INCLD_WM || + p[1]->ins_code == X_INCLD_BM || + p[1]->ins_code == X_INCLD_UM || + p[1]->ins_code == X_LDINC_WM || + p[1]->ins_code == X_LDINC_BM || + p[1]->ins_code == X_LDINC_UM || + p[1]->ins_code == X_DECLD_WM || + p[1]->ins_code == X_DECLD_BM || + p[1]->ins_code == X_DECLD_UM || + p[1]->ins_code == X_LDDEC_WM || + p[1]->ins_code == X_LDDEC_BM || + p[1]->ins_code == X_LDDEC_UM || + p[1]->ins_code == X_INCLD_WS || + p[1]->ins_code == X_INCLD_BS || + p[1]->ins_code == X_INCLD_US || + p[1]->ins_code == X_LDINC_WS || + p[1]->ins_code == X_LDINC_BS || + p[1]->ins_code == X_LDINC_US || + p[1]->ins_code == X_DECLD_WS || + p[1]->ins_code == X_DECLD_BS || + p[1]->ins_code == X_DECLD_US || + p[1]->ins_code == X_LDDEC_WS || + p[1]->ins_code == X_LDDEC_BS || + p[1]->ins_code == X_LDDEC_US || + p[1]->ins_code == X_INCLD_WAR || + p[1]->ins_code == X_LDINC_WAR || + p[1]->ins_code == X_DECLD_WAR || + p[1]->ins_code == X_LDDEC_WAR || + p[1]->ins_code == X_INCLD_BAR || + p[1]->ins_code == X_INCLD_UAR || + p[1]->ins_code == X_LDINC_BAR || + p[1]->ins_code == X_LDINC_UAR || + p[1]->ins_code == X_DECLD_BAR || + p[1]->ins_code == X_DECLD_UAR || + p[1]->ins_code == X_LDDEC_BAR || + p[1]->ins_code == X_LDDEC_UAR || + p[1]->ins_code == X_INCLD_BAY || + p[1]->ins_code == X_INCLD_UAY || + p[1]->ins_code == X_LDINC_BAY || + p[1]->ins_code == X_LDINC_UAY || + p[1]->ins_code == X_DECLD_BAY || + p[1]->ins_code == X_DECLD_UAY || + p[1]->ins_code == X_LDDEC_BAY || + p[1]->ins_code == X_LDDEC_UAY) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case X_INCLD_WM: + case X_LDINC_WM: p[1]->ins_code = X_INC_WMQ; break; + case X_INCLD_BM: + case X_INCLD_UM: + case X_LDINC_BM: + case X_LDINC_UM: p[1]->ins_code = X_INC_UMQ; break; + case X_DECLD_WM: + case X_LDDEC_WM: p[1]->ins_code = X_DEC_WMQ; break; + case X_DECLD_BM: + case X_DECLD_UM: + case X_LDDEC_BM: + case X_LDDEC_UM: p[1]->ins_code = X_DEC_UMQ; break; + case X_INCLD_WS: + case X_LDINC_WS: p[1]->ins_code = X_INC_WSQ; break; + case X_INCLD_BS: + case X_INCLD_US: + case X_LDINC_BS: + case X_LDINC_US: p[1]->ins_code = X_INC_USQ; break; + case X_DECLD_WS: + case X_LDDEC_WS: p[1]->ins_code = X_DEC_WSQ; break; + case X_DECLD_BS: + case X_DECLD_US: + case X_LDDEC_BS: + case X_LDDEC_US: p[1]->ins_code = X_DEC_USQ; break; + case X_INCLD_WAR: + case X_LDINC_WAR: p[1]->ins_code = X_INC_WARQ; break; + case X_DECLD_WAR: + case X_LDDEC_WAR: p[1]->ins_code = X_DEC_WARQ; break; + case X_INCLD_BAR: + case X_INCLD_UAR: + case X_LDINC_BAR: + case X_LDINC_UAR: p[1]->ins_code = X_INC_UARQ; break; + case X_DECLD_BAR: + case X_DECLD_UAR: + case X_LDDEC_BAR: + case X_LDDEC_UAR: p[1]->ins_code = X_DEC_UARQ; break; + case X_INCLD_BAY: + case X_INCLD_UAY: + case X_LDINC_BAY: + case X_LDINC_UAY: p[1]->ins_code = X_INC_UAYQ; break; + case X_DECLD_BAY: + case X_DECLD_UAY: + case X_LDDEC_BAY: + case X_LDDEC_UAY: p[1]->ins_code = X_DEC_UAYQ; break; + default: abort(); + } + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* ********************************************************* */ + + /* then check for I_SHORT, and remove it ASAP */ + if (q_nb >= 1 && p[0]->ins_code == I_SHORT) { + /* remove I_SHORT after it has been checked */ + nb = 1; + + /* + * __ld.wi i --> __ld.uiq i + * __short + * + * __ld.{w/b/u}m symbol --> __ld.{w/b/u}mq i + * __short + * + * __ld.{w/b/u}s symbol --> __ld.{w/b/u}sq i + * __short + */ + if + ((q_nb >= 2) && + (p[1]->ins_code == I_LD_WI || + p[1]->ins_code == I_LD_WM || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == I_LD_UM || + p[1]->ins_code == X_LD_WS || + p[1]->ins_code == X_LD_BS || + p[1]->ins_code == X_LD_US) + ) { + switch (p[1]->ins_code) { + case I_LD_WI: p[1]->ins_code = X_LD_UIQ; break; + case I_LD_WM: p[1]->ins_code = I_LD_WMQ; break; + case I_LD_BM: p[1]->ins_code = I_LD_BMQ; break; + case I_LD_UM: p[1]->ins_code = I_LD_UMQ; break; + case X_LD_WS: p[1]->ins_code = X_LD_WSQ; break; + case X_LD_BS: p[1]->ins_code = X_LD_BSQ; break; + case X_LD_US: p[1]->ins_code = X_LD_USQ; break; + default: abort(); + } + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* then evaluate constant expressions */ + /* ********************************************************* */ + + if (q_nb >= 3) { + /* + * __push.wr --> __add.wi i + * __ld.wi i + * __add.wt + * + * __push.wr --> __sub.wi i + * __ld.wi i + * __sub.wt + * + * __push.wr --> __and.wi i + * __ld.wi i + * __and.wt + * + * __push.wr --> __eor.wi i + * __ld.wi i + * __eor.wt + * + * __push.wr --> __or.wi i + * __ld.wi i + * __or.wt + * + * __push.wr --> __asl.wi i + * __ld.wi i + * __asl.wt + * + * __push.wr --> __asr.wi i + * __ld.wi i + * __asr.wt + * + * __push.wr --> __lsr.wi i + * __ld.wi i + * __lsr.wt + * + * __push.wr --> __mul.wi i + * __ld.wi i + * __mul.wt + * + * __push.wr --> __{s/u}div.wi i + * __ld.wi i + * __{s/u}div.wt + * + * __push.wr --> __{s/u}mod.wi i + * __ld.wi i + * __{s/u}mod.wt + */ + if + ((p[0]->ins_code == I_ADD_WT || + p[0]->ins_code == I_SUB_WT || + p[0]->ins_code == I_AND_WT || + p[0]->ins_code == I_EOR_WT || + p[0]->ins_code == I_OR_WT || + p[0]->ins_code == I_ASL_WT || + p[0]->ins_code == I_ASR_WT || + p[0]->ins_code == I_LSR_WT || + p[0]->ins_code == I_MUL_WT || + p[0]->ins_code == I_SDIV_WT || + p[0]->ins_code == I_UDIV_WT || + p[0]->ins_code == I_SMOD_WT || + p[0]->ins_code == I_UMOD_WT) && + (p[1]->ins_code == I_LD_WI) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + *p[2] = *p[1]; + switch (p[0]->ins_code) { + case I_ADD_WT: p[2]->ins_code = I_ADD_WI; break; + case I_SUB_WT: p[2]->ins_code = I_SUB_WI; break; + case I_AND_WT: p[2]->ins_code = I_AND_WI; break; + case I_EOR_WT: p[2]->ins_code = I_EOR_WI; break; + case I_OR_WT: p[2]->ins_code = I_OR_WI; break; + case I_ASL_WT: p[2]->ins_code = I_ASL_WI; break; + case I_ASR_WT: p[2]->ins_code = I_ASR_WI; break; + case I_LSR_WT: p[2]->ins_code = I_LSR_WI; break; + case I_MUL_WT: p[2]->ins_code = I_MUL_WI; break; + case I_SDIV_WT: p[2]->ins_code = I_SDIV_WI; break; + case I_UDIV_WT: p[2]->ins_code = I_UDIV_WI; break; + case I_SMOD_WT: p[2]->ins_code = I_SMOD_WI; break; + case I_UMOD_WT: p[2]->ins_code = I_UMOD_WI; break; + default: abort(); + } + nb = 2; + + if (p[2]->ins_type == T_VALUE && p[2]->ins_data == 0) { + switch (p[2]->ins_code) { + case I_SDIV_WT: + case I_UDIV_WT: + case I_SMOD_WT: + case I_UMOD_WT: + error("cannot optimize a divide-by-zero"); + break; + case I_AND_WT: + case I_MUL_WT: + p[2]->ins_code = I_LD_WI; + break; + default: + nb = 3; + break; + } + } + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + if (q_nb >= 2) { + /* + * __ld.wi i --> __ld.wi (~i) + * __com.wr + */ + if + ((p[0]->ins_code == I_COM_WR) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = ~p[1]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (-i) + * __neg.wr + */ + else if + ((p[0]->ins_code == I_NEG_WR) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = -p[1]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i + j) + * __add.wi j + */ + else if + ((p[0]->ins_code == I_ADD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data += p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i - j) + * __sub.wi j + */ + else if + ((p[0]->ins_code == I_SUB_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data -= p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i & j) + * __and.wi j + */ + else if + ((p[0]->ins_code == I_AND_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data &= p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i ^ j) + * __eor.wi j + */ + else if + ((p[0]->ins_code == I_EOR_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data ^= p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i | j) + * __or.wi j + */ + else if + ((p[0]->ins_code == I_OR_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data |= p[0]->ins_data; + nb = 1; + } + + + /* + * __ld.wi i --> __ld.wi (i + i) + * __asl.wr + */ + else if + ((p[0]->ins_code == I_ASL_WR) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data += p[1]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i << j) + * __asl.wi j + */ + else if + ((p[0]->ins_code == I_ASL_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data <<= p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i >> j) + * __asr.wi j + */ + else if + ((p[0]->ins_code == I_ASR_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data >>= p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i >> j) + * __lsr.wi j + */ + else if + ((p[0]->ins_code == I_LSR_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = ((uintptr_t) p[1]->ins_data) >> p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i * j) + * __mul.wi j + */ + else if + ((p[0]->ins_code == I_MUL_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data *= p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i / j) + * __sdiv.wi j + */ + else if + ((p[0]->ins_code == I_SDIV_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = p[1]->ins_data / p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i / j) + * __udiv.wi j + */ + else if + ((p[0]->ins_code == I_UDIV_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = ((unsigned) p[1]->ins_data) / ((unsigned) p[0]->ins_data); + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i % j) + * __smod.wi j + */ + else if + ((p[0]->ins_code == I_SMOD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = p[1]->ins_data % p[0]->ins_data; + nb = 1; + } + + /* + * __ld.wi i --> __ld.wi (i % j) + * __umod.wi j + */ + else if + ((p[0]->ins_code == I_UMOD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data = ((unsigned) p[1]->ins_data) % ((unsigned) p[0]->ins_data); + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* then transform muliplication and division by a power of 2 */ + /* ********************************************************* */ + + if (q_nb >= 1) { + /* + * __mul.wi i --> __asl.wi log2(i) + */ + if + ((p[0]->ins_code == I_MUL_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data >= -1) && + (p[0]->ins_data <= 65536) + ) { + /* replace code */ + if (p[0]->ins_data == -1) { + p[0]->ins_code = I_NEG_WR; + p[0]->ins_type = 0; + p[0]->ins_data = 0; + /* no instructions removed, just loop */ + goto lv1_loop; + } + else + if (p[0]->ins_data == 0) { + p[0]->ins_code = I_LD_WI; + /* no instructions removed, just loop */ + goto lv1_loop; + } + else + if (p[0]->ins_data == 1) { + nb = 1; + } + else + if (__builtin_popcount((unsigned int)p[0]->ins_data) == 1) { + p[0]->ins_code = I_ASL_WI; + p[0]->ins_type = T_VALUE; + p[0]->ins_data = __builtin_ctz((unsigned int)p[0]->ins_data); + /* no instructions removed, just loop */ + goto lv1_loop; + } + } + + /* + * __udiv.wi i --> __lsr.wi log2(i) + * + * Also possible after converting an __sdiv.wi into a __udiv.{w/u}i + * + * N.B. You cannot convert __sdiv.wi into __asr.wi! + */ + if + ((p[0]->ins_code == I_UDIV_WI || + p[0]->ins_code == I_UDIV_UI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data >= 0) && + (p[0]->ins_data <= 65536) + ) { + /* replace code */ + if (p[0]->ins_data == 0) { + error("cannot optimize a divide-by-zero"); + } + else + if (p[0]->ins_data == 1) { + nb = 1; + } + else + if (__builtin_popcount((unsigned int)p[0]->ins_data) == 1) { + p[0]->ins_code = I_LSR_WI; + p[0]->ins_type = T_VALUE; + p[0]->ins_data = __builtin_ctz((unsigned int)p[0]->ins_data); + /* no instructions removed, just loop */ + goto lv1_loop; + } + } + + /* + * __umod.wi i --> __and.wi (i - 1) + * + * Also possible after converting an __smod.wi into a __umod.{w/u}i + * + * N.B. Modifying an __smod.wi is ugly! + */ + if + ((p[0]->ins_code == I_UMOD_WI || + p[0]->ins_code == I_UMOD_UI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data >= 0) && + (p[0]->ins_data <= 65536) + ) { + /* replace code */ + if (p[0]->ins_data == 0) { + error("cannot optimize a divide-by-zero"); + } + else + if (p[0]->ins_data == 1) { + p[0]->ins_code = I_LD_WI; + p[0]->ins_type = T_VALUE; + p[0]->ins_data = 0; + /* no instructions removed, just loop */ + goto lv1_loop; + } + else + if (__builtin_popcount((unsigned int)p[0]->ins_data) == 1) { + p[0]->ins_code = I_AND_WI; + p[0]->ins_data = p[0]->ins_data - 1; + /* no instructions removed, just loop */ + goto lv1_loop; + } + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* then optimize conditional tests */ + /* ********************************************************* */ + + if (q_nb >= 4) { + /* + * is_ubyte() --> is_ubyte() + * __push.wr __cmp.umq type, symbol + * __ld.um symbol + * __cmp.wt type + * + * is_ubyte() --> is_ubyte() + * __push.wr __cmp.usq type, (n - 2) + * __ld.us n + * __cmp.wt type + */ + if + ((p[0]->ins_code == I_CMP_WT) && + (p[1]->ins_code == I_LD_UM || + p[1]->ins_code == X_LD_US) && + (p[2]->ins_code == I_PUSH_WR) && + (is_ubyte(p[3])) + ) { + /* replace code */ + *p[2] = *p[1]; + switch (p[1]->ins_code) { + case I_LD_UM: p[2]->ins_code = X_CMP_UMQ; break; + case X_LD_US: p[2]->ins_code = X_CMP_USQ; p[2]->ins_data -= 2; break; + default: break; + } + p[2]->cmp_type = compare2uchar[p[0]->cmp_type]; + nb = 2; + } + + /* + * LLnn: --> LLnn: + * __bool LLqq: + * __tst.wr __bool + * LLqq: + * + * Remove redundant __tst.wr from compound conditionals + * that the compiler generates. + */ + else if + ((p[0]->ins_code == I_LABEL) && + (p[1]->ins_code == I_TST_WR) && + (p[2]->ins_code == I_BOOLEAN) && + (p[3]->ins_code == I_LABEL) + ) { + *p[1] = *p[2]; + *p[2] = *p[0]; + nb = 1; + } + + /* + * LLnn: --> LLnn: + * __bool __bfalse + * __tst.wr + * __bfalse + * + * LLnn: --> LLnn: + * __bool __btrue + * __tst.wr + * __btrue + * + * Remove redundant __tst.wr from compound conditionals + * that the compiler always generates with back-to-back + * "&&" or "||" sub-expressions. + */ + else if + ((p[0]->ins_code == I_BFALSE || + p[0]->ins_code == I_BTRUE) && + (p[1]->ins_code == I_TST_WR) && + (p[2]->ins_code == I_BOOLEAN) && + (p[3]->ins_code == I_LABEL) + ) { + *p[2] = *p[0]; + nb = 2; + } + + /* + * LLnn: --> LLnn: + * __bool __not.cf + * __not.wr __bfalse + * __bfalse + * + * LLnn: --> LLnn: + * __bool __not.cf + * __not.wr __btrue + * __btrue + * + * Happens when a "!" follows a condition in brackets. + * + * It is so tempting to just invert the branch, but + * that would break subsequent branches! + */ + else if + ((p[0]->ins_code == I_BFALSE || + p[0]->ins_code == I_BTRUE) && + (p[1]->ins_code == I_NOT_WR) && + (p[2]->ins_code == I_BOOLEAN) && + (p[3]->ins_code == I_LABEL) + ) { + *p[1] = *p[0]; + p[2]->ins_code = X_NOT_CF; + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + if (q_nb >= 3) { + /* + * __push.wr --> __not.wr + * __ld.wi 0 + * __cmp.wt equ_w + * + * __push.wr --> __tst.wr + * __ld.wi 0 + * __cmp.wt neq_w + * + * Check for this before converting to __cmp.wi! + */ + if + ((p[0]->ins_code == I_CMP_WT) && + (p[0]->cmp_type == CMP_EQU || + p[0]->cmp_type == CMP_NEQ) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) && + (p[1]->ins_data == 0) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + p[2]->ins_code = (p[0]->cmp_type == CMP_EQU) ? I_NOT_WR : I_TST_WR; + p[2]->ins_type = 0; + p[2]->ins_data = 0; + nb = 2; + } + + /* + * __push.wr --> __cmp.wi type, i + * __ld.wi i + * __cmp.wt type + * + * __push.wr --> __cmp.wm type, symbol + * __ld.wm symbol + * __cmp.wt type + * + * __push.wr --> __cmp.ws type, (n - 2) + * __ld.ws n + * __cmp.wt type + */ + else if + ((p[0]->ins_code == I_CMP_WT) && + (p[1]->ins_code == I_LD_WI || + p[1]->ins_code == I_LD_WM || + p[1]->ins_code == X_LD_WS) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + *p[2] = *p[1]; + switch (p[1]->ins_code) { + case I_LD_WI: p[2]->ins_code = X_CMP_WI; break; + case I_LD_WM: p[2]->ins_code = X_CMP_WM; break; + case X_LD_WS: p[2]->ins_code = X_CMP_WS; p[2]->ins_data -= 2; break; + default: break; + } + p[2]->cmp_type = p[0]->cmp_type; + nb = 2; + } + + /* + * __cmp.wt --> __cmp.wt + * __bool + * __not.wr + * + * __cmp.wi --> __cmp.wi + * __bool + * __not.wr + * + * __cmp.wm --> __cmp.wm + * __bool + * __not.wr + * + * __cmp.ws --> __cmp.ws + * __bool + * __not.wr + * + * __cmp.uiq --> __cmp.uiq + * __bool + * __not.wr + * + * __cmp.umq --> __cmp.umq + * __bool + * __not.wr + * + * __cmp.usq --> __cmp.usq + * __bool + * __not.wr + * + * N.B. This inverts the test condition of the __cmp.wt! + */ + else if + ( + (p[0]->ins_code == I_NOT_WR) && + (p[1]->ins_code == I_BOOLEAN) && + (p[2]->ins_code == I_CMP_WT || + p[2]->ins_code == X_CMP_WI || + p[2]->ins_code == X_CMP_WM || + p[2]->ins_code == X_CMP_WS || + p[2]->ins_code == X_CMP_UIQ || + p[2]->ins_code == X_CMP_UMQ || + p[2]->ins_code == X_CMP_USQ) + ) { + p[2]->cmp_type = compare2not[p[2]->cmp_type]; + nb = 2; + } + + /* + * __not.wr --> __tst.wr + * __bool + * __not.wr + * + * __not.{w/u}p --> __tst.{w/u}p + * __bool + * __not.wr + * + * __not.{w/u}m symbol --> __tst.{w/u}m symbol + * __bool + * __not.wr + * + * __not.{w/u}s n --> __tst.{w/u}s n + * __bool + * __not.wr + * + * __not.{w/u}ar symbol --> __tst.{w/u}ar symbol + * __bool + * __not.wr + * + * __not.uay symbol --> __tst.uay symbol + * __bool + * __not.wr + * + * __nand.wi i --> __tand.wi i + * __bool + * __not.wr + * + * __tst.wr --> __not.wr + * __bool + * __not.wr + * + * __tst.{w/u}p --> __not.{w/u}p + * __bool + * __not.wr + * + * __tst.{w/u}m symbol --> __not.{w/u}m symbol + * __bool + * __not.wr + * + * __tst.{w/u}s n --> __not.{w/u}s n + * __bool + * __not.wr + * + * __tst.{w/u}ar symbol --> __not.{w/u}ar symbol + * __bool + * __not.wr + * + * __tst.uay symbol --> __not.uay symbol + * __bool + * __not.wr + * + * __tand.wi i --> __nand.wi i + * __bool + * __not.wr + * + * N.B. This inverts the test condition of the __tst.* or __not.* + */ + else if + ((p[0]->ins_code == I_NOT_WR) && + (p[1]->ins_code == I_BOOLEAN) && + (p[2]->ins_code == I_NOT_WR || + p[2]->ins_code == X_NOT_WP || + p[2]->ins_code == X_NOT_WM || + p[2]->ins_code == X_NOT_WS || + p[2]->ins_code == X_NOT_WAR || + p[2]->ins_code == X_NOT_UP || + p[2]->ins_code == X_NOT_UM || + p[2]->ins_code == X_NOT_US || + p[2]->ins_code == X_NOT_UAR || + p[2]->ins_code == X_NOT_UAY || + p[2]->ins_code == X_NAND_WI || + p[2]->ins_code == I_TST_WR || + p[2]->ins_code == X_TST_WP || + p[2]->ins_code == X_TST_WM || + p[2]->ins_code == X_TST_WS || + p[2]->ins_code == X_TST_WAR || + p[2]->ins_code == X_TST_UP || + p[2]->ins_code == X_TST_UM || + p[2]->ins_code == X_TST_US || + p[2]->ins_code == X_TST_UAR || + p[2]->ins_code == X_TST_UAY || + p[2]->ins_code == X_TAND_WI) + ) { + switch (p[2]->ins_code) { + case I_NOT_WR: p[2]->ins_code = I_TST_WR; break; + case X_NOT_WP: p[2]->ins_code = X_TST_WP; break; + case X_NOT_WM: p[2]->ins_code = X_TST_WM; break; + case X_NOT_WS: p[2]->ins_code = X_TST_WS; break; + case X_NOT_WAR: p[2]->ins_code = X_TST_WAR; break; + case X_NOT_UP: p[2]->ins_code = X_TST_UP; break; + case X_NOT_UM: p[2]->ins_code = X_TST_UM; break; + case X_NOT_US: p[2]->ins_code = X_TST_US; break; + case X_NOT_UAR: p[2]->ins_code = X_TST_UAR; break; + case X_NOT_UAY: p[2]->ins_code = X_TST_UAY; break; + case X_NAND_WI: p[2]->ins_code = X_TAND_WI; break; + case I_TST_WR: p[2]->ins_code = I_NOT_WR; break; + case X_TST_WP: p[2]->ins_code = X_NOT_WP; break; + case X_TST_WM: p[2]->ins_code = X_NOT_WM; break; + case X_TST_WS: p[2]->ins_code = X_NOT_WS; break; + case X_TST_WAR: p[2]->ins_code = X_NOT_WAR; break; + case X_TST_UP: p[2]->ins_code = X_NOT_UP; break; + case X_TST_UM: p[2]->ins_code = X_NOT_UM; break; + case X_TST_US: p[2]->ins_code = X_NOT_US; break; + case X_TST_UAR: p[2]->ins_code = X_NOT_UAR; break; + case X_TST_UAY: p[2]->ins_code = X_NOT_UAY; break; + case X_TAND_WI: p[2]->ins_code = X_NAND_WI; break; + default: abort(); + } + nb = 2; + } + + /* + * __cmp.wt --> __cmp.wt + * __bool + * __tst.wr + * + * __cmp.wi --> __cmp.wi + * __bool + * __tst.wr + * + * __cmp.wm --> __cmp.wm + * __bool + * __tst.wr + * + * __cmp.ws --> __cmp.ws + * __bool + * __tst.wr + * + * __cmp.uiq --> __cmp.uiq + * __bool + * __tst.wr + * + * __cmp.umq --> __cmp.umq + * __bool + * __tst.wr + * + * __cmp.usq --> __cmp.usq + * __bool + * __tst.wr + * + * __not.wr --> __not.wr + * __bool + * __tst.wr + * + * __not.{w/u}p --> __not.{w/u}p + * __bool + * __tst.wr + * + * __not.{w/u}m symbol --> __not.{w/u}m symbol + * __bool + * __tst.wr + * + * __not.{w/u}s n --> __not.{w/u}s n + * __bool + * __tst.wr + * + * __not.{w/u}ar symbol --> __not.{w/u}ar symbol + * __bool + * __tst.wr + * + * __not.uay symbol --> __not.uay symbol + * __bool + * __tst.wr + * + * __nand.wi i --> __nand.wi i + * __bool + * __tst.wr + * + * __tst.wr --> __tst.wr + * __bool + * __tst.wr + * + * __tst.{w/u}p --> __tst.{w/u}p + * __bool + * __tst.wr + * + * __tst.{w/u}m symbol --> __tst.{w/u}m symbol + * __bool + * __tst.wr + * + * __tst.{w/u}s n --> __tst.{w/u}s n + * __bool + * __tst.wr + * + * __tst.{w/u}ar symbol --> __tst.{w/u}ar symbol + * __bool + * __tst.wr + * + * __tst.uay symbol --> __tst.uay symbol + * __bool + * __tst.wr + * + * __tand.wi i --> __tand.wi i + * __bool + * __tst.wr + * + * Remove redundant __tst.wr in compound conditionals + * that the compiler often generates in testjump() or + * at the end of an "&&" or "||". + */ + else if + ((p[0]->ins_code == I_TST_WR) && + (p[1]->ins_code == I_BOOLEAN) && + (p[2]->ins_code == I_CMP_WT || + p[2]->ins_code == X_CMP_WI || + p[2]->ins_code == X_CMP_WM || + p[2]->ins_code == X_CMP_WS || + p[2]->ins_code == X_CMP_UIQ || + p[2]->ins_code == X_CMP_UMQ || + p[2]->ins_code == X_CMP_USQ || + p[2]->ins_code == I_NOT_WR || + p[2]->ins_code == X_NOT_WP || + p[2]->ins_code == X_NOT_WM || + p[2]->ins_code == X_NOT_WS || + p[2]->ins_code == X_NOT_WAR || + p[2]->ins_code == X_NOT_UP || + p[2]->ins_code == X_NOT_UM || + p[2]->ins_code == X_NOT_US || + p[2]->ins_code == X_NOT_UAR || + p[2]->ins_code == X_NOT_UAY || + p[2]->ins_code == X_NAND_WI || + p[2]->ins_code == I_TST_WR || + p[2]->ins_code == X_TST_WP || + p[2]->ins_code == X_TST_WM || + p[2]->ins_code == X_TST_WS || + p[2]->ins_code == X_TST_WAR || + p[2]->ins_code == X_TST_UP || + p[2]->ins_code == X_TST_UM || + p[2]->ins_code == X_TST_US || + p[2]->ins_code == X_TST_UAR || + p[2]->ins_code == X_TST_UAY || + p[2]->ins_code == X_TAND_WI) + ) { + nb = 2; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + if (q_nb >= 2) { + /* + * __ld.{w/b/u}p --> __tst.{w/u}p + * __tst.wr + * + * __ld.{w/b/u}m symbol --> __tst.{w/u}m symbol + * __tst.wr + * + * __ld.{w/b/u}s n --> __tst.{w/u}s n + * __tst.wr + * + * __ld.{w/b/u}ar symbol --> __tst.{w/u}ar symbol + * __tst.wr + * + * __ld.{b/u}ay symbol --> __tst.uay symbol + * __tst.wr + * + * __and.{w/u}i i --> __tand.wi i + * __tst.wr + * + * __ld.{w/b/u}p --> __not.{w/u}p + * __not.wr + * + * __ld.{w/b/u}m symbol --> __not.{w/u}m symbol + * __not.wr + * + * __ld.{w/b/u}s n --> __not.{w/u}s n + * __not.wr + * + * __ld.{w/b/u}ar symbol --> __not.{w/u}ar symbol + * __not.wr + * + * __ld.{b/u}ay symbol --> __not.uay symbol + * __not.wr + * + * __and.{w/u}i i --> __nand.wi i + * __not.wr + */ + if + ( + (p[0]->ins_code == I_TST_WR || + p[0]->ins_code == I_NOT_WR) && + (p[1]->ins_code == I_LD_WP || + p[1]->ins_code == I_LD_WM || + p[1]->ins_code == X_LD_WS || + p[1]->ins_code == X_LD_WAR || + p[1]->ins_code == I_LD_BP || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == X_LD_BS || + p[1]->ins_code == X_LD_BAR || + p[1]->ins_code == X_LD_BAY || + p[1]->ins_code == I_LD_UP || + p[1]->ins_code == I_LD_UM || + p[1]->ins_code == X_LD_US || + p[1]->ins_code == X_LD_UAR || + p[1]->ins_code == X_LD_UAY || + p[1]->ins_code == I_AND_WI || + p[1]->ins_code == I_AND_UIQ) + ) { + /* remove code */ + if (p[0]->ins_code == I_TST_WR) { + switch (p[1]->ins_code) { + case I_LD_WP: p[1]->ins_code = X_TST_WP; break; + case I_LD_WM: p[1]->ins_code = X_TST_WM; break; + case X_LD_WS: p[1]->ins_code = X_TST_WS; break; + case X_LD_WAR: p[1]->ins_code = X_TST_WAR; break; + case I_LD_BP: + case I_LD_UP: p[1]->ins_code = X_TST_UP; break; + case I_LD_BM: + case I_LD_UM: p[1]->ins_code = X_TST_UM; break; + case X_LD_BS: + case X_LD_US: p[1]->ins_code = X_TST_US; break; + case X_LD_BAR: + case X_LD_UAR: p[1]->ins_code = X_TST_UAR; break; + case X_LD_BAY: + case X_LD_UAY: p[1]->ins_code = X_TST_UAY; break; + case I_AND_UIQ: + case I_AND_WI: p[1]->ins_code = X_TAND_WI; break; + default: abort(); + } + } else { + switch (p[1]->ins_code) { + case I_LD_WP: p[1]->ins_code = X_NOT_WP; break; + case I_LD_WM: p[1]->ins_code = X_NOT_WM; break; + case X_LD_WS: p[1]->ins_code = X_NOT_WS; break; + case X_LD_WAR: p[1]->ins_code = X_NOT_WAR; break; + case I_LD_BP: + case I_LD_UP: p[1]->ins_code = X_NOT_UP; break; + case I_LD_BM: + case I_LD_UM: p[1]->ins_code = X_NOT_UM; break; + case X_LD_BS: + case X_LD_US: p[1]->ins_code = X_NOT_US; break; + case X_LD_BAR: + case X_LD_UAR: p[1]->ins_code = X_NOT_UAR; break; + case X_LD_BAY: + case X_LD_UAY: p[1]->ins_code = X_NOT_UAY; break; + case I_AND_UIQ: + case I_AND_WI: p[1]->ins_code = X_NAND_WI; break; + default: abort(); + } + } + nb = 1; + } + + /* + * __ld.u{p/m/s/ar/ay} symbol --> __ld.u{p/m/s/ar/ay} symbol + * __cmp_w.wi j __cmp_b.uiq j + * + * __and.uiq i --> __and.uiq i + * __cmp_w.wi j __cmp_b.uiq j + * + * C promotes an unsigned char to a signed int so this + * must be done in the peephole, not the compiler. + */ + else if + ((p[0]->ins_code == X_CMP_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data >= 0) && + (p[0]->ins_data <= 255) && + (is_ubyte(p[1])) + ) { + /* replace code */ + p[0]->ins_code = X_CMP_UIQ; + p[0]->cmp_type = compare2uchar[p[0]->cmp_type]; + /* no instructions removed, just loop */ + goto lv1_loop; + } + + /* + * __bool --> LLnn: + * LLnn: __bool + * + * Delay boolean conversion until the end of the list of labels + * that are generated when using multiple "&&" and "||". + * + * N.B. This optimization should be done before the X_TST_WM optimization! + */ + else if + ((p[0]->ins_code == I_LABEL) && + (p[1]->ins_code == I_BOOLEAN) + ) { + *p[1] = *p[0]; + p[0]->ins_code = I_BOOLEAN; + p[0]->ins_type = 0; + p[0]->ins_data = 0; + /* no instructions removed, just loop */ + goto lv1_loop; + } + + /* + * __bool --> __bool + * __bool + * + * Remove redundant conversions of a flag into a boolean + * that are generated when using multiple "&&" and "||". + * + * N.B. This optimization should be done before the X_TST_WM optimization! + */ + else if + ((p[1]->ins_code == I_BOOLEAN) && + (p[0]->ins_code == I_BOOLEAN) + ) { + *p[1] = *p[0]; + nb = 1; + } + + /* + * __bra LLaa --> __bra LLaa + * __bra LLbb + */ + else if + ((p[0]->ins_code == I_BRA) && + (p[1]->ins_code == I_BRA) + ) { + nb = 1; + } + + /* + * LLaa: LLaa .alias LLbb + * __bra LLbb --> __bra LLbb + */ + else if + ((p[0]->ins_code == I_BRA) && + (p[1]->ins_code == I_LABEL) + ) { + int i = 1; + do { + if (p[i]->ins_data != p[0]->ins_data) { + p[i]->ins_code = I_ALIAS; + p[i]->imm_type = T_VALUE; + p[i]->imm_data = p[0]->ins_data; + } + } while (++i < q_nb && i < 10 && p[i]->ins_code == I_LABEL); + } + + /* + * __bra LLaa --> LLaa: + * LLaa: + */ + else if + ((p[0]->ins_code == I_LABEL) && + (p[1]->ins_code == I_BRA) && + (p[1]->ins_type == T_LABEL) && + (p[0]->ins_data == p[1]->ins_data) + ) { + *p[1] = *p[0]; + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* 4-instruction patterns */ + /* ********************************************************* */ + + if (q_nb >= 4) { + /* __ld.wi i --> __ld.wi i + * __push.wr __push.wr + * __st.wm __ptr __ld.{w/u}m i + * __ld.{w/u}p __ptr + * + * Load a variable from memory, this is generated for + * code like a "+=", where the store can be optimized + * later on. + */ + if + ((p[0]->ins_code == I_LD_WP || + p[0]->ins_code == I_LD_BP || + p[0]->ins_code == I_LD_UP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == I_PUSH_WR) && + (p[3]->ins_code == I_LD_WI) + ) { + /* replace code */ + *p[1] = *p[3]; + if (p[0]->ins_code == I_LD_WP) + p[1]->ins_code = I_LD_WM; + else + if (p[0]->ins_code == I_LD_BP) + p[1]->ins_code = I_LD_BM; + else + p[1]->ins_code = I_LD_UM; + nb = 1; + } + + /* + * __lea.s i --> __lea.s i + * __push.wr __push.wr + * __st.wm __ptr __ld.{w/b/u}s (i + 2) + * __ld.{w/b/u}p __ptr + * + * Load a variable from memory, this is generated for + * code like a "+=", where the store can be optimized + * later on. + */ + else if + ((p[0]->ins_code == I_LD_WP || + p[0]->ins_code == I_LD_BP || + p[0]->ins_code == I_LD_UP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == I_PUSH_WR) && + (p[3]->ins_code == I_LEA_S) + ) { + /* replace code */ + *p[1] = *p[3]; + if (p[0]->ins_code == I_LD_WP) + p[1]->ins_code = X_LD_WS; + else + if (p[0]->ins_code == I_LD_BP) + p[1]->ins_code = X_LD_BS; + else + p[1]->ins_code = X_LD_US; + p[1]->ins_data += 2; + nb = 1; + } + + /* + * __lea.s i --> __lea.s (i + j) + * __push.wr + * __ld.wi j + * __add.wt + * + * This is generated for address calculations into local + * arrays and structs on the stack. + */ + else if + ((p[0]->ins_code == I_ADD_WT) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) && + (p[2]->ins_code == I_PUSH_WR) && + (p[3]->ins_code == I_LEA_S) + ) { + /* replace code */ + p[3]->ins_code = I_LEA_S; + p[3]->ins_data += p[1]->ins_data; + nb = 3; + } + +#if OPT_ARRAY_RD + /* + * __asl.wr --> __ld.war array + * __add.wi array + * __st.wm _ptr + * __ld.wp _ptr + * + * Classic base+offset word-array read. + * + * N.B. The byte-array peephole rule is further down in this file. + */ + else if + ((p[0]->ins_code == I_LD_WP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == I_ADD_WI) && + (p[2]->ins_type == T_SYMBOL) && + (is_small_array((SYMBOL *)p[2]->ins_data)) && + (p[3]->ins_code == I_ASL_WR) + ) { + /* replace code */ + p[3]->ins_code = X_LD_WAR; + p[3]->ins_type = T_SYMBOL; + p[3]->ins_data = p[2]->ins_data; + nb = 3; + } +#endif + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* 3-instruction patterns */ + /* ********************************************************* */ + + if (q_nb >= 3) { + /* + * __case --> LLnn: + * __endcase + * LLnn: + * + * I_ENDCASE is only generated in order to catch which + * case statements could fall through to the next case + * so that an SAX instruction could be generated if or + * when do_switch() uses a "JMP [table, x]". + * + * This removes redundant I_CASE/I_ENDCASE i-codes that + * just fall through to the next case. + */ + if + ((p[0]->ins_code == I_LABEL) && + (p[1]->ins_code == I_ENDCASE) && + (p[2]->ins_code == I_CASE) + ) { + /* remove code */ + *p[2] = *p[0]; + nb = 2; + } + + /* __ld.wi i --> __ld.{w/b/u}m i + * __st.wm __ptr + * __ld.{w/b/u}p __ptr + * + * Load a global/static variable from memory + */ + else if + ((p[0]->ins_code == I_LD_WP || + p[0]->ins_code == I_LD_BP || + p[0]->ins_code == I_LD_UP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == I_LD_WI) + ) { + /* replace code */ + if (p[0]->ins_code == I_LD_WP) + p[2]->ins_code = I_LD_WM; + else + if (p[0]->ins_code == I_LD_BP) + p[2]->ins_code = I_LD_BM; + else + p[2]->ins_code = I_LD_UM; + nb = 2; + } + + /* + * __lea.s i --> __ld.{w/b/u}s i + * __st.wm __ptr + * __ld.{w/b/u}p __ptr + * + * Load a local variable from memory + */ + else if + ((p[0]->ins_code == I_LD_WP || + p[0]->ins_code == I_LD_BP || + p[0]->ins_code == I_LD_UP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == I_LEA_S) + ) { + /* replace code */ + if (p[0]->ins_code == I_LD_WP) + p[2]->ins_code = X_LD_WS; + else + if (p[0]->ins_code == I_LD_BP) + p[2]->ins_code = X_LD_BS; + else + p[2]->ins_code = X_LD_US; + nb = 2; + } + + /* + * __push.wr --> __add.wm symbol + * __ld.wm symbol + * __add.wt + * + * __push.wr --> __sub.wm symbol + * __ld.wm symbol + * __sub.wt + * + * etc/etc + */ + else if + ((p[0]->ins_code == I_ADD_WT || + p[0]->ins_code == I_SUB_WT || + p[0]->ins_code == I_AND_WT || + p[0]->ins_code == I_EOR_WT || + p[0]->ins_code == I_OR_WT) && + (p[1]->ins_code == I_LD_WM) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + *p[2] = *p[1]; + switch (p[0]->ins_code) { + case I_ADD_WT: p[2]->ins_code = I_ADD_WM; break; + case I_SUB_WT: p[2]->ins_code = I_SUB_WM; break; + case I_AND_WT: p[2]->ins_code = I_AND_WM; break; + case I_EOR_WT: p[2]->ins_code = I_EOR_WM; break; + case I_OR_WT: p[2]->ins_code = I_OR_WM; break; + default: abort(); + } + nb = 2; + } + + /* + * __push.wr --> __add.um symbol + * __ld.um symbol + * __add.wt + * + * __push.wr --> __sub.um symbol + * __ld.um symbol + * __sub.wt + * + * etc/etc + */ + else if + ((p[0]->ins_code == I_ADD_WT || + p[0]->ins_code == I_SUB_WT || + p[0]->ins_code == I_AND_WT || + p[0]->ins_code == I_EOR_WT || + p[0]->ins_code == I_OR_WT) && + (p[1]->ins_code == I_LD_UM) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + *p[2] = *p[1]; + switch (p[0]->ins_code) { + case I_ADD_WT: p[2]->ins_code = I_ADD_UM; break; + case I_SUB_WT: p[2]->ins_code = I_SUB_UM; break; + case I_AND_WT: p[2]->ins_code = I_AND_UM; break; + case I_EOR_WT: p[2]->ins_code = I_EOR_UM; break; + case I_OR_WT: p[2]->ins_code = I_OR_UM; break; + default: abort(); + } + nb = 2; + } + + /* + * __push.wr --> __add.ws (i - 2) + * __ld.ws i + * __add.wt + */ + else if + ((p[0]->ins_code == I_ADD_WT) && + (p[1]->ins_code == X_LD_WS || + p[1]->ins_code == X_LD_US) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + *p[2] = *p[1]; + switch (p[1]->ins_code) { + case X_LD_WS: p[2]->ins_code = X_ADD_WS; break; + case X_LD_US: p[2]->ins_code = X_ADD_US; break; + default: abort(); + } + p[2]->ins_data -= 2; + nb = 2; + } + + /* + * __ld{w/b/u}m symbol --> __incld.{w/b/u}m symbol + * __add.wi 1 + * __st.{w/u}m symbol + * + * __ld{w/b/u} symbol --> __decld.{w/b/u}m symbol + * __sub.wi 1 + * __st.{w/u}m symbol + * + * pre-increment, post-increment, + * pre-decrement, post-decrement! + */ + else if + ((p[1]->ins_code == I_ADD_WI || + p[1]->ins_code == I_SUB_WI) && + (p[1]->ins_type == T_VALUE) && + (p[1]->ins_data == 1) && + (p[0]->ins_code == I_ST_WM || + p[0]->ins_code == I_ST_UM) && + (p[2]->ins_code == I_LD_WM || + p[2]->ins_code == I_LD_BM || + p[2]->ins_code == I_LD_UM) && + (p[0]->ins_type == p[2]->ins_type) && + (p[0]->ins_data == p[2]->ins_data) +// (cmp_operands(p[0], p[2]) == 1) + ) { + /* replace code */ + switch (p[2]->ins_code) { + case I_LD_WM: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_WM : X_DECLD_WM; break; + case I_LD_BM: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_BM : X_DECLD_BM; break; + case I_LD_UM: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_UM : X_DECLD_UM; break; + default: break; + } + nb = 2; + } + + /* + * __ld{w/b/u}s symbol --> __incld.{w/b/u}s symbol + * __add.wi 1 + * __st.{w/u}s symbol + * + * __ld{w/b/u}s symbol --> __decld.{w/b/u}s symbol + * __sub.wi 1 + * __st.{w/u}s symbol + * + * C pre-increment, post-increment, + * C pre-decrement, post-decrement! + */ + else if + ((p[1]->ins_code == I_ADD_WI || + p[1]->ins_code == I_SUB_WI) && + (p[1]->ins_type == T_VALUE) && + (p[1]->ins_data == 1) && + (p[0]->ins_code == X_ST_WS || + p[0]->ins_code == X_ST_US) && + (p[2]->ins_code == X_LD_WS || + p[2]->ins_code == X_LD_BS || + p[2]->ins_code == X_LD_US) && + (p[0]->ins_type == p[2]->ins_type) && + (p[0]->ins_data == p[2]->ins_data) + ) { + /* replace code */ + switch (p[2]->ins_code) { + case X_LD_WS: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_WS : X_DECLD_WS; break; + case X_LD_BS: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_BS : X_DECLD_BS; break; + case X_LD_US: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_US : X_DECLD_US; break; + default: break; + } + nb = 2; + } + + /* + * __ldp.{w/b/u}ar symbol --> __incld_{w/b/u}ar symbol + * __add.wi 1 + * __st.{w/u}at symbol + * + * __ldp.{w/b/u}ar symbol --> __decld_{w/b/u}ar symbol + * __sub.wi 1 + * __st.{w/u}at symbol + * + * __ldp.{b/u}ay symbol --> __incld_{b/u}ay symbol + * __add.wi 1 + * __st.{w/u}at symbol + * + * __ldp.{b/u}ay symbol --> __decld_{b/u}ay symbol + * __sub.wi 1 + * __st.{w/u}at symbol + * + * pre-increment, post-increment, + * pre-decrement, post-decrement! + */ + else if + ((p[1]->ins_code == I_ADD_WI || + p[1]->ins_code == I_SUB_WI) && + (p[1]->ins_type == T_VALUE) && + (p[1]->ins_data == 1) && + (p[0]->ins_code == X_ST_WAT || + p[0]->ins_code == X_ST_UAT) && + (p[2]->ins_code == X_LDP_WAR || + p[2]->ins_code == X_LDP_BAR || + p[2]->ins_code == X_LDP_UAR || + p[2]->ins_code == X_LDP_BAY || + p[2]->ins_code == X_LDP_UAY) && + (p[0]->ins_type == p[2]->ins_type) && + (p[0]->ins_data == p[2]->ins_data) +// (cmp_operands(p[0], p[2]) == 1) + ) { + /* replace code */ + switch (p[2]->ins_code) { + case X_LDP_WAR: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_WAR : X_DECLD_WAR; break; + case X_LDP_BAR: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_BAR : X_DECLD_BAR; break; + case X_LDP_UAR: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_UAR : X_DECLD_UAR; break; + case X_LDP_BAY: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_BAY : X_DECLD_BAY; break; + case X_LDP_UAY: p[2]->ins_code = (p[1]->ins_code == I_ADD_WI) ? X_INCLD_UAY : X_DECLD_UAY; break; + default: break; + } + nb = 2; + } + +#if OPT_ARRAY_RD + /* + * __add.wi array --> __ld.{b/u}ar array + * __st.wm _ptr + * __ld.{b/u}p _ptr + * + * Classic base+offset byte-array read. + * + * N.B. The word-array peephole rule is further up in this file. + */ + else if + ((p[0]->ins_code == I_LD_BP || + p[0]->ins_code == I_LD_UP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == I_ADD_WI) && + (p[2]->ins_type == T_SYMBOL) && + (is_small_array((SYMBOL *)p[2]->ins_data)) + ) { + /* replace code */ + p[2]->ins_code = (p[0]->ins_code == I_LD_BP) ? X_LD_BAR : X_LD_UAR; + nb = 2; + } +#endif + +#if OPT_ARRAY_WR + /* + * __index.{w/u}r array --> __ldp.{w/b/u}ar array + * __st.wm _ptr + * __ld.{w/b/u}p _ptr + * + * Optimized base+offset array write. + * + * This MUST be enabled when the X_INDEX_WR / X_INDEX_UR + * optimization is enabled, or array loads break because + * the index is put into __ptr instead of an address! + */ + else if + ((p[0]->ins_code == I_LD_WP || + p[0]->ins_code == I_LD_BP || + p[0]->ins_code == I_LD_UP) && + (p[0]->ins_type == T_PTR) && + (p[1]->ins_code == I_ST_WM) && + (p[1]->ins_type == T_PTR) && + (p[2]->ins_code == X_INDEX_WR || + p[2]->ins_code == X_INDEX_UR) + ) { + /* replace code */ + if (p[0]->ins_code == I_LD_WP) + p[2]->ins_code = X_LDP_WAR; + else + p[2]->ins_code = (p[0]->ins_code == I_LD_BP) ? X_LDP_BAR : X_LDP_UAR; + nb = 2; + } +#endif + + /* + * __not.wr --> __boolnot.wr + * __bool is_usepr() + * is_usepr() + * + * __not.{w/u}p --> __boolnot.{w/u}p + * __bool is_usepr() + * is_usepr() + * + * __not.{w/u}m symbol --> __boolnot.{w/u}m symbol + * __bool is_usepr() + * is_usepr() + * + * __not.{w/u}s n --> __boolnot.{w/u}s n + * __bool is_usepr() + * is_usepr() + * + * __not.{w/u}ar symbol --> __boolnot.{w/u}ar symbol + * __bool is_usepr() + * is_usepr() + * + * __not.uay symbol --> __boolnot.uay symbol + * __bool is_usepr() + * is_usepr() + * + * Optimize "var = !var" which doesn't need to set the flags. + * + * N.B. This MUST be done after the rule for merging two "!" because + * I_NOT_WR is included in the is_usepr() test! + */ + else if + ((is_usepr(p[0])) && + (p[1]->ins_code == I_BOOLEAN) && + (p[2]->ins_code == I_NOT_WR || + p[2]->ins_code == X_NOT_WP || + p[2]->ins_code == X_NOT_WM || + p[2]->ins_code == X_NOT_WS || + p[2]->ins_code == X_NOT_WAR || + p[2]->ins_code == X_NOT_UP || + p[2]->ins_code == X_NOT_UM || + p[2]->ins_code == X_NOT_US || + p[2]->ins_code == X_NOT_UAR || + p[2]->ins_code == X_NOT_UAY) + ) { + /* replace code */ + *p[1] = *p[0]; + switch (p[2]->ins_code) { + case I_NOT_WR: p[2]->ins_code = X_BOOLNOT_WR; break; + case X_NOT_WP: p[2]->ins_code = X_BOOLNOT_WP; break; + case X_NOT_WM: p[2]->ins_code = X_BOOLNOT_WM; break; + case X_NOT_WS: p[2]->ins_code = X_BOOLNOT_WS; break; + case X_NOT_WAR: p[2]->ins_code = X_BOOLNOT_WAR; break; + case X_NOT_UP: p[2]->ins_code = X_BOOLNOT_UP; break; + case X_NOT_UM: p[2]->ins_code = X_BOOLNOT_UM; break; + case X_NOT_US: p[2]->ins_code = X_BOOLNOT_US; break; + case X_NOT_UAR: p[2]->ins_code = X_BOOLNOT_UAR; break; + case X_NOT_UAY: p[2]->ins_code = X_BOOLNOT_UAY; break; + default: abort(); + } + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* 2-instruction patterns */ + /* ********************************************************* */ + + if (q_nb >= 2) { + /* + * __ld.{b/u}p __ptr --> __ld.{b/u}p __ptr + * __switch.wr __switch.ur + * + * __ld.{b/u}m symbol --> __ld.{b/u}m symbol + * __switch.wr __switch.ur + * + * __ld.{b/u}s n --> __ld.{b/u}s n + * __switch.wr __switch.ur + * + * __ld.{b/u}ar array --> __ld.{b/u}ar array + * __switch.wr __switch.ur + */ + if + ((p[0]->ins_code == I_SWITCH_WR) && + (p[1]->ins_code == I_LD_BP || + p[1]->ins_code == I_LD_UP || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == I_LD_UM || + p[1]->ins_code == X_LD_BS || + p[1]->ins_code == X_LD_US || + p[1]->ins_code == X_LD_BAR || + p[1]->ins_code == X_LD_UAR) + ) { + /* optimize code */ + p[0]->ins_code = I_SWITCH_UR; + nb = 0; + } + + /* + * __switch.{w/u}r --> __switch.{w/u}rw + * __endcase + * + * __bra LLnn --> __bra LLnn + * __endcase + * + * I_ENDCASE is only generated in order to catch which + * case statements could fall through to the next case + * so that an SAX instruction could be inserted, which + * is only needed *IF* "doswitch" uses "JMP table, x". + * + * This removes obviously-redundant I_ENDCASE i-codes. + */ + else if + ((p[0]->ins_code == I_ENDCASE) && + (p[1]->ins_code == I_SWITCH_WR || + p[1]->ins_code == I_SWITCH_UR || + p[1]->ins_code == I_BRA) + ) { + /* remove code */ + nb = 1; + } + + /* + * __modsp i --> __modsp (i + j) + * __modsp j + */ + else if + ((p[0]->ins_code == I_MODSP) && + (p[1]->ins_code == I_MODSP) && + + (p[0]->ins_type == T_STACK) && + (p[1]->ins_type == T_STACK) + ) { + /* replace code */ + p[1]->ins_data += p[0]->ins_data; + nb = 1; + } + + /* + * __lea.s i --> __lea.s (i + j) + * __add.wi j + * + * This is generated for address calculations into local + * arrays and structs on the stack. + */ + else if + ((p[0]->ins_code == I_ADD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_LEA_S) + ) { + /* replace code */ + p[1]->ins_code = I_LEA_S; + p[1]->ins_data += p[0]->ins_data; + nb = 1; + } + + /* + * __add.wi i --> __add.wi (i + j) + * __add.wi j + */ + else if + ((p[0]->ins_code == I_ADD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_code == I_ADD_WI) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + p[1]->ins_data += p[0]->ins_data; + nb = 1; + } + + /* + * __asl.wi i --> __asl.wi (i+1) + * __asl.wr + * + * __asl.wi i --> __asl.wi (i+j) + * __asl.wi j + * + * __asl.wr --> __asl.wi (1+j) + * __asl.wi j + * + * __asl.wr --> __asl.wi (1+1) + * __asl.wr + * + * sometimes generated for the address within an array of structs + */ + else if + ((p[0]->ins_code == I_ASL_WR || + p[0]->ins_code == I_ASL_WI) && + (p[1]->ins_code == I_ASL_WR || + p[1]->ins_code == I_ASL_WI) + ) { + /* replace code */ + intptr_t data = 0; + data += (p[0]->ins_code == I_ASL_WR) ? 1 : p[0]->ins_data; + data += (p[1]->ins_code == I_ASL_WR) ? 1 : p[1]->ins_data; + p[1]->ins_code = I_ASL_WI; + p[1]->ins_type = T_VALUE; + p[1]->ins_data = data; + nb = 1; + } + + /* + * __ld.wi symbol --> __ld.wi (symbol + j) + * __add.wi j + * + * __add.wi symbol --> __add.wi (symbol + j) + * __add.wi j + */ + else if + ((p[0]->ins_code == I_ADD_WI) && + (p[1]->ins_code == I_LD_WI || + p[1]->ins_code == I_ADD_WI) && + + (p[0]->ins_type == T_VALUE) && + (p[1]->ins_type == T_SYMBOL) + ) { + /* replace code */ + if (p[0]->ins_data != 0) { + SYMBOL * oldsym = (SYMBOL *)p[1]->ins_data; + SYMBOL * newsym = copysym(oldsym); + if (NAMEALLOC <= + snprintf(newsym->name, NAMEALLOC, "%s + %ld", oldsym->name, (long) p[0]->ins_data)) + error("optimized symbol+offset name too long"); + p[1]->ins_type = T_SYMBOL; + p[1]->ins_data = (intptr_t)newsym; + } + nb = 1; + } + + /* + * __ld.wi j --> __ld.wi (symbol + j) + * __add.wi symbol + */ + else if + ((p[0]->ins_code == I_ADD_WI) && + (p[1]->ins_code == I_LD_WI) && + + (p[0]->ins_type == T_SYMBOL) && + (p[1]->ins_type == T_VALUE) + ) { + /* replace code */ + if (p[1]->ins_data != 0) { + SYMBOL * oldsym = (SYMBOL *)p[0]->ins_data; + SYMBOL * newsym = copysym(oldsym); + if (NAMEALLOC <= + snprintf(newsym->name, NAMEALLOC, "%s + %ld", oldsym->name, (long) p[1]->ins_data)) + error("optimized symbol+offset name too long"); + p[1]->ins_type = T_SYMBOL; + p[1]->ins_data = (intptr_t)newsym; + } else { + *p[1] = *p[0]; + p[1]->ins_code = I_LD_WI; + } + nb = 1; + } + + /* + * __st.wm a --> __st.wm a + * __ld.wm a + */ + else if + ((p[0]->ins_code == I_LD_WM) && + (p[1]->ins_code == I_ST_WM) && + (cmp_operands(p[0], p[1]) == 1) + ) { + /* remove code */ + nb = 1; + } + + /* + * __st.ws i --> __st.ws i + * __ld.ws i + */ + else if + ((p[0]->ins_code == X_LD_WS) && + (p[1]->ins_code == X_ST_WS) && + (p[0]->ins_data == p[1]->ins_data)) { + /* remove code */ + nb = 1; + } + + /* + * __st.us i --> __st.us i + * __ld.us i + */ + else if + ((p[0]->ins_code == X_LD_BS || + p[0]->ins_code == X_LD_US) && + (p[1]->ins_code == X_ST_US) && + (p[0]->ins_data == p[1]->ins_data) + ) { + if (p[0]->ins_code == X_LD_BS) + p[0]->ins_code = I_EXT_BR; + else + p[0]->ins_code = I_EXT_UR; + p[0]->ins_data = p[0]->ins_type = 0; + } + + /* + * __ld.wm a (or __ld.wi a) --> __ld.wm b (or __ld.wi b) + * __ld.wm b (or __ld.wi b) + * + * JCB: Orphaned load, does this really happen? + */ + else if + ((p[0]->ins_code == I_LD_WM || + p[0]->ins_code == I_LD_WI || + p[0]->ins_code == X_LD_WS || + p[0]->ins_code == I_LEA_S || + p[0]->ins_code == I_LD_BM || + p[0]->ins_code == I_LD_BP || + p[0]->ins_code == X_LD_BS || + p[0]->ins_code == I_LD_UM || + p[0]->ins_code == I_LD_UP || + p[0]->ins_code == X_LD_US) && + (p[1]->ins_code == I_LD_WM || + p[1]->ins_code == I_LD_WI || + p[1]->ins_code == X_LD_WS || + p[1]->ins_code == I_LEA_S || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == I_LD_BP || + p[1]->ins_code == X_LD_BS || + p[1]->ins_code == I_LD_UM || + p[1]->ins_code == I_LD_UP || + p[1]->ins_code == X_LD_US) + ) { + /* remove code */ + *p[1] = *p[0]; + nb = 1; + } + + /* + * __decld.{w/b/u}m symbol --> __lddec.{w/b/u}m symbol + * __add.wi 1 + * + * __decld.{w/b/u}s n --> __lddec.{w/b/u}s n + * __add.wi 1 + * + * __decld.{w/b/u}ar array --> __lddec.{w/b/u}ar array + * __add.wi 1 + * + * __decld.{b/u}ay array --> __lddec.{b/u}ay array + * __add.wi 1 + * + * C post-decrement! + */ + else if + ((p[0]->ins_code == I_ADD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data == 1) && + (p[1]->ins_code == X_DECLD_WM || + p[1]->ins_code == X_DECLD_BM || + p[1]->ins_code == X_DECLD_UM || + p[1]->ins_code == X_DECLD_WS || + p[1]->ins_code == X_DECLD_BS || + p[1]->ins_code == X_DECLD_US || + p[1]->ins_code == X_DECLD_WAR || + p[1]->ins_code == X_DECLD_BAR || + p[1]->ins_code == X_DECLD_UAR || + p[1]->ins_code == X_DECLD_BAY || + p[1]->ins_code == X_DECLD_UAY) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case X_DECLD_WM: p[1]->ins_code = X_LDDEC_WM; break; + case X_DECLD_BM: p[1]->ins_code = X_LDDEC_BM; break; + case X_DECLD_UM: p[1]->ins_code = X_LDDEC_UM; break; + case X_DECLD_WS: p[1]->ins_code = X_LDDEC_WS; break; + case X_DECLD_BS: p[1]->ins_code = X_LDDEC_BS; break; + case X_DECLD_US: p[1]->ins_code = X_LDDEC_US; break; + case X_DECLD_WAR: p[1]->ins_code = X_LDDEC_WAR; break; + case X_DECLD_BAR: p[1]->ins_code = X_LDDEC_BAR; break; + case X_DECLD_UAR: p[1]->ins_code = X_LDDEC_UAR; break; + case X_DECLD_BAY: p[1]->ins_code = X_LDDEC_BAY; break; + case X_DECLD_UAY: p[1]->ins_code = X_LDDEC_UAY; break; + default: break; + } + nb = 1; + } + + /* + * __incld.{w/b/u}m symbol --> __ldinc.{w/b/u}m symbol + * __sub.wi 1 + * + * __incld.{w/b/u}s n --> __ldinc.{w/b/u}s n + * __sub.wi 1 + * + * __incld.{w/b/u}ar array --> __ldinc.{w/b/u}ar array + * __sub.wi 1 + * + * __incld.{w/b/u}ay array --> __ldinc.{w/b/u}ay array + * __sub.wi 1 + * + * C post-increment! + */ + else if + ((p[0]->ins_code == I_SUB_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data == 1) && + (p[1]->ins_code == X_INCLD_WM || + p[1]->ins_code == X_INCLD_BM || + p[1]->ins_code == X_INCLD_UM || + p[1]->ins_code == X_INCLD_WS || + p[1]->ins_code == X_INCLD_BS || + p[1]->ins_code == X_INCLD_US || + p[1]->ins_code == X_INCLD_WAR || + p[1]->ins_code == X_INCLD_BAR || + p[1]->ins_code == X_INCLD_UAR || + p[1]->ins_code == X_INCLD_BAY || + p[1]->ins_code == X_INCLD_UAY) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case X_INCLD_WM: p[1]->ins_code = X_LDINC_WM; break; + case X_INCLD_BM: p[1]->ins_code = X_LDINC_BM; break; + case X_INCLD_UM: p[1]->ins_code = X_LDINC_UM; break; + case X_INCLD_WS: p[1]->ins_code = X_LDINC_WS; break; + case X_INCLD_BS: p[1]->ins_code = X_LDINC_BS; break; + case X_INCLD_US: p[1]->ins_code = X_LDINC_US; break; + case X_INCLD_WAR: p[1]->ins_code = X_LDINC_WAR; break; + case X_INCLD_BAR: p[1]->ins_code = X_LDINC_BAR; break; + case X_INCLD_UAR: p[1]->ins_code = X_LDINC_UAR; break; + case X_INCLD_BAY: p[1]->ins_code = X_LDINC_BAY; break; + case X_INCLD_UAY: p[1]->ins_code = X_LDINC_UAY; break; + default: break; + } + nb = 1; + } + + /* + * __ld.{w/b/u}m symbol --> __ld.{w/b/u}mq symbol + * __index.wr array __index.wr array + * + * __ld.{w/b/u}m symbol --> __ld.{w/b/u}mq symbol + * __index.ur array __index.ur array + * + * __ld.{w/b/u}m symbol --> __ld.{w/b/u}mq symbol + * __ld.war array __ld.war array + * + * + * __ld.{w/b/u}s n --> __ld.{w/b/u}sq n + * __index.wr array __index.wr array + * + * __ld.{w/b/u}s n --> __ld.{w/b/u}sq n + * __index.ur array __index.ur array + * + * __ld.{w/b/u}s n --> __ld.{w/b/u}sq n + * __ld.war array __ld.war array + * + * Index optimizations for base+offset array access. + */ + else if + ((p[0]->ins_code == X_INDEX_WR || + p[0]->ins_code == X_INDEX_UR || + p[0]->ins_code == X_LD_WAR) && + (p[1]->ins_code == I_LD_WM || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == I_LD_UM || + p[1]->ins_code == X_LD_WS || + p[1]->ins_code == X_LD_BS || + p[1]->ins_code == X_LD_US) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case I_LD_WM: p[1]->ins_code = I_LD_WMQ; break; + case I_LD_BM: p[1]->ins_code = I_LD_BMQ; break; + case I_LD_UM: p[1]->ins_code = I_LD_UMQ; break; + case X_LD_WS: p[1]->ins_code = X_LD_WSQ; break; + case X_LD_BS: p[1]->ins_code = X_LD_BSQ; break; + case X_LD_US: p[1]->ins_code = X_LD_USQ; break; + default: break; + } + nb = 0; + } + + /* + * __ld.{w/b/u}m symbol --> __ldy.{w/b/u}mq + * __ld.{b/u}ar array __ld.{b/u}ay array + * + * __ld.{w/b/u}s n --> __ldy.{w/b/u}sq n + * __ld.{b/u}ar array __ld.{b/u}ay array + * + * Index optimizations for base+offset array access. + */ + else if + ((p[0]->ins_code == X_LD_BAR || + p[0]->ins_code == X_LD_UAR) && + (p[1]->ins_code == I_LD_WM || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == I_LD_UM || + p[1]->ins_code == X_LD_WS || + p[1]->ins_code == X_LD_BS || + p[1]->ins_code == X_LD_US) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case I_LD_WM: p[1]->ins_code = I_LDY_WMQ; break; + case I_LD_BM: p[1]->ins_code = I_LDY_BMQ; break; + case I_LD_UM: p[1]->ins_code = I_LDY_UMQ; break; + case X_LD_WS: p[1]->ins_code = X_LDY_WSQ; break; + case X_LD_BS: p[1]->ins_code = X_LDY_BSQ; break; + case X_LD_US: p[1]->ins_code = X_LDY_USQ; break; + default: break; + } + switch (p[0]->ins_code) { + case X_LD_BAR: p[0]->ins_code = X_LD_BAY; break; + case X_LD_UAR: p[0]->ins_code = X_LD_UAY; break; + case X_LDP_BAR: p[0]->ins_code = X_LDP_BAY; break; + case X_LDP_UAR: p[0]->ins_code = X_LDP_UAY; break; + default: break; + } + nb = 0; + } + + /* + * __ld.{w/b/u}mq symbol --> __ldy.{w/b/u}mq + * __ldp.{b/u}ar array __ldp.{b/u}ay array + * + * __ld.{w/b/u}sq n --> __ldy.{w/b/u}sq n + * __ldp.{b/u}ar array __ldp.{b/u}ay array + * + * Index optimizations for base+offset array access. + * + * The X_INDEX_UR rule above already converted __ld.{w/b/u}m + * to __ld.{w/b/u}mq! + */ + else if + ((p[0]->ins_code == X_LDP_BAR || + p[0]->ins_code == X_LDP_UAR) && + (p[1]->ins_code == I_LD_WMQ || + p[1]->ins_code == I_LD_BMQ || + p[1]->ins_code == I_LD_UMQ || + p[1]->ins_code == X_LD_WSQ || + p[1]->ins_code == X_LD_BSQ || + p[1]->ins_code == X_LD_USQ) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case I_LD_WMQ: p[1]->ins_code = I_LDY_WMQ; break; + case I_LD_BMQ: p[1]->ins_code = I_LDY_BMQ; break; + case I_LD_UMQ: p[1]->ins_code = I_LDY_UMQ; break; + case X_LD_WSQ: p[1]->ins_code = X_LDY_WSQ; break; + case X_LD_BSQ: p[1]->ins_code = X_LDY_BSQ; break; + case X_LD_USQ: p[1]->ins_code = X_LDY_USQ; break; + default: break; + } + switch (p[0]->ins_code) { + case X_LD_BAR: p[0]->ins_code = X_LD_BAY; break; + case X_LD_UAR: p[0]->ins_code = X_LD_UAY; break; + case X_LDP_BAR: p[0]->ins_code = X_LDP_BAY; break; + case X_LDP_UAR: p[0]->ins_code = X_LDP_UAY; break; + default: break; + } + nb = 0; + } + + /* + * __ld.u{p/m/s/ar/ay} symbol --> __ld.u{p/m/s/ar/ay} symbol + * __sdiv.wi i __udiv.wi i + * + * __ld.u{p/m/s/ar/ay} symbol --> __ld.u{p/m/s/ar/ay} symbol + * __smod.wi i __umod.wi i + * + * C promotes an unsigned char to a signed int so this + * must be done in the peephole, not the compiler. + */ + else if + ((p[0]->ins_code == I_SDIV_WI || + p[0]->ins_code == I_SMOD_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data >= 0) && + (is_ubyte(p[1])) + ) { + /* replace code */ + if (p[0]->ins_code == I_SDIV_WI) + p[0]->ins_code = (p[0]->ins_data < 256) ? I_UDIV_UI : I_UDIV_WI; + else + p[0]->ins_code = (p[0]->ins_data < 256) ? I_UMOD_UI : I_UMOD_WI; + /* no instructions removed, just loop */ + goto lv1_loop; + } + + /* + * __ld.u{p/m/s/ar/ay} symbol --> __ld.u{p/m/s/ar/ay} symbol + * __asr.wi i __lsr.uiq i + * + * __ld.u{p/m/s/ar/ay} symbol --> __ld.u{p/m/s/ar/ay} symbol + * __lsr.wi i __lsr.uiq i + * + * C promotes an unsigned char to a signed int so this + * must be done in the peephole, not the compiler. + */ + else if + ((p[0]->ins_code == I_ASR_WI || + p[0]->ins_code == I_LSR_WI) && + (p[0]->ins_type == T_VALUE) && + (is_ubyte(p[1])) + ) { + /* replace code */ + if (p[0]->ins_data >= 8) { + p[1]->ins_code = I_LD_WI; + p[1]->ins_type = T_VALUE; + p[1]->ins_data = 0; + nb = 1; + } else { + p[0]->ins_code = I_LSR_UIQ; + /* no instructions removed, just loop */ + goto lv1_loop; + } + } + + /* + * __ld.u{p/m/s/ar/ay} symbol --> __ld.u{p/m/s/ar/ay} symbol + * __and.wi i __and.uiq i + * + * C promotes an unsigned char to a signed int so this + * must be done in the peephole, not the compiler. + */ + else if + ((p[0]->ins_code == I_AND_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data >= 0) && + (p[0]->ins_data <= 255) && + (is_ubyte(p[1])) + ) { + /* replace code */ + p[0]->ins_code = I_AND_UIQ; + /* no instructions removed, just loop */ + goto lv1_loop; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + + /* ********************************************************* */ + /* 1-instruction patterns */ + /* ********************************************************* */ + + if (q_nb >= 1) { + /* + * __add.wi 0 --> + * + * arg_to_fptr() leaves a useless I_ADD_WI behind when + * generating an I_FARPTR_I for an "array+n" parameter + * + * __sub.wi 0 --> + * + * might as well check for this too, while we're here + */ + if + ((p[0]->ins_code == I_ADD_WI || + p[0]->ins_code == I_SUB_WI) && + (p[0]->ins_type == T_VALUE) && + (p[0]->ins_data == 0) + ) { + nb = 1; + } + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv1_loop; + } + } + } + + /* + * ******************************************************************** + * optimization level 2 - instruction re-scheduler, + * ******************************************************************** + * + * change the instruction order to allow for direct assignments rather + * than the stack-based assignments that are generated by complex math + * or things like "var++" that are not covered by the simpler peephole + * rules earlier. + * + * this covers a bunch of math with immediate integers ... + * + * __ld.wi i --> ... + * __push.wr __{add/sub}.wi i + * ... + * __{add/sub}.wt + * + * this covers storing to global and static variables ... + * + * __ld.wi symbol --> ... + * __push.wr __st.{w/u}m symbol + * ... + * __st.{w/u}pt + * + * this covers storing to local variables ... + * + * __lea.s n --> ... + * __push.wr __st.{w/u}s n + * ... + * __st.{w/u}pt + * + * this covers storing to global and static arrays with "=" ... + * + * __asl.wr --> __index.wr array + * __add.wi array ... + * __push.wr __st.wat array + * ... + * __st.wpt + * + * __add.wi array --> __index.ur array + * __push.wr ... + * ... __st.uat array + * __st.upt + * + * this covers storing to global and static arrays with "+=", "-=", etc ... + * + * __asl.wr --> __ldp.war array + * __add.wi array ... + * __push.wr __st.wat array + * __st.wm __ptr + * __ld.wp __ptr + * ... + * __st.wpt + * + * __add.wi array --> __ldp.uar array + * __push.wr ... + * __st.wm __ptr __st.uat array + * __ld.up __ptr + * ... + * __st.upt + */ + if (optimize >= 2) { + int offset; + int copy, scan, prev; + + /* check last instruction */ + if (q_nb > 1 && + (q_ins[q_wr].ins_code == I_ST_WPT || + q_ins[q_wr].ins_code == I_ST_UPT || + q_ins[q_wr].ins_code == I_ADD_WT || + q_ins[q_wr].ins_code == I_SUB_WT || + q_ins[q_wr].ins_code == I_AND_WT || + q_ins[q_wr].ins_code == I_EOR_WT || + q_ins[q_wr].ins_code == I_OR_WT || + q_ins[q_wr].ins_code == I_MUL_WT) + ) { + /* browse back the instruction list and + * establish a stack history + */ + offset = 2; + + for (copy = 1, scan = q_wr; copy < q_nb; copy++) { + scan -= 1; + + if (scan < 0) + scan += Q_SIZE; + + /* index of insn preceding scan */ + prev = scan - 1; + if (prev < 0) + prev += Q_SIZE; + + /* check instruction */ + switch (q_ins[scan].ins_code) { + case I_MODSP: + if ((q_ins[scan].ins_type == T_STACK) || + (q_ins[scan].ins_type == T_NOP)) + offset += (int)q_ins[scan].ins_data; + break; + + case I_POP_WR: + case I_CMP_WT: + case I_ST_WPT: + case I_ST_UPT: + case I_ADD_WT: + case I_SUB_WT: + case I_AND_WT: + case I_EOR_WT: + case I_OR_WT: + case I_ASL_WT: + case I_ASR_WT: + case I_LSR_WT: + case I_MUL_WT: + case I_SDIV_WT: + case I_UDIV_WT: + case I_SMOD_WT: + case I_UMOD_WT: + offset += 2; + break; + + case I_PUSH_WR: + offset -= 2; + break; + default: + break; + } + + /* check offset */ + if (offset == 0) { + /* + * found the I_PUSH_WR that matches the I_ST_WPT + */ + int from = scan + 1; /* begin copying after the I_PUSH_WR */ + int drop = 2; /* drop I_PUSH_WR and the i-code before it */ + + if (copy == 1) { + /* hmm, may be not... + * there should be at least one instruction + * between I_PUSH_WR and I_ST_WPT. + * this case should never happen, though, + * but better skipping it + */ + break; + } + + /* + * check the first instruction + */ + { + /* + * only handle sequences that start with an + * I_PUSH_WR preceded by I_LEA_S/I_LD_WI/I_ADD_WI + */ + if (q_ins[scan].ins_code != I_PUSH_WR) + break; + +#if OPT_ARRAY_WR + if (q_ins[prev].ins_code != I_LD_WI && + q_ins[prev].ins_code != I_LEA_S && + q_ins[prev].ins_code != I_ADD_WI) + break; +#else + if (q_ins[prev].ins_code != I_LD_WI && + q_ins[prev].ins_code != I_LEA_S) + break; +#endif + + if (q_ins[prev].ins_code != I_LD_WI && + q_ins[q_wr].ins_code != I_ST_WPT && + q_ins[q_wr].ins_code != I_ST_UPT) + break; + + /* change __st.wpt into __st.w{m/s} */ + if (q_ins[prev].ins_code == I_LD_WI) { + switch (q_ins[q_wr].ins_code) { + case I_ST_WPT: + q_ins[q_wr].ins_code = I_ST_WM; + break; + case I_ST_UPT: + q_ins[q_wr].ins_code = I_ST_UM; + break; + case I_ADD_WT: + q_ins[q_wr].ins_code = I_ADD_WI; + break; + case I_SUB_WT: + q_ins[q_wr].ins_code = I_ISUB_WI; + break; + case I_AND_WT: + q_ins[q_wr].ins_code = I_AND_WI; + break; + case I_EOR_WT: + q_ins[q_wr].ins_code = I_EOR_WI; + break; + case I_OR_WT: + q_ins[q_wr].ins_code = I_OR_WI; + break; + case I_MUL_WT: + q_ins[q_wr].ins_code = I_MUL_WI; + break; + default: + abort(); + } + /* use data from the preceding I_LD_WI */ + q_ins[q_wr].ins_type = q_ins[prev].ins_type; + q_ins[q_wr].ins_data = q_ins[prev].ins_data; + } else + if (q_ins[prev].ins_code == I_LEA_S) { + if (q_ins[q_wr].ins_code == I_ST_WPT) + q_ins[q_wr].ins_code = X_ST_WS; + else + q_ins[q_wr].ins_code = X_ST_US; + /* use data from the preceding I_LEA_S */ + q_ins[q_wr].ins_type = q_ins[prev].ins_type; + q_ins[q_wr].ins_data = q_ins[prev].ins_data; + q_ins[q_wr].sym = q_ins[prev].sym; +#if OPT_ARRAY_WR + + } else { + int push = X_INDEX_UR; + int code = X_ST_UAT; + + /* make sure that I_ADD_WI is really a short array */ + if (q_ins[prev].ins_type != T_SYMBOL || + !is_small_array((SYMBOL *)q_ins[prev].ins_data)) + break; + + copy = copy + 1; + from = scan; + drop = 1; + + /* make sure that an I_ST_WPT has an I_ASL_WR */ + if (q_ins[q_wr].ins_code == I_ST_WPT) { + int aslw = prev - 1; + if (aslw < 0) + aslw += Q_SIZE; + if (copy == q_nb || q_ins[aslw].ins_code != I_ASL_WR) + break; + drop = 2; + push = X_INDEX_WR; + code = X_ST_WAT; + } + + /* push the index from the preceding I_ADD_WI */ + q_ins[scan].ins_code = push; + q_ins[scan].ins_type = T_SYMBOL; + q_ins[scan].ins_data = q_ins[prev].ins_data; + + /* use data from the preceding I_ADD_WI */ + q_ins[q_wr].ins_code = code; + q_ins[q_wr].ins_type = T_SYMBOL; + q_ins[q_wr].ins_data = q_ins[prev].ins_data; +#endif + } + } + + /* + * adjust stack references for the + * removal of the I_PUSH_WR + */ + for (int temp = copy; temp > 1; temp--) { + scan += 1; + if (scan >= Q_SIZE) + scan -= Q_SIZE; + + /* check instruction */ + if (is_sprel(&q_ins[scan])) { + /* adjust stack offset */ + q_ins[scan].ins_data -= 2; + } + } + + /* + * remove all the instructions ... + */ + q_nb -= (drop + copy); + q_wr -= (drop + copy); + if (q_wr < 0) + q_wr += Q_SIZE; + + /* + * ... and re-insert them one by one + * in the queue (for further optimizations) + */ + for (; copy > 0; copy--) { + if (from >= Q_SIZE) + from -= Q_SIZE; +#ifdef DEBUG_OPTIMIZER + printf("\nReinserting after rescheduling ..."); +#endif + push_ins(&q_ins[from++]); + } + break; + } + } + } + + /* + * optimization level 2b - after the instruction re-scheduler + */ + if (q_nb >= 3) { + INS *p[3]; + int i, j; + int nb = 0; + +lv2_loop: + /* precalculate pointers to instructions */ + for (i = 0, j = q_wr; i < 3; i++) { + /* save pointer */ + p[i] = &q_ins[j]; + + /* next */ + j -= 1; + if (j < 0) + j += Q_SIZE; + } + + /* + * __push.wr --> __st.{w/u}pi i + * __ld.wi i + * __st.{w/u}pt + * + * This cannot be done earlier because it screws up + * the reordering optimization above. + * + * JCB: This is optimizing writes though a pointer variable! + */ + if + ((p[0]->ins_code == I_ST_WPT || + p[0]->ins_code == I_ST_UPT) && + (p[1]->ins_code == I_LD_WI) && + (p[1]->ins_type == T_VALUE) && + (p[2]->ins_code == I_PUSH_WR) + ) { + /* replace code */ + p[2]->ins_code = p[0]->ins_code == I_ST_WPT ? I_ST_WPI : I_ST_UPI; + p[2]->ins_data = p[1]->ins_data; + nb = 2; + } + +#if 0 + /* + * __push.wr --> __st.wm __ptr + * + * __st.{w/u}pt __st.{w/u}p __ptr + * + * This cannot be done earlier because it screws up + * the reordering optimization above. + * + * THIS IS VERY RARE, REMOVE IT FOR NOW AND RETHINK IT + */ + else if + ((p[0]->ins_code == I_ST_UPT || + p[0]->ins_code == I_ST_WPT) && + (is_load(p[1])) && + (p[2]->ins_code == I_PUSH_WR) + ) { + p[2]->ins_code = I_ST_WM; + p[2]->ins_type = T_PTR; + /* We just removed a push, adjust SP-relative + addresses. */ + if (is_sprel(p[1])) + p[1]->ins_data -= 2; + if (p[0]->ins_code == I_ST_UPT) + p[0]->ins_code = I_ST_UP; + else + p[0]->ins_code = I_ST_WP; + q_ins[q_wr].ins_type = T_PTR; + } +#endif + + /* flush queue */ + if (nb) { + q_wr -= nb; + q_nb -= nb; + nb = 0; + + if (q_wr < 0) + q_wr += Q_SIZE; + + /* loop */ + goto lv2_loop; + } + } + } +} + +/* ---- + * flush_ins_label(int nextlabel) + * ---- + * flush instruction queue, eliminating redundant trailing branches to a + * label following immediately + * + */ +void flush_ins_label (int nextlabel) +{ + while (q_nb) { + /* skip last op if it's a branch to nextlabel */ + if (q_nb > 1 || nextlabel == -1 || + (q_ins[q_rd].ins_code != I_BRA) || + q_ins[q_rd].ins_data != nextlabel) { + /* gen code */ + if (arg_stack_flag) + arg_push_ins(&q_ins[q_rd]); + else + gen_code(&q_ins[q_rd]); + } + + /* advance and wrap queue read pointer */ + q_rd++; + q_nb--; + + if (q_rd == Q_SIZE) + q_rd = 0; + } + + /* reset queue */ + q_rd = 0; + q_wr = Q_SIZE - 1; + q_nb = 0; +} + +/* ---- + * flush_ins() + * ---- + * flush instruction queue + * + */ +void flush_ins (void) +{ + flush_ins_label(-1); +} diff --git a/src/hucc/optimize.h b/src/hucc/optimize.h new file mode 100644 index 00000000..281aa502 --- /dev/null +++ b/src/hucc/optimize.h @@ -0,0 +1,25 @@ +/* File opt.c: 2.1 (83/03/20,16:02:09) */ +/*% cc -O -c % + * + */ + +#ifndef _OPTIMIZE_H +#define _OPTIMIZE_H + +/* bit-flag definitions for the i-code instructions */ +#define IS_SPREL 1 +#define IS_UBYTE 2 +#define IS_SBYTE 4 +#define IS_USEPR 8 +#define IS_STORE 16 +#define IS_SHORT 32 + +/* flag information for each of the i-code instructions */ +extern unsigned char icode_flags[]; + +void push_ins (INS *ins); +void flush_ins (void); +void flush_ins_label (int nextlabel); +void gen_asm (INS *inst); + +#endif diff --git a/src/hucc/pragma.c b/src/hucc/pragma.c new file mode 100644 index 00000000..3a04ebb1 --- /dev/null +++ b/src/hucc/pragma.c @@ -0,0 +1,543 @@ +/* File pragma.c: 2.1 (00/08/09,04:59:24) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "error.h" +#include "io.h" +#include "lex.h" +#include "pragma.h" +#include "sym.h" +#include "fastcall.h" + +/* locals */ +struct fastcall ftemp; +struct fastcall *fastcall_tbl[256]; +static char cmd[LINESIZE]; +static char *cmdptr; + +/* default pragma's */ +static char *pragma_init[] = { +#if 0 + /* 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 __dl, word acc)", + "fastcall put_digit(byte __dl, byte __cl, byte acc)", + "fastcall put_char(byte __dl, word acc)", + "fastcall put_char(byte __dl, byte __cl, byte acc)", + "fastcall put_raw(word __dx, word acc)", + "fastcall put_raw(word __dx, byte __cl, byte acc)", + "fastcall put_number(word __dx, byte __cl, word acc)", + "fastcall put_number(word __dx, byte __cl, byte __bl, byte acc)", + "fastcall put_hex(word __dx, byte __cl, word acc)", + "fastcall put_hex(word __dx, byte __cl, byte __bl, byte acc)", + "fastcall put_string(word __si, word acc)", + "fastcall put_string(word __si, byte __bl, byte acc)", + /* 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 __di, word __bx, 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, byte __ah)", + "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 strlen(word __si)", + "fastcall memcpy(word __di, word __si, word acc)", + "fastcall mempcpy(word __di, word __si, word acc)", + "fastcall memcmp(word __di, word __si, word acc)", + "fastcall memset(word __di, word __bx, 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)", + + "fastcall __builtin_ffs(word acc)", + + /* TGEMU funcs used for unit tests, not for regular HuCC users! */ + "fastcall abort()", + "fastcall exit(word acc)", + "fastcall dump_screen()", +#endif + NULL +}; + +/* protos */ +int fastcall_look (const char *fname, int nargs, struct fastcall **p); + + +/* ---- + * dopragma() + * ---- + * handle pragma directive + * + */ +void dopragma (void) +{ + int i; + + /* make a local copy of the pragma command line */ + for (i = 0;; i++) { + if (ch() == 0) + break; + cmd[i] = gch(); + } + cmd[i] = 0; + + /* parse */ + parse_pragma(); +} + + +/* ---- + * defpragma() + * ---- + * default pragmas + * + */ +void defpragma (void) +{ + int i; + + for (i = 0;; i++) { + if (pragma_init[i] == NULL) + break; + strcpy(cmd, pragma_init[i]); + parse_pragma(); + } +} + + +/* ---- + * parse_pragma() + * ---- + * parse pragma command line + * + */ +void parse_pragma (void) +{ + char sname[NAMESIZE]; + + /* get command */ + cmdptr = cmd; + + if (!symget(sname)) { + error("illegal symbol name"); + return; + } + + /* fastcall */ + if (strcmp(sname, "fastcall") == 0) + new_fastcall(); +/* new_fastcall(sname); */ + else if (!strcmp(sname, "no_recursive")) + norecurse = 1; + else if (!strcmp(sname, "recursive")) + norecurse = 0; + /* others */ + else + error("unknown pragma"); +} + + +/* ---- + * new_fastcall() + * ---- + * setup a new fastcall + * + * ie. #pragma fastcall func(word __dx, byte __al, byte __ah) + * + */ +void new_fastcall (void) +{ + struct fastcall *ptr; + char fname[NAMESIZE]; + char sname[NAMESIZE]; + int hash; + int cnt; + int i; + + ptr = &ftemp; + cnt = 0; + ptr->nargs = 0; + ptr->flags = 0; + + /* get func name */ + if (!symget(fname)) { + error("illegal symbol name"); + return; + } + + /* open */ + if (!strmatch("(")) { + error("missing bracket"); + return; + } + + /* extract args (max. 8) */ + for (i = 0; i < 8; i++) { + /* get type */ + if (!symget(sname)) { + if (*cmdptr == ')') + break; + error("syntax error"); + return; + } + if (strcmp(sname, "byte") == 0) + ptr->argtype[i] = TYPE_BYTE; + else if (strcmp(sname, "word") == 0) + ptr->argtype[i] = TYPE_WORD; + else if (strcmp(sname, "farptr") == 0) + ptr->argtype[i] = TYPE_FARPTR; + else if (strcmp(sname, "dword") == 0) + ptr->argtype[i] = TYPE_DWORD; + else { + error("fastcall unknown type"); + return; + } + + /* get name */ + if (!symget(sname)) { + /* auto */ + if (*cmdptr != ',') + ptr->argtype[i] = TYPE_WORDACC; + else { + error("fastcall register missing"); + return; + } + } + else { + /* dword */ + if (ptr->argtype[i] == TYPE_DWORD) { + /* ptr */ + if (strcmp(sname, "acc") == 0) + strcpy(ptr->argname[i++], "#acc"); + else + strcpy(ptr->argname[i++], sname); + + /* low word */ + if (*cmdptr++ != ':') { + error("syntax error"); + return; + } + if (!symget(sname)) { + error("illegal symbol name"); + return; + } + + /* copy */ + strcpy(ptr->argname[i++], sname); + + /* high word */ + if (*cmdptr++ != '|') { + error("syntax error"); + return; + } + if (!symget(sname)) { + error("illegal symbol name"); + return; + } + + /* copy */ + strcpy(ptr->argname[i], sname); + cnt++; + } + + /* far ptr */ + else if (ptr->argtype[i] == TYPE_FARPTR) { + /* bank */ + strcpy(ptr->argname[i++], sname); + ptr->argtype[i] = TYPE_WORD; + + /* addr */ + if (*cmdptr++ != ':') { + error("syntax error"); + return; + } + if (!symget(sname)) { + error("illegal symbol name"); + return; + } + + /* copy */ + strcpy(ptr->argname[i], sname); + cnt++; + } + + /* other */ + else { + if (strcmp(sname, "acc") == 0) { + /* accumulator */ + ptr->argtype[i] = TYPE_WORDACC; + } + else { + /* variable */ + strcpy(ptr->argname[i], sname); + cnt++; + } + } + } + + /* increment arg counter */ + ptr->nargs++; + + /* next */ + if (!strmatch(",")) + break; + } + + /* close */ + if (!strmatch(")")) { + error("missing bracket"); + return; + } + + /* extra infos */ + if (cnt) { + if (ptr->nargs > 1) + ptr->flags |= FASTCALL_EXTRA; + } + if (symget(sname)) { + if (strcmp(sname, "nop") == 0) + ptr->flags |= FASTCALL_NOP; + if (strcmp(sname, "macro") == 0) + ptr->flags |= FASTCALL_MACRO; + } + + /* copy func name */ + strcpy(ptr->fname, fname); + + /* search for multi-decl */ + if (fastcall_look(fname, ptr->nargs, NULL)) { + error("already defined"); + return; + } + + /* ok */ + ptr = (void *)malloc(sizeof(struct fastcall)); + + if (ptr == NULL) + error("out of memory"); + else { + /* dup struct */ + *ptr = ftemp; + + /* add to hash table */ + hash = symhash(fname); + ptr->next = fastcall_tbl[hash]; + fastcall_tbl[hash] = ptr; + } +} + + +/* ---- + * fastcall_look() + * ---- + * search a fastcall function + * + */ +int fastcall_look (const char *fname, int nargs, struct fastcall **p) +{ + struct fastcall *ptr; + struct fastcall *ref; + int hash; + int is_fc; + + /* search */ + hash = symhash(fname); + ptr = fastcall_tbl[hash]; + ref = NULL; + is_fc = 0; + while (ptr) { + if (strcmp(ptr->fname, fname) == 0) { + is_fc++; + if (nargs != -1) { + if (ptr->nargs == nargs) + ref = ptr; + } + } + ptr = ptr->next; + } + if (nargs != -1) { + if (!ref) + is_fc = 0; + } + + /* return result */ + if (p) + *p = ref; + return (is_fc); +} + + +/* ---- + * symhash() + * ---- + * calculate the hash value of a symbol + * + */ +int symhash (const char *sym) +{ + int i; + char c; + int hash = 0; + + /* calc hash value */ + for (i = 0;; i++) { + c = sym[i]; + if (c == 0) + break; + hash += c; + hash = (hash << 3) + (hash >> 5) + c; + } + + /* ok */ + return (hash & 0xFF); +} + + +/* ---- + * symget() + * ---- + * extract a symbol name + * + */ +int symget (char *sname) +{ + int i; + + skip_blanks(); + + /* first char must be alpha */ + if (!alpha(*cmdptr)) + return (0); + + /* extract symbol name (stops at first non-alphanum char) */ + for (i = 0;; i++) { + if (!alphanum(*cmdptr)) + break; + sname[i] = *cmdptr++; + } + sname[i] = 0; + + /* ok */ + return (1); +} + + +/* ---- + * strmatch() + * ---- + * test if next input string is legal symbol name + * + */ +int strmatch (char *lit) +{ + int i; + + skip_blanks(); + + /* compare */ + i = streq(cmdptr, lit); + + if (i) { + /* match */ + cmdptr += i; + return (1); + } + + /* different */ + return (0); +} + + +/* ---- + * skip_blanks() + * ---- + * skips blank chars (stops at end of input line) + * + */ +void skip_blanks (void) +{ + while ((*cmdptr == ' ') || (*cmdptr == '\t')) + cmdptr++; +} diff --git a/src/hucc/pragma.h b/src/hucc/pragma.h new file mode 100644 index 00000000..b86b1aca --- /dev/null +++ b/src/hucc/pragma.h @@ -0,0 +1,21 @@ +/* File pragma.c: 2.1 (00/08/09,04:59:24) */ +/*% cc -O -c % + * + */ + +#ifndef _PRAGMA_H +#define _PRAGMA_H + +void dopragma (void); +void defpragma (void); +void parse_pragma (void); +void new_fastcall (void); +int fastcall_look (const char *fname, int nargs, struct fastcall **p); +int symhash (const char *sym); +int symget (char *sname); +int strmatch (char *lit); +void skip_blanks (void); + +extern struct fastcall *fastcall_tbl[256]; + +#endif diff --git a/src/hucc/preproc.c b/src/hucc/preproc.c new file mode 100644 index 00000000..6321550d --- /dev/null +++ b/src/hucc/preproc.c @@ -0,0 +1,860 @@ +/* File preproc.c: 2.3 (84/11/27,11:47:40) */ +/*% cc -O -c % + * + */ + +// #define DEBUG_PREPROC + +#include +#include +#include +#include +#include +#include +#include "code.h" +#include "defs.h" +#include "data.h" +#include "error.h" +#include "io.h" +#include "lex.h" +#include "optimize.h" +#include "pragma.h" +#include "preproc.h" +#include "primary.h" +#include "sym.h" + +/* path separator */ +#ifdef _WIN32 +#define PATH_SEPARATOR ';' +#define DIR_SEPARATOR '\\' +#define DIR_SEPARATOR_STRING "\\" +#define DEFAULT_DIRS "c:\\huc\\include\\hucc" +#else +#define PATH_SEPARATOR ':' +#define DIR_SEPARATOR '/' +#define DIR_SEPARATOR_STRING "/" +#define DEFAULT_DIRS "/usr/local/lib/huc/include/hucc:" \ + "/usr/local/huc/include/hucc:" \ + "/usr/local/share/huc/include/hucc:" \ + "/usr/local/include/hucc:" \ + "/usr/lib/huc/include/hucc:" \ + "/usr/share/huc/include/hucc:" \ + "/usr/include/hucc" +#endif + +/* locals */ +static char *incpath[10]; + +static const char *include_path (void) +{ + const char *p; + + p = getenv("PCE_INCLUDE"); + if (!p) + p = DEFAULT_DIRS; + return (p); +} + +char **include_dirs (void) +{ + return (incpath); +} + +/* + * init the include paths + */ +void init_path (void) +{ + const char *p, *pl; + int i, l; + + p = include_path(); + + for (i = 0; i < 10; i++) { + pl = strchr(p, PATH_SEPARATOR); + + if (pl == NULL) + l = (int)strlen(p); + else + l = (int)(pl - p); + if (l) { + incpath[i] = (char *)malloc(l + 2); + strncpy(incpath[i], p, l); + p += l; + while (*p == PATH_SEPARATOR) + p++; + incpath[i][l] = '\0'; + if (incpath[i][l - 1] != DIR_SEPARATOR) + strcat(incpath[i], DIR_SEPARATOR_STRING); +#ifdef DEBUG_PREPROC + printf("incpath %s\n", incpath[i]); +#endif + } + else { + if (incpath[i]) + free(incpath[i]); + incpath[i] = 0; + } + } +} + +/* + * open a file - browse paths + */ +FILE *file_open (char *name, char *mode) +{ + FILE *fp = NULL; + char testname[256]; + int i; + + for (i = 0; i < 10; i++) { + if (incpath[i] && strlen(incpath[i])) { + strcpy(testname, incpath[i]); + strcat(testname, name); + strcpy(inclstk_name[inclsp], testname); + fp = fopen(testname, mode); + if (fp != NULL) break; + } + } + +#ifdef DEBUG_PREPROC + if (fp) { + printf("HuCC opened \"%s\".\n", testname); + } +#endif + + return (fp); +} + +/* + * open an include file + */ +void doinclude (void) +{ + FILE *inp2; + + blanks(); + inp2 = fixiname(); + if (inp2) { + if (inclsp < INCLSIZ) { + inclstk_line[inclsp] = line_number; + line_number = 0; + inclstk[inclsp++] = input2; + input2 = inp2; + } + else { + fclose(inp2); + error("too many nested includes"); + } + } + else + error("Could not open include file"); + kill(); +} + +void incl_globals_h (void) +{ + FILE *inp2; + + /* open the globals.h file to include those variables */ + /* but if we can't open it, it's no problem */ + + if ((inp2 = fopen("globals.h", "r")) == NULL) + inp2 = file_open("globals.h", "r"); + + if (inp2) { + if (inclsp < INCLSIZ) { +#ifdef DEBUG_PREPROC + printf("HuCC opened \"globals.h\".\n"); +#endif + inclstk_line[inclsp] = line_number; + line_number = 0; + strcpy(inclstk_name[inclsp], "globals.h"); + inclstk[inclsp++] = input2; + input2 = inp2; + globals_h_in_process = 1; + } + else { + fclose(inp2); + error("too many nested includes"); + } + } +} + +void incl_huc_h (void) +{ + FILE *inp2; + + /* open the huc.h file to include those variables */ + /* but if we can't open it, it's no problem */ + + if ((inp2 = fopen("huc.h", "r")) == NULL) + inp2 = file_open("huc.h", "r"); + + if (inp2) { + if (inclsp < INCLSIZ) { +#ifdef DEBUG_PREPROC + printf("HuCC opened \"huc.h\".\n"); +#endif + inclstk_line[inclsp] = line_number; + line_number = 0; + strcpy(inclstk_name[inclsp], "huc.h"); + inclstk[inclsp++] = input2; + input2 = inp2; + } + else { + fclose(inp2); + error("too many nested includes"); + } + } +} + +/* + * fixiname - remove "brackets" around include file name + */ +FILE *fixiname (void) +{ + char c1, c2, *p, *ibp; + char buf[LINESIZE]; + FILE *fp; + + ibp = &buf[0]; + c1 = gch(); + c2 = (c1 == '"') ? '"' : '>'; + if ((c1 != '"') && (c1 != '<')) { + error("incorrect file name delimiter"); + return (NULL); + } + for (p = line + lptr; *p;) { + if (*p == c2) + break; + if ((*p == '\\') && (p[1] == '\\')) + p++; + *ibp++ = *p++; + } + if (*p != c2) { + error("file name delimiter missing"); + return (NULL); + } + *ibp = 0; + fp = NULL; + strcpy(inclstk_name[inclsp], buf); + if ((c1 == '<') || ((fp = fopen(buf, "r")) == NULL)) + fp = file_open(buf, "r"); +#ifdef DEBUG_PREPROC + if (fp) { + printf("HuCC opening #include \"%s\".\n", buf); + } +#endif + return (fp); +} + +/* + * "asm" pseudo-statement + * + * enters mode where assembly language statements are passed + * intact through parser + * + */ +void doasm (void) +{ + /* Save the SP if this #asm section is inside a function */ + if (fexitlab) + out_ins(I_SAVESP, 0, 0); + flush_ins(); /* David - optimize.c related */ + cmode = 0; + FOREVER { + readline(); + if (match("#endasm")) + break; + if (feof(input)) + break; + outstr(line); + nl(); + } + kill(); + cmode = 1; + /* Restore the SP if this #asm section is inside a function */ + if (fexitlab) { + out_ins(I_LOADSP, 0, 0); + flush_ins(); /* David - optimize.c related */ + } +} + +void doasmdef (void) +{ + char sname[100]; + char sval[100]; + int i = 0; + + symname(sname); + while ((ch() == ' ') || (ch() == 9)) + gch(); + + while (ch()) { + sval[i++] = ch(); + gch(); + } + sval[i++] = '\0'; + + outstr(sname); + outstr(" = "); + outstr(sval); + nl(); +} + +void dodefine (void) +{ + addmac(); +} + +void doundef (void) +{ + struct macro *mp; + char sname[NAMESIZE]; + + if (!symname(sname)) { + illname(); + kill(); + return; + } + + mp = findmac(sname); + if (mp) + delmac(mp); + kill(); +} + +void preprocess (void) +{ + if (ifline()) return; + + while (cpp(NO)) ; +} + +static int max_if_depth = 0; +static int *had_good_elif = 0; + +static void bump_iflevel (void) +{ + ++iflevel; + if (iflevel >= max_if_depth) { + max_if_depth = (max_if_depth + 1) * 2; + had_good_elif = realloc(had_good_elif, max_if_depth * sizeof(int)); + } +} + +void doifdef (bool ifdef) +{ + char sname[NAMESIZE]; + bool k; + + blanks(); + bump_iflevel(); + had_good_elif[iflevel] = 0; + if (skiplevel) return; + + k = symname(sname) && findmac(sname); + if (k != ifdef) skiplevel = iflevel; +} + +static void doif (void) +{ + int num; + + blanks(); + bump_iflevel(); + had_good_elif[iflevel] = 0; + if (skiplevel) return; + + lex_stop_at_eol = 1; + const_expr(&num, NULL, NULL); + lex_stop_at_eol = 0; + if (!num) + skiplevel = iflevel; +} + +static void doelif (void) +{ + int num; + + blanks(); + if (skiplevel && skiplevel < iflevel) + return; + + if (!skiplevel || had_good_elif[iflevel]) { + /* previous section was good, so we are not */ + skiplevel = iflevel; + return; + } + lex_stop_at_eol = 1; + const_expr(&num, NULL, NULL); + lex_stop_at_eol = 0; + if (!num) + skiplevel = iflevel; + else { + had_good_elif[iflevel] = 1; + skiplevel = 0; + } +} + +int ifline (void) +{ + FOREVER { + readline(); +cont_no_read: + if (!input || feof(input)) return (1); + + if (match("#ifdef")) { + doifdef(YES); + continue; + } + else if (match("#ifndef")) { + doifdef(NO); + continue; + } + else if (match("#if")) { + /* need to preprocess the argument because it may + contain macros */ + cpp(YES); + doif(); + /* const_expr() already read the next line */ + goto cont_no_read; + } + else if (match("#elif")) { + /* need to preprocess the argument because it may + contain macros */ + cpp(YES); + doelif(); + /* const_expr() already read the next line */ + goto cont_no_read; + } + else if (match("#else")) { + if (iflevel) { + if (skiplevel == iflevel && !had_good_elif[iflevel]) + skiplevel = 0; + else if (skiplevel == 0) + skiplevel = iflevel; + } + else noiferr(); + continue; + } + else if (match("#endif")) { + if (iflevel) { + if (skiplevel == iflevel) skiplevel = 0; + --iflevel; + } + else noiferr(); + continue; + } + else if (!skiplevel) { + if (match("#define")) { + dodefine(); + continue; + } + else if (match("#undef")) { + doundef(); + continue; + } + else if (match("#pragma")) { + dopragma(); + continue; + } + } + if (!skiplevel) return (0); + } +} + +/* + * noiferr + * Input : nothing + * Output : nothing + * + * Called when a #if statement is lacking + * + */ +void noiferr (void) +{ + error("no matching #if..."); +} + + +int cpp (int subline) +{ + int k; + char c, sname[NAMESIZE]; + int tog; + int cpped; /* non-zero if something expanded */ + int llptr; + + cpped = 0; + /* don't expand lines with preprocessor commands in them */ + if (!subline && (!cmode || line[0] == '#')) { + if (sstreq("#include")) + return (0); + + /* except #inc/#def commands */ + if (!match("#inc") && !match("#def")) + return (0); + } + + mptr = 0; + if (subline) + llptr = lptr; /* start wherever we are right now */ + else + llptr = lptr = 0; /* do the whole line */ + + while (ch()) { + if ((ch() == ' ') || (ch() == 9)) { + keepch(' '); + while ((ch() == ' ') || (ch() == 9)) + gch(); + } + else if (ch() == '"') { + keepch(ch()); + gch(); + while (ch() != '"') { + if (ch() == 0) { + error("missing quote"); + break; + } + if (ch() == '\\') keepch(gch()); + keepch(gch()); + } + gch(); + keepch('"'); + } + else if (ch() == '\'') { + keepch('\''); + gch(); + while (ch() != '\'') { + if (ch() == 0) { + error("missing apostrophe"); + break; + } + if (ch() == '\\') keepch(gch()); + keepch(gch()); + } + gch(); + keepch('\''); + } + else if ((ch() == '/') && (nch() == '*')) { + inchar(); + inchar(); + while ((((c = ch()) == '*') && (nch() == '/')) == 0) + if (c == '$') { + inchar(); + tog = TRUE; + if (ch() == '-') { + tog = FALSE; + inchar(); + } + if (alpha(c = ch())) { + inchar(); + toggle(c, tog); + } + } + else { + if (ch() == 0) + readline(); + else + inchar(); + if (feof(input)) + break; + } + inchar(); + inchar(); + } + else if (ch() == '/' && nch() == '/') { + while (ch()) + inchar(); + } + else if (alphanum(ch())) { + k = 0; + while (alphanum(ch())) { + if (k < NAMEMAX) + sname[k++] = ch(); + gch(); + } + sname[k] = 0; + struct macro *mp; + mp = findmac(sname); + if (mp) { + char args[40][256]; + int argc = 0; + int haveargs = 0; + int nest = 0; + /* If the macro wants arguments, substitute them. + Unlike at the time of definition, here whitespace + is permissible between the macro identifier and + the opening parenthesis. */ + if (mp->argc && match("(")) { + if (mp->argc == -1) { + if (!match(")")) { + error("missing closing paren"); + return (0); + } + } + else { + haveargs = 1; + for (;;) { + char * parg = args[argc]; + char * pend = args[argc] + 255; + parg[0] = '\0'; + while (ch() != ',' || nest > 0) { + char c = gch(); + if (c == '(') + nest++; + if (!c) { + error("missing closing paren"); + return (0); + } + parg[0] = c; + parg[1] = '\0'; + if (++parg >= pend) { + error("macro argument too int"); + return (0); + } + if (ch() == ')') { + if (nest) + nest--; + else + break; + } + } +#ifdef DEBUG_PREPROC + printf("macro arg %s\n", args[argc]); +#endif + argc++; + if (ch() == ')') { + gch(); + break; + } + gch(); + } + } + } + if (mp->argc != -1 && argc != mp->argc) { + error("wrong number of macro arguments"); + return (0); + } + + cpped = 1; + k = 0; + if (haveargs) { + int i; + char *buf = malloc(1); + buf[0] = 0; + char *dp = mp->def; + buf[0] = 0; + for (i = 0; mp->argpos[i].arg != -1; i++) { + buf = realloc(buf, strlen(buf) + + mp->argpos[i].pos - (dp - mp->def) + + strlen(args[mp->argpos[i].arg]) + 1); + strncat(buf, dp, mp->argpos[i].pos - (dp - mp->def)); + strcat(buf, args[mp->argpos[i].arg]); + dp = mp->def + mp->argpos[i].pos + strlen(mp->args[mp->argpos[i].arg]); + } + buf = realloc(buf, strlen(buf) + strlen(dp) + 1); + strcat(buf, dp); +#ifdef DEBUG_PREPROC + printf("postproc %s\n", buf); +#endif + for (i = 0; buf[i]; i++) + keepch(buf[i]); + free(buf); + } + else { + while ((c = mp->def[k++])) + keepch(c); + keepch(' '); + } + } + else { + k = 0; + while ((c = sname[k++])) + keepch(c); + } + } + else + keepch(gch()); + } + keepch(0); + if (mptr >= MPMAX) + error("line too int"); + /* copy cooked input back to where we got the raw input from */ + strcpy(&line[llptr], mline); + /* ...and continue processing at that point */ + lptr = llptr; + return (cpped); +} + +int keepch (char c) +{ + mline[mptr] = c; + if (mptr < MPMAX) + mptr++; + return (c); +} + +void defmac (char *s) +{ + kill(); + strcpy(line, s); + addmac(); +} + +void addmac (void) +{ + char sname[NAMESIZE]; + struct macro *mp; + + if (!symname(sname)) { + illname(); + kill(); + return; + } + mp = findmac(sname); + if (mp) { + error("Duplicate define"); + delmac(mp); + } + else + mp = &macq[macptr++]; + + mp->name = strdup(sname); + + int argc = 0; + mp->args = malloc(sizeof(char *) * 1); + mp->args[0] = 0; + mp->argpos = malloc(sizeof(*mp->argpos) * 1); + mp->argpos[0].arg = -1; + /* Stuff within parentheses is only considered a list of arguments + if there is no whitespace between the identifier and the opening + paren. */ + if (ch() == '(') { + gch(); + if (match(")")) + argc = -1; + else { + for (;;) { + if (!symname(sname)) { + error("invalid macro argument"); + delmac(mp); + return; + } +#ifdef DEBUG_PREPROC + printf("arg %d %s\n", argc, sname); +#endif + mp->args = realloc(mp->args, sizeof(char *) * (argc + 2)); + mp->args[argc++] = strdup(sname); + if (argc >= 40) { + error("too many arguments"); + delmac(mp); + return; + } + mp->args[argc] = 0; + if (match(")")) + break; + if (!match(",")) { + error("expected comma"); + delmac(mp); + return; + } + } + } + } + mp->argc = argc; + + while ((ch() == ' ') || (ch() == 9)) + gch(); + char c; + mp->def = malloc(1); + mp->def[0] = 0; + int pos = 0; + int count = 0; + for (;;) { + int found = 0; + int i; + if (ch() == '/' && nch() == '/') { + kill(); + break; + } + for (i = 0; i < argc; i++) { + if (alphanum(ch()) && amatch(mp->args[i], (int)strlen(mp->args[i]))) { +#ifdef DEBUG_PREPROC + printf("arg %d at offset %d\n", i, pos); +#endif + mp->def = realloc(mp->def, strlen(mp->def) + strlen(mp->args[i]) + 1); + strcat(mp->def, mp->args[i]); + mp->argpos = realloc(mp->argpos, sizeof(*mp->argpos) * (count + 2)); + mp->argpos[count].arg = i; + mp->argpos[count++].pos = pos; + mp->argpos[count].arg = -1; + mp->argpos[count].pos = -1; + pos += (int)strlen(mp->args[i]); + found = 1; + break; + } + } + if (!found) { + c = gch(); + if (c == '\\') { + c = gch(); + if (!c) { + readline(); + c = gch(); + } + } + if (!c) + break; + mp->def = realloc(mp->def, strlen(mp->def) + 2); + strncat(mp->def, &c, 1); + pos++; + } + } +#ifdef DEBUG_PREPROC + printf("macdef %s\n", mp->def); +#endif + if (macptr >= MACMAX) + error("macro table full"); +} + +void delmac (struct macro *mp) +{ + if (mp->name) + free(mp->name); + mp->name = 0; + if (mp->def) + free(mp->def); + mp->def = 0; + if (mp->args) + free(mp->args); + mp->args = 0; + if (mp->argpos) + free(mp->argpos); + mp->argpos = 0; +} + +struct macro *findmac (char *sname) +{ + int k; + + k = 0; + while (k < macptr) { + if (macq[k].name && astreq(sname, macq[k].name, NAMEMAX)) + return (&macq[k]); + + k++; + } + return (0); +} + +void toggle (char name, int onoff) +{ + switch (name) { + case 'C': + ctext = onoff; + break; + } +} diff --git a/src/hucc/preproc.h b/src/hucc/preproc.h new file mode 100644 index 00000000..f7044a07 --- /dev/null +++ b/src/hucc/preproc.h @@ -0,0 +1,46 @@ +#ifndef _INCLUDE_PREPROC_H +#define _INCLUDE_PREPROC_H + +void doinclude (void); + +void incl_globals_h (void); + +void incl_huc_h (void); + +FILE *fixiname (void); + +void init_path (void); + +void doasmdef (void); + +void doasm (void); + +void dodefine (void); + +void doundef (void); + +void preprocess (void); + +void doifdef (bool ifdef); + +int ifline (void); + +void noiferr (void); + +int cpp (int); + +int keepch (char c); + +void defmac (char *s); + +void addmac (void); + +void delmac (struct macro *mp); + +struct macro *findmac (char *sname); + +void toggle (char name, int onoff); + +char **include_dirs (void); + +#endif diff --git a/src/hucc/primary.c b/src/hucc/primary.c new file mode 100644 index 00000000..fae91cc7 --- /dev/null +++ b/src/hucc/primary.c @@ -0,0 +1,893 @@ +/* File primary.c: 2.4 (84/11/27,16:26:07) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "enum.h" +#include "error.h" +#include "expr.h" +#include "gen.h" +#include "io.h" +#include "lex.h" +#include "primary.h" +#include "sym.h" +#include "struct.h" + +extern char current_fn[]; + +int match_type (struct type_type *t, int do_ptr, int allow_unk_compound) +{ + char n[NAMESIZE]; + int have_sign = 0; + int sflag; + int i; + static int anon_struct_cnt = 0; + + t->type_type = 0; + t->flags = 0; + t->otag = -1; + + for (i = 0; i < typedef_ptr; i++) { + if (amatch(typedefs[i].sname, (int)strlen(typedefs[i].sname))) { + *t = typedefs[i]; + goto ret_do_ptr; + } + } + + if (amatch("register", 8)) + t->flags |= F_REGISTER; + if (amatch("volatile", 8)) + t->flags |= F_VOLATILE; + if (amatch("const", 5)) + t->flags |= F_CONST; + + if ((sflag = amatch("struct", 6)) || amatch("union", 5)) { + /* compound */ + if (symname(n)) { + t->otag = find_tag(n); + if (t->otag < 0 && !allow_unk_compound) { + error("unknown struct name"); + junk(); + return (0); + } + t->type_type = CSTRUCT; + if (sflag) + t->flags |= F_STRUCT; + strcpy(t->sname, n); + } + else { + blanks(); + if (ch() == '{') { + sprintf(t->sname, "__anon_struct%d", anon_struct_cnt++); + t->otag = define_struct(t->sname, DEFAUTO, sflag); + t->type_type = CSTRUCT; + if (sflag) + t->flags |= F_STRUCT; + } + else { + error("illegal struct name"); + junk(); + return (0); + } + } + } + else if (amatch("enum", 4)) { + t->type_type = CENUM; + if (symname(n)) { + /* This may or may not find an enum type, but if + it doesn't it's not necessarily an error. */ + t->otag = find_enum_type(n); + strcpy(t->sname, n); + } + else { + blanks(); + if (ch() == '{') { + /* anonymous enum */ + t->otag = define_enum(NULL, DEFAUTO); + t->sname[0] = 0; + } + else { + illname(); + junk(); + return (0); + } + } + } + else { + /* scalar */ + if (amatch("unsigned", 8)) { + t->type_type |= CUNSIGNED; + have_sign = 1; + } + else if (amatch("signed", 6)) + have_sign = 1; + + if (amatch("char", 4)) { + t->type_type |= CCHAR; + if ((have_sign == 0) && (user_signed_char == 0)) + t->type_type |= CUNSIGNED; + } + else if (amatch("int", 3)) + t->type_type |= CINT; + else if (amatch("short", 5)) { + amatch("int", 3); + t->type_type |= CINT; + } + else if (amatch("void", 4)) { + if (have_sign) + goto invalid_cast; + t->type_type |= CVOID; + } + else { + if (have_sign) + t->type_type |= CINT; + else /* not a cast */ + return (0); + } + } + + t->type_ident = VARIABLE; + t->ptr_order = 0; + +ret_do_ptr: + if (do_ptr) + while (match("*")) { + t->type_ident = POINTER; + t->ptr_order++; + } + + return (1); + +invalid_cast: + error("invalid type cast"); + return (0); +} + +int primary (LVALUE *lval, int comma, bool *deferred) +{ + SYMBOL *ptr; + char sname[NAMESIZE]; + int num; + int k; + + lval->ptr_type = 0; /* clear pointer/array type */ + lval->ptr_order = 0; + lval->val_type = 0; + lval->symbol2 = 0; + if (match("(")) { + /* typecast */ + struct type_type t; + if (match_type(&t, YES, NO)) { + needbracket(")"); + k = heir10(lval, comma); + if (k) + rvalue(lval); + if (t.type_ident == POINTER) { + lval->ptr_type = t.type_type; + lval->val_type = 0; + } else { + gcast(t.type_type); + lval->ptr_type = 0; + lval->val_type = t.type_type; + } + lval->ptr_order = t.ptr_order; + return (0); + } + else { + indflg = 0; + /* need to use expression_ex() (not heir1()), otherwise + the comma operator is not handled */ + k = expression_ex(lval, comma, YES); + needbracket(")"); + return (k); + } + } + if (amatch("sizeof", 6)) { + int have_paren; + struct type_type t; + indflg = 0; + have_paren = match("("); + if (match_type(&t, YES, NO)) { + if (t.type_ident == POINTER) + immed(T_VALUE, INTSIZE); + else if (t.type_type == CSTRUCT) + immed(T_VALUE, tag_table[t.otag].size); + else if (t.type_type == CINT || t.type_type == CUINT) + immed(T_VALUE, INTSIZE); + else if (t.type_type == CCHAR || t.type_type == CUCHAR) + immed(T_VALUE, 1); + else { + error("internal error: sizeof type unknown"); + return (0); + } + } + else if (symname(sname)) { + if (!strcmp("__func__", sname) || + !strcmp("__FUNCTION__", sname)) + immed(T_VALUE, strlen(current_fn) + 1); + else if (!strcmp("__FILE__", sname)) + immed(T_VALUE, strlen(fname_copy) + 1); + else if ((ptr = findloc(sname)) || + (ptr = findglb(sname))) { + k = ptr->alloc_size; + immed(T_VALUE, k); + } + else { + error("sizeof undeclared variable"); + immed(T_VALUE, 0); + } + } + else if (readqstr()) + immed(T_VALUE, strlen(litq2)); + else + error("sizeof only on type or variable"); + if (have_paren) + needbracket(")"); + lval->symbol = 0; + lval->indirect = 0; + return (0); + } + if (amatch("__FUNCTION__", 12) || amatch("__func__", 8)) { + const_str(&num, current_fn); + immed(T_STRING, num); + indflg = 0; + lval->symbol = 0; + lval->indirect = 0; + lval->ptr_type = CCHAR; + lval->ptr_order = 1; + return (0); + } + else if (amatch("__FILE__", 8)) { + const_str(&num, fname_copy); + immed(T_STRING, num); + indflg = 0; + lval->symbol = 0; + lval->indirect = 0; + lval->ptr_type = CCHAR; + lval->ptr_order = 1; + return (0); + } + else if (amatch("__sei", 5) && match("(") && match(")")) { + gsei(); + return (0); + } + else if (amatch("__cli", 5) && match("(") && match(")")) { + gcli(); + return (0); + } + + if (symname(sname)) { + blanks(); + if (find_enum(sname, &num)) { + immed(T_VALUE, num); + indflg = 0; + lval->symbol = 0; + lval->indirect = 0; + return (0); + } + ptr = findloc(sname); + if (ptr) { + /* + * David, patched to support local 'static' variables + */ + lval->symbol = ptr; + lval->indirect = ptr->sym_type; + lval->tagsym = 0; + if (ptr->sym_type == CSTRUCT) + lval->tagsym = &tag_table[ptr->tagidx]; + if (ptr->identity == POINTER) { + if ((ptr->storage & STORAGE) == LSTATIC) + lval->indirect = 0; + else { + lval->indirect = CUINT; + getloc(ptr); + } + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + return (1); + } + if (ptr->identity == ARRAY || + (ptr->identity == VARIABLE && ptr->sym_type == CSTRUCT)) { + /* add array base address after index calculation */ +#if ULI_NORECURSE + if (/* ptr->identity == ARRAY && */ ch() == '[' && (ptr->storage & STORAGE) == AUTO && norecurse && glint(ptr) < 0) + *deferred = true; + else +#endif + if (/* ptr->identity == ARRAY && */ ch() == '[' && (ptr->storage & STORAGE) == LSTATIC) + *deferred = true; + else + getloc(ptr); + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + if (ptr->identity == VARIABLE && ptr->sym_type == CSTRUCT) + return (1); + else + return (0); + } + if ((ptr->storage & STORAGE) == LSTATIC) + lval->indirect = 0; + else + getloc(ptr); + return (1); + } + ptr = findglb(sname); + if (ptr) { + if (ptr->identity != FUNCTION) { + lval->symbol = ptr; + lval->indirect = 0; + lval->tagsym = 0; + if (ptr->sym_type == CSTRUCT) + lval->tagsym = &tag_table[ptr->tagidx]; + if (ptr->identity != ARRAY && + (ptr->identity != VARIABLE || ptr->sym_type != CSTRUCT)) { + if (ptr->identity == POINTER) { + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + } + return (1); + } + if (!ptr->far) { + /* add array base address after index calculation */ + if (/* ptr->identity == ARRAY && */ ch() == '[') + *deferred = true; + else + immed(T_SYMBOL, (intptr_t)ptr); + } + else { + /* special variables */ + if ((ch() != '[') && (ch() != '(')) { + immed(T_SYMBOL, (intptr_t)ptr); +// error ("can't access far array"); + } + } + lval->indirect = + lval->ptr_type = ptr->sym_type; + lval->ptr_order = ptr->ptr_order; + if (ptr->identity == VARIABLE && ptr->sym_type == CSTRUCT) + return (1); + else + return (0); + } + } + if (ch() != '(') { + if (ptr && (ptr->identity == FUNCTION)) { + lval->symbol = ptr; + lval->indirect = 0; + immed(T_SYMBOL, (intptr_t)ptr); + return (0); + } + error("undeclared variable"); + } + ptr = addglb(sname, FUNCTION, CINT, 0, PUBLIC, 0); + indflg = 0; + lval->symbol = ptr; + lval->indirect = 0; + return (0); + } + if ((k = constant(&num))) { + indflg = 0; + lval->symbol = 0; + lval->indirect = 0; + if (k == 2) { + /* a string constant */ + lval->ptr_type = (user_signed_char) ? CCHAR : CUCHAR; + lval->ptr_order = 1; +#if 1 + } else { + /* this works together with the integer promotion rules + * to make sure that values >= 0 and < 128 are compared + * as bytes, with word compares being used if > 128 + */ + if (num < -128) + lval->val_type = CINT; + else + if (num < 128) + lval->val_type = CCHAR; + else + if (num < 32768) + lval->val_type = CINT; + else + lval->val_type = CUINT; +#endif + } + return (0); + } + else { + indflg = 0; + error("invalid expression"); + immed(T_VALUE, 0); + junk(); + return (0); + } +} + +/* + * true if val1 -> int pointer or int array and val2 not pointer or array + */ +bool dbltest (LVALUE val1[], LVALUE val2[]) +{ + if (val1 == NULL || !val1->ptr_type) + return (false); + + if (val1->ptr_type == CCHAR || val1->ptr_type == CUCHAR) + return (false); + + if (val2->ptr_type) + return (false); + + return (true); +} + +/* + * determine type of binary operation + */ +void result (LVALUE lval[], LVALUE lval2[]) +{ + if (lval->ptr_type && lval2->ptr_type) { + lval->ptr_type = 0; + lval->ptr_order = 0; + } + else if (lval2->ptr_type) { + lval->symbol = lval2->symbol; + lval->indirect = lval2->indirect; + lval->ptr_type = lval2->ptr_type; + lval->ptr_order = lval2->ptr_order; + } +} + +int constant (int *val) +{ + if (number(val)) + immed(T_VALUE, *val); + else if (pstr(val)) + immed(T_VALUE, *val); + else if (qstr(val)) { + immed(T_STRING, *val); + return (2); + } + else + return (0); + + return (1); +} + +bool number (int *val) +{ + int k, minus, base; + char c; + + k = minus = 1; + while (k) { + k = 0; + if (match("+")) + k = 1; + if (match("-")) { + minus = (-minus); + k = 1; + } + } + if (!numeric(c = ch())) + return (false); + + if (match("0x") || match("0X")) { + while (numeric(c = ch()) || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')) { + inbyte(); + k = k * 16 + + (numeric(c) ? (c - '0') : ((c & 07) + 9)); + } + } + else if (match("0b") || match("0B")) { + while (numeric(c = ch()) && + ((c == '1') || + (c == '0'))) { + inbyte(); + k = k * 2 + (c - '0'); + } + } + else { + base = (c == '0') ? 8 : 10; + while (numeric(ch())) { + c = inbyte(); + k = k * base + (c - '0'); + } + } + if (minus < 0) + k = (-k); + val[0] = k; + return (true); +} + +static int parse0 (int *num) +{ + if (!const_expr(num, ")", NULL)) + return (0); + + if (!match(")")) + error("internal error"); + return (1); +} + +static int parse3 (int *num) +{ + int num2; + struct type_type t; + char op; + char n[NAMESIZE]; + int have_paren = 0; + + if (match("-")) + op = '-'; + else if (match("+")) + op = '+'; + else if (match("~")) + op = '~'; + else if (match("!")) + op = '!'; + else if (match("(")) { + if (match_type(&t, YES, NO)) { + if (!match(")")) { + error("invalid type cast"); + return (0); + } + op = 'c'; + } + else { + have_paren = 1; + op = 0; + } + } + else + op = 0; + + if (!(have_paren && parse0(&num2)) && + !number(&num2) && + !pstr(&num2) && + !(symname(n) && find_enum(n, &num2))) + return (0); + + if (op == '-') + *num = -num2; + else if (op == '~') + *num = ~num2; + else if (op == '!') + *num = !num2; + else if (op == 'c') { + if (t.type_ident != POINTER) { + assert(sizeof(short) == 2); + switch (t.type_type) { + case CCHAR: + *num = (char)num2; + break; + case CUCHAR: + *num = (unsigned char)num2; + break; + case CINT: + *num = (short)num2; + break; + case CUINT: + *num = (unsigned short)num2; + break; + default: + error("unable to handle cast in constant expression"); + return (0); + } + } + else + *num = num2; + } + else + *num = num2; + return (1); +} + +static int parse5 (int *num) +{ + int num1, num2; + + if (!parse3(&num1)) + return (0); + + for (;;) { + char op; + if (match("*")) + op = '*'; + else if (match("/")) + op = '/'; + else { + *num = num1; + return (1); + } + + if (!parse3(&num2)) + return (0); + + if (op == '*') + num1 *= num2; + else + num1 /= num2; + } +} + +static int parse6 (int *num) +{ + int num1, num2; + + if (!parse5(&num1)) + return (0); + + for (;;) { + char op; + if (match("+")) + op = '+'; + else if (match("-")) + op = '-'; + else { + *num = num1; + return (1); + } + + if (!parse5(&num2)) + return (0); + + if (op == '-') + num1 -= num2; + else + num1 += num2; + } +} + +static int parse7 (int *num) +{ + int num1, num2; + + if (!parse6(&num1)) + return (0); + + for (;;) { + char op; + if (match("<<")) + op = 'l'; + else if (match(">>")) + op = 'r'; + else { + *num = num1; + return (1); + } + + if (!parse6(&num2)) + return (0); + + if (op == 'l') + num1 <<= num2; + else + num1 >>= num2; + } +} + +static int parse9 (int *num) +{ + int num1, num2; + + if (!parse7(&num1)) + return (0); + + for (;;) { + char op; + if (match("==")) + op = '='; + else if (match("!=")) + op = '!'; + else { + *num = num1; + return (1); + } + + if (!parse7(&num2)) + return (0); + + if (op == '=') + num1 = num1 == num2; + else + num1 = num1 != num2; + } +} + +bool const_expr (int *num, char *end1, char *end2) +{ + if (!parse9(num)) { + error("failed to evaluate constant expression"); + return (false); + } + blanks(); + if (end1 && !sstreq(end1) && !(end2 && sstreq(end2))) { + error("unexpected character after constant expression"); + return (false); + } + return (true); +} + +/* + * pstr + * pstr parses a character than can eventually be 'double' i.e. like 'a9' + * returns 0 in case of failure else 1 + */ +bool pstr (int *val) +{ + int k; + char c; + + k = 0; + if (!match("'")) + return (false); + + while ((c = gch()) != '\'') { + c = (c == '\\') ? spechar() : c; + k = (k & 255) * 256 + (c & 255); + } + *val = k; + return (true); +} + +/* + * qstr + * qstr parses a double quoted string into litq + * return 0 in case of failure and 1 else + */ +bool qstr (int *val) +{ + char c; + + if (!match(quote)) + return (0); + + *val = litptr; + while (ch() != '"') { + if (ch() == 0) + break; + if (litptr >= LITMAX) { + error("string space exhausted"); + while (!match(quote)) + if (gch() == 0) + break; + return (false); + } + c = gch(); + litq[litptr++] = (c == '\\') ? spechar() : c; + } + gch(); + litq[litptr++] = 0; + return (true); +} + +bool const_str (int *val, const char *str) +{ + if (litptr + (int)strlen(str) + 1 >= LITMAX) { + error("string space exhausted"); + return (false); + } + strcpy(&litq[litptr], str); + *val = litptr; + litptr += (int)strlen(str) + 1; + return (true); +} + +/* + * readqstr + * readqstr parses a double quoted string into litq2 + * return 0 in case of failure and 1 else + * Zeograd: this function don't dump the result of the reading in the literal + * pool, it is rather intended for use in pseudo code + */ +bool readqstr (void) +{ + char c; + int posptr = 0; + + if (!match(quote)) + return (0); + + while (ch() != '"') { + if (ch() == 0) + break; + if (posptr >= LITMAX2) { + error("string space exhausted"); + while (!match(quote)) + if (gch() == 0) + break; + return (false); + } + c = gch(); + litq2[posptr++] = (c == '\\') ? spechar() : c; + } + gch(); + litq2[posptr] = 0; + return (true); +} + +/* + * readstr + * reaqstr parses a string into litq2 + * it only read alpha numeric characters + * return 0 in case of failure and 1 else + * Zeograd: this function don't dump the result of the reading in the literal + * pool, it is rather intended for use in pseudo code + */ +bool readstr (void) +{ + char c; + int posptr = 0; + + while (alphanum(ch()) || (ch() == '_')) { + if (ch() == 0) + break; + if (posptr >= LITMAX2) { + error("string space exhausted"); + return (false); + } + c = gch(); + litq2[posptr++] = (c == '\\') ? spechar() : c; + } + litq2[posptr] = 0; + return (true); +} + + +/* + * decode special characters (preceeded by back slashes) + */ +char spechar (void) +{ + char c; + + c = ch(); + + if (c == 'n') c = EOL; + else if (c == 't') c = TAB; + else if (c == 'r') c = CR; + else if (c == 'f') c = FFEED; + else if (c == 'b') c = BKSP; + else if (c == '0') c = EOS; + else if (numeric(c) && c < '8') { + /* octal character specification */ + int n = 0; + while (numeric(c) && c < '8') { + n = (n << 3) | (c - '0'); + gch(); + c = ch(); + } + return (n); + } + else if (c == 'x') { + int n = 0, i; + gch(); + for (i = 0; i < 2; i++) { + c = gch(); + if (c >= 'a' && c <= 'f') + c = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + c = c - 'A' + 10; + else if (c >= '0' && c <= '9') + c = c - '0'; + else { + error("invalid hex character"); + return (0); + } + n = (n << 4) | c; + } + return (n); + } + else if (c == EOS) return (c); + + gch(); + return (c); +} diff --git a/src/hucc/primary.h b/src/hucc/primary.h new file mode 100644 index 00000000..651b02c8 --- /dev/null +++ b/src/hucc/primary.h @@ -0,0 +1,24 @@ +/* File primary.c: 2.4 (84/11/27,16:26:07) */ +/*% cc -O -c % + * + */ + +#ifndef _PRIMARY_H +#define _PRIMARY_H + +int primary (LVALUE *lval, int comma, bool *deferred); +bool dbltest (LVALUE val1[], LVALUE val2[]); +void result (LVALUE lval[], LVALUE lval2[]); +int constant (int *val); +bool number (int *val); +bool const_expr (int *num, char *, char *); +bool pstr (int *val); +bool qstr (int *val); +bool const_str (int *val, const char *str); +bool readqstr (void); +bool readstr (void); +char spechar (void); + +int match_type (struct type_type *, int do_ptr, int allow_unk_compound); + +#endif diff --git a/src/hucc/pseudo.c b/src/hucc/pseudo.c new file mode 100644 index 00000000..7beb81e9 --- /dev/null +++ b/src/hucc/pseudo.c @@ -0,0 +1,1005 @@ +/* + * pseudo.c + */ + +#include +#include +#include +#include +#include "data.h" +#include "defs.h" +#include "code.h" +#include "const.h" +#include "error.h" +#include "io.h" +#include "lex.h" +#include "optimize.h" +#include "primary.h" +#include "pseudo.h" +#include "sym.h" + + +/* local array to store internal strings */ +static char str_buf[0x10000]; +static int str_idx; + +/* protos */ +char *new_string (int und, char *a); +void do_inc_ex (int type); + +/* + * This source file includes all kind of stuff used to 'simulate' pseudo code + * of the magic kit and so using itself pseudo C functions... + */ +void dopsdinc (void) +{ + int dummy; /* Used in the qstr function, I don't know its utility yet */ + int numericarg = 0; /* Number of numeric arg to test validity */ + + if (amatch("pal", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incpal\t\t\""); + + if (readqstr() == 0) { + /* read the filename */ + error("bad filename in incpal"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if (numericarg > 2) + error("Maximum 2 numeric arg for incpal(name,\"filename\" [,start_pal] [,nb_pal])"); + + kill(); + } + else + if (amatch("bin", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CUCHAR); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incbin\t\t\""); + if (readqstr() == 0) { + /* read the filename */ + error("bad filename in incbin"); + kill(); + return; + } + outstr(litq2); + outstr("\"\n"); + + if (!match(")")) + error("missing )"); + + nl(); + ol(".code"); + kill(); + } + else + if (amatch("bat", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incbat\t\t\""); + + if (readqstr() == 0) { + error("bad filename in incbat"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 1) && + (numericarg != 3) && + (numericarg != 5)) + error("Either 1,3 or 5 numeric arguments are needed for incbat statement"); + + kill(); + } + else + if (amatch("spr", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incspr\t\t\""); + + if (readqstr() == 0) { + error("bad filename in incspr"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 0) && + (numericarg != 2) && + (numericarg != 4)) + error("Either 0,2 or 4 numeric arguments are needed for incspr statement"); + + kill(); + } + else + if (amatch("sprpal", 6)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incsprpal\t\""); + + if (readqstr() == 0) { + error("bad filename in incsprpal"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 0) && + (numericarg != 2) && + (numericarg != 4)) + error("Either 0,2 or 4 numeric arguments are needed for incsprpal statement"); + + kill(); + } + else + if (amatch("chr", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incchr\t\t\""); + + if (readqstr() == 0) { + error("bad filename in incchr"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 0) && + (numericarg != 2) && + (numericarg != 4)) + error("Either 0,2 or 4 numeric arguments are needed for incchr statement"); + + kill(); + } + else + if (amatch("chrpal", 6)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".incchrpal\t\""); + + if (readqstr() == 0) { + error("bad filename in incchrpal"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 0) && + (numericarg != 2) && + (numericarg != 4)) + error("Either 0,2 or 4 numeric arguments are needed for incchrpal statement"); + + kill(); + } + else + if (amatch("chr_ex", 6)) + do_inc_ex(8); + else + if (amatch("tile", 4)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".inctile\t\""); + + if (readqstr() == 0) { + error("bad filename in inctile"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 0) && + (numericarg != 2) && + (numericarg != 4)) + error("Either 0,2 or 4 numeric arguments are needed for inctile statement"); + + kill(); + } + else + if (amatch("tilepal", 7)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + ol(".if\t\t(* & $1FFF) > $1F00"); + ol(".align\t\t$2000"); + ol(".endif"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":\n"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".inctilepal\t\""); + + if (readqstr() == 0) { + error("bad filename in inctilepal"); + kill(); + return; + } + + outstr(litq2); + outstr("\""); + + if (match(",")) + outstr(", "); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + outdec(dummy); + if (match(",")) + outstr(", "); + } + + nl(); + ol(".code"); + + if ((numericarg != 0) && + (numericarg != 2) && + (numericarg != 4)) + error("Either 0,2 or 4 numeric arguments are needed for inctilepal statement"); + + kill(); + } + else + if (amatch("tile_ex", 7)) + do_inc_ex(16); + else + if (amatch("asmlabel", 8)) { + if (!match("(")) + error("missing ("); + + // .data first! + nl(); + ol(".code"); + + // Get the label, but save it for later. + readstr(); + strcpy(str_buf, litq2); + addglb_far(litq2, CUCHAR); + + if (!match(",")) { + error("asmlabel missing ,"); + kill(); + return; + } + + // Get the file name + if (readqstr() == 0) { + error("bad filename in incasm"); + kill(); + return; + } + + // If page argument, then get it. Else default it. + if (match(",")) { + if (number(&dummy) != 0) { + ot(".page\t\t"); + if (dummy > 8) + outdec(dummy / 0x2000); + else + outdec(dummy); + nl(); + } + else { + error("missing page number/address"); + kill(); + return; + } + } + else { + ol(".page\t\t2"); + } + + // Output the label name: + prefix(); + outstr(str_buf); + outstr(":\n"); + + ot(".include\t\""); + outstr(litq2); + outstr("\""); + nl(); + + ol(".page\t\t7"); /* assumes code bank is mapped at 0xE000 */ + + if (!match(")")) + error("missing )"); + nl(); + kill(); + } + else + if (amatch("asm", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + if (readqstr() == 0) { + error("bad filename in incasm"); + kill(); + return; + } + + if (match(",")) { + if (number(&dummy) != 0) { + ot(".page\t\t"); + if (dummy > 8) + outdec(dummy / 0x2000); + else + outdec(dummy); + nl(); + } + else { + error("missing page number/address"); + kill(); + return; + } + } + + ot(".include\t\""); + outstr(litq2); + outstr("\""); + nl(); + + ol(".page\t\t3"); /* assumes data bank is mapped at 0x6000 */ + + if (!match(")")) + error("missing )"); + ol(".code"); + kill(); + } + else { + error("Unknown include directive"); + kill(); + } + return; +} + + +void dopsddef (void) +{ + int numericarg = 0; + int dummy; + int dummy_array[16]; + int i; + + if (amatch("pal", 3)) { + if (!match("(")) + error("missing ("); + + readstr(); /* read the label name */ + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ',' in #defpal"); + kill(); + return; + } + + numericarg = 0; + + while (!match(")")) { + number(&dummy_array[numericarg]); + numericarg++; + + if (numericarg > 16) + error("No more than 16 colors can be defined at once"); + + match(","); + } + + ol(".data"); + prefix(); + outstr(litq2); + outstr(":"); + ot(".defpal\t\t"); + + for (i = 0; i < numericarg; i++) { + outhexfix(dummy_array[i], 3); + + if (i < numericarg - 1) { + outstr(", "); + if (i == 7) { + outstr(" \\\n"); + ot("\t"); + } + } + } + + nl(); + ol(".code"); + + kill(); + } + else + if (amatch("chr", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".defchr\t\t"); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + + switch (numericarg) { + case 1: + outhexfix(dummy, 4); + outstr(", "); + break; + case 2: + outdec(dummy); + outstr(",\\"); + nl(); + break; + case 10: + outhexfix(dummy, 8); + break; + default: + outhexfix(dummy, 8); + outstr(",\\"); + nl(); + } + + match(","); + } + + nl(); + ol(".code"); + + if (numericarg != 10) + error("You must enter the VRAM address, the default palette and 8 values for pattern"); + + kill(); + } + else + if (amatch("spr", 3)) { + if (!match("(")) + error("missing ("); + + ol(".data"); + + readstr(); /* read the label name */ + prefix(); + outstr(litq2); + outstr(":"); + addglb_far(litq2, CINT); + + if (!match(",")) { + error("missing ,"); + kill(); + return; + } + + ot(".defspr\t\t"); + + numericarg = 0; + + while (!match(")")) { + numericarg++; + + number(&dummy); + + switch (numericarg) { + case 1: + outhexfix(dummy, 4); + outstr(", "); + break; + case 2: + outdec(dummy); + outstr(",\\"); + nl(); + break; + case 34: + outhexfix(dummy, 8); + break; + default: + outhexfix(dummy, 8); + outstr(", "); + + if (!(numericarg & 1)) { + outstr("\\"); + nl(); + } + } + + match(","); + } + + nl(); + ol(".code"); + + if (numericarg != 34) + error("You must enter the VRAM address, the default palette and 32 values for pattern"); + + kill(); + } + else { + error("Unknown define directive"); + kill(); + } + return; +} + +void do_asm_func (int type) +{ + /* syntax is + name of the data : identifier + */ + char n[NAMESIZE]; + char *ptr; + + /* get identifier */ + if (!symname(n)) { + error("invalid identifier"); + kill(); + return; + } + + /* close function */ + needbracket(")"); + + /* duplicate identifier */ + ptr = new_string(1, n); + + /* gen code */ + if (ptr) + out_ins(I_LD_WI, type, (intptr_t)ptr); + else + error("out of memory"); +} + +char *new_string (int und, char *a) +{ + int len; + int tmp; + + if (a == NULL) + return (NULL); + + len = (int)strlen(a); + tmp = str_idx; + if ((len + str_idx) > 0xFFF0) + return (NULL); + + if (und) + str_buf[str_idx++] = '_'; + strcpy(&str_buf[str_idx], a); + str_idx += len; + str_buf[str_idx++] = '\0'; + return (&str_buf[tmp]); +} + +void do_inc_ex (int type) +{ + int end; + int i; + int j; + int num; + int nb_tile; + char label[NAMESIZE]; + char label2[NAMESIZE]; + char str[NAMESIZE + 32]; + + struct { + char fname[FILENAMESIZE]; + int arg[5]; + } tiles[16]; + + if (!match("(")) { + error("missing '('"); + kill(); + return; + } + + readstr(); /* read the label name */ + strcpy(label, litq2); + strcpy(label2, litq2); + strcpy(str, "__data__"); + strcat(label2, str); + addglb(label2, ARRAY, CINT, 0, EXTERN, 0); + addglb(label, ARRAY, CINT, 0, EXTERN, 0); + + if (!match(",")) { + error("comma missing"); + kill(); + return; + } + + end = 0; + num = 0; + nb_tile = 0; + while (!end) { + if (match("\\")) {}; + if (!readqstr()) { + error("not a file name"); + kill(); + return; + } + if (!match(",")) { + error("comma missing"); + kill(); + return; + } + strcpy(tiles[num].fname, litq2); + + for (i = 0; i < 5; i++) { + if (match("\\")) {}; + if (!number(&tiles[num].arg[i])) { + error("not a number"); + kill(); + return; + } + if (match(")")) { + if (i == 4) { + kill(); + end = 1; + break; + } + else { + error("arg missing"); + kill(); + return; + } + } + if (!match(",")) { + error("comma missing"); + kill(); + return; + } + while ((ch() == ' ') || (ch() == '\t')) + gch(); + if (ch() == '\0') { + error("arg missing"); + kill(); + return; + } + } + nb_tile += tiles[num].arg[2] * tiles[num].arg[3]; + num++; + if (num == 16) { + if (!end) { + error("too many args (max 16 files)"); + kill(); + return; + } + } + } + + /* create const array to hold extra infos */ + new_const(); + const_val[const_val_idx++] = const_data_idx; /* number of tile */ + sprintf(str, "%i", nb_tile); + add_buffer(str, '(', 1); + const_data[const_data_idx++] = '\0'; + const_val[const_val_idx++] = const_data_idx; /* tile size */ + sprintf(str, "%i", (int)type); + add_buffer(str, '(', 1); + const_data[const_data_idx++] = '\0'; + const_val[const_val_idx++] = const_data_idx; /* tile bank */ + sprintf(str, "BANK(_%s)", label2); + add_buffer(str, '(', 1); + const_data[const_data_idx++] = '\0'; + const_val[const_val_idx++] = const_data_idx; /* tile addr */ + sprintf(str, " _%s", label2); + add_buffer(str, '(', 1); + const_data[const_data_idx++] = '\0'; + const_val[const_val_idx++] = -(litptr + 1024); /* pal idx table addr */ + add_const(CINT); + + /* create pal idx table */ + for (i = 0; i < num; i++) { + j = tiles[i].arg[2] * tiles[i].arg[3]; + while (j) { + j--; + if (litptr < LITMAX) + litq[litptr++] = (tiles[i].arg[4] << 4); + } + } + + /* dump incchr/tile cmds */ + ol(".data"); + prefix(); + outstr(label2); + outstr(":\n"); + for (i = 0; i < num; i++) { + if (type == 8) + ot(".incchr\t\t\""); + else + ot(".inctile\t\""); + outstr(tiles[i].fname); + outstr("\""); + for (j = 0; j < 4; j++) { + outstr(", "); + outdec(tiles[i].arg[j]); + } + nl(); + } + ol(".code"); + kill(); +} diff --git a/src/hucc/pseudo.h b/src/hucc/pseudo.h new file mode 100644 index 00000000..c39474ef --- /dev/null +++ b/src/hucc/pseudo.h @@ -0,0 +1,13 @@ +/* + * pseudo.h + */ + +#ifndef _PSEUDO_H +#define _PSEUDO_H + +void dopsdinc (void); +void dopsddef (void); +void do_asm_func (int type); +char *new_string (int und, char *a); + +#endif diff --git a/src/hucc/stmt.c b/src/hucc/stmt.c new file mode 100644 index 00000000..95cfca62 --- /dev/null +++ b/src/hucc/stmt.c @@ -0,0 +1,638 @@ +/* File stmt.c: 2.1 (83/03/20,16:02:17) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "enum.h" +#include "error.h" +#include "expr.h" +#include "gen.h" +#include "io.h" +#include "lex.h" +#include "preproc.h" +#include "primary.h" +#include "stmt.h" +#include "sym.h" +#include "while.h" +#include "struct.h" +#include "optimize.h" + +/* + * statement parser + * + * called whenever syntax requires a statement. this routine + * performs that statement and returns a number telling which one + * + * 'func' is true if we require a "function_statement", which + * must be compound, and must contain "statement_list" (even if + * "declaration_list" is omitted) + */ +int statement (int func) +{ + if ((ch() == 0) & feof(input)) + return (0); + + lastst = 0; + if (func) { + top_level_stkp = 1; /* uninitialized */ + if (match("{")) { + compound(YES); + return (lastst); + } + else + error("function requires compound statement"); + } + if (match("{")) + compound(NO); + else + stst(); + return (lastst); +} + +/* + * declaration + */ +int stdecl (void) +{ + if (amatch("register", 8)) + doldcls(DEFAUTO); + else if (amatch("auto", 4)) + doldcls(DEFAUTO); + else if (amatch("static", 6)) + doldcls(LSTATIC); + else if (doldcls(AUTO)) ; + else + return (NO); + + return (YES); +} + +int doldcls (int stclass) +{ + struct type_type t; + + blanks(); + /* we don't do optimizations that would require "volatile" */ + if (match_type(&t, NO, YES)) { +#if ULI_NORECURSE == 0 + if (norecurse && stclass != LSTATIC) + stclass = LSTATIC | WASAUTO; +#endif + if (t.type_type == CSTRUCT && t.otag == -1) + t.otag = define_struct(t.sname, stclass, !!(t.flags & F_STRUCT)); + if (t.type_type == CVOID) { + blanks(); + if (ch() != '*') { + error("illegal type \"void\""); + junk(); + return (0); + } + } + if (t.type_type == CENUM) { + if (t.otag == -1) + t.otag = define_enum(t.sname, stclass); + t.type_type = enum_types[t.otag].base; + } + declloc(t.type_type, stclass, t.otag); + } + else + return (0); + + needsemicolon(); + return (1); +} + + +/* + * non-declaration statement + */ +void stst (void) +{ + if (amatch("if", 2)) { + doif(); + lastst = STIF; + } + else if (amatch("while", 5)) { + dowhile(); + lastst = STWHILE; + } + else if (amatch("switch", 6)) { + doswitch(); + lastst = STSWITCH; + } + else if (amatch("do", 2)) { + dodo(); + needsemicolon(); + lastst = STDO; + } + else if (amatch("for", 3)) { + dofor(); + lastst = STFOR; + } + else if (amatch("return", 6)) { + doreturn(); + needsemicolon(); + lastst = STRETURN; + } + else if (amatch("break", 5)) { + dobreak(); + needsemicolon(); + lastst = STBREAK; + } + else if (amatch("continue", 8)) { + docont(); + needsemicolon(); + lastst = STCONT; + } + else if (amatch("goto", 4)) { + dogoto(); + needsemicolon(); + lastst = STGOTO; + } + else if (match(";")) + ; + else if (amatch("case", 4)) { + docase(); + lastst = statement(NO); + } + else if (amatch("default", 7)) { + dodefault(); + lastst = statement(NO); + } + else if (match("#asm")) { + doasm(); + lastst = STASM; + } + else if (match("{")) + compound(NO); + else { + int slptr = lptr; + char lbl[NAMESIZE]; + if (symname(lbl) && ch() == ':') { + gch(); + dolabel(lbl); + lastst = statement(NO); + } + else { + lptr = slptr; + expression(YES); + needsemicolon(); + lastst = STEXP; + } + } + gfence(); +} + +/* + * compound statement + * + * allow any number of statements to fall between "{" and "}" + * + * 'func' is true if we are in a "function_statement", which + * must contain "statement_list" + */ +void compound (int func) +{ + int decls; + + decls = YES; + ncmp++; + /* remember stack pointer before entering the first compound + statement inside a function */ +#if ULI_NORECURSE + if (!func && top_level_stkp == 1 && !norecurse) +#else + if (!func && top_level_stkp == 1) +#endif + top_level_stkp = stkp; + while (!match("}")) { + if (feof(input)) + return; + + if (decls) { + if (!stdecl()) { + decls = NO; + gtext(); + } + } + else + stst(); + } + ncmp--; +} + +/* + * "if" statement + */ +void doif (void) +{ + int fstkp, flab1, flab2; + int flev; + + flev = locsym_index; + fstkp = stkp; + flab1 = getlabel(); + test(flab1, FALSE); + statement(NO); + stkp = modstk(fstkp); + locsym_index = flev; + if (!amatch("else", 4)) { + gnlabel(flab1); + return; + } + jump(flab2 = getlabel()); + gnlabel(flab1); + statement(NO); + stkp = modstk(fstkp); + locsym_index = flev; + gnlabel(flab2); +} + +/* + * "while" statement + */ +void dowhile (void) +{ + int ws[WS_COUNT]; + + ws[WS_LOCSYM_INDEX] = locsym_index; + ws[WS_STACK_OFFSET] = stkp; + ws[WS_TYPE] = WS_WHILE; + ws[WS_TEST_LABEL] = getlabel(); + ws[WS_EXIT_LABEL] = getlabel(); + addwhile(ws); + gnlabel(ws[WS_TEST_LABEL]); + test(ws[WS_EXIT_LABEL], FALSE); + statement(NO); + jump(ws[WS_TEST_LABEL]); + gnlabel(ws[WS_EXIT_LABEL]); + locsym_index = ws[WS_LOCSYM_INDEX]; + stkp = modstk(ws[WS_STACK_OFFSET]); + delwhile(); +} + +/* + * "do" statement + */ +void dodo (void) +{ + int ws[WS_COUNT]; + + ws[WS_LOCSYM_INDEX] = locsym_index; + ws[WS_STACK_OFFSET] = stkp; + ws[WS_TYPE] = WS_DO; + ws[WS_BODY_LABEL] = getlabel(); + ws[WS_TEST_LABEL] = getlabel(); + ws[WS_EXIT_LABEL] = getlabel(); + addwhile(ws); + gnlabel(ws[WS_BODY_LABEL]); + statement(NO); + if (!match("while")) { + error("missing while"); + return; + } + gnlabel(ws[WS_TEST_LABEL]); + test(ws[WS_BODY_LABEL], TRUE); + gnlabel(ws[WS_EXIT_LABEL]); + locsym_index = ws[WS_LOCSYM_INDEX]; + stkp = modstk(ws[WS_STACK_OFFSET]); + delwhile(); +} + +/* + * "for" statement + */ +void dofor (void) +{ + int ws[WS_COUNT], *pws; + + ws[WS_LOCSYM_INDEX] = locsym_index; + ws[WS_STACK_OFFSET] = stkp; + ws[WS_TYPE] = WS_FOR; + ws[WS_TEST_LABEL] = getlabel(); + ws[WS_INCR_LABEL] = getlabel(); + ws[WS_BODY_LABEL] = getlabel(); + ws[WS_EXIT_LABEL] = getlabel(); + addwhile(ws); + pws = readwhile(); + needbracket("("); + if (!match(";")) { + expression(YES); + needsemicolon(); + gfence(); + } + gnlabel((int)pws[WS_TEST_LABEL]); + if (!match(";")) { + expression(YES); + testjump(pws[WS_BODY_LABEL], TRUE); + jump(pws[WS_EXIT_LABEL]); + needsemicolon(); + } + else + pws[WS_TEST_LABEL] = pws[WS_BODY_LABEL]; + gnlabel(pws[WS_INCR_LABEL]); + if (!match(")")) { + expression(YES); + needbracket(")"); + gfence(); + jump(pws[WS_TEST_LABEL]); + } + else + pws[WS_INCR_LABEL] = pws[WS_TEST_LABEL]; + gnlabel(pws[WS_BODY_LABEL]); + statement(NO); + stkp = modstk(pws[WS_STACK_OFFSET]); + jump(pws[WS_INCR_LABEL]); + gnlabel(pws[WS_EXIT_LABEL]); + locsym_index = pws[WS_LOCSYM_INDEX]; + delwhile(); +} + +/* + * "switch" statement + */ +void doswitch (void) +{ + int ws[WS_COUNT]; + int *ptr; + bool auto_default = false; + + ws[WS_LOCSYM_INDEX] = locsym_index; + ws[WS_STACK_OFFSET] = stkp; + ws[WS_TYPE] = WS_SWITCH; + ws[WS_CASE_INDEX] = swstp; + ws[WS_TABLE_LABEL] = getlabel(); + ws[WS_DEFAULT_LABEL] = ws[WS_EXIT_LABEL] = getlabel(); + addwhile(ws); + needbracket("("); + expression(YES); + needbracket(")"); + gswitch(ws[WS_TABLE_LABEL]); + statement(NO); + + ptr = readswitch(); + jump(ptr[WS_EXIT_LABEL]); + + if (ptr[WS_DEFAULT_LABEL] == ptr[WS_EXIT_LABEL]) { + ptr[WS_DEFAULT_LABEL] = getlabel(); + auto_default = true; + } + dumpswitch(ptr); + if (auto_default) { + gnlabel((int)ptr[WS_DEFAULT_LABEL]); + out_ins(I_CASE, 0, 0); + } + + gnlabel(ptr[WS_EXIT_LABEL]); + locsym_index = ptr[WS_LOCSYM_INDEX]; + stkp = modstk(ptr[WS_STACK_OFFSET]); + swstp = ptr[WS_CASE_INDEX]; + delwhile(); +} + +/* + * "case" label + */ +void docase (void) +{ + int val; + char n[NAMESIZE]; + + val = 0; + if (readswitch()) { + if (!number(&val)) + if (!pstr(&val)) + if (!(symname(n) && find_enum(n, &val))) + error("bad case label"); + addcase(val); + if (!match(":")) + error("missing colon"); + } + else + error("no active switch"); +} + +/* + * "default" label + */ +void dodefault (void) +{ + int *ptr; + int lab; + + ptr = readswitch(); + if (ptr) { + ptr[WS_DEFAULT_LABEL] = lab = getlabel(); + gcase(lab, INT_MAX); + if (!match(":")) + error("missing colon"); + } + else + error("no active switch"); +} + +/* + * "return" statement + */ +void doreturn (void) +{ + /* Jumping to fexitlab will clean up the top-level stack, + but we may have added additional stack variables in + an inner compound statement, and if so we have to + clean those up as well. */ + if (top_level_stkp != 1 && stkp != top_level_stkp) + modstk(top_level_stkp); + + if (endst() == 0) + expression(YES); + + jump(fexitlab); +} + +/* + * "break" statement + */ +void dobreak (void) +{ + int *ptr; + + if ((ptr = readwhile()) == 0) + return; + + modstk(ptr[WS_STACK_OFFSET]); + jump(ptr[WS_EXIT_LABEL]); +} + +/* + * "continue" statement + */ +void docont (void) +{ + int *ptr; + + if ((ptr = findwhile()) == 0) + return; + + modstk(ptr[WS_STACK_OFFSET]); + if (ptr[WS_TYPE] == WS_FOR) + jump(ptr[WS_INCR_LABEL]); + else + jump(ptr[WS_TEST_LABEL]); +} + +void dolabel (char *name) +{ + int i; + + for (i = 0; i < clabel_ptr; i++) { + if (!strcmp(clabels[i].name, name)) { + /* This label has been goto'd to before. + We have to create a stack pointer offset EQU + that describes the stack pointer difference from + the goto to here. */ + sprintf(name, "LL%d_stkp", clabels[i].label); + /* XXX: memleak */ + out_ins_ex(I_DEF, T_LITERAL, (intptr_t)strdup(name), + T_VALUE, stkp - clabels[i].stkp); + /* From now on, clabel::stkp contains the relative + stack pointer at the location of the label. */ + clabels[i].stkp = stkp; + gnlabel(clabels[i].label); +// printf("old label %s stkp %ld\n", clabels[i].name, (long) stkp); + return; + } + } + /* This label has not been referenced before, we need to create a + new entry. */ + clabels = realloc(clabels, (clabel_ptr + 1) * sizeof(struct clabel)); + strcpy(clabels[clabel_ptr].name, name); + clabels[clabel_ptr].stkp = stkp; + clabels[clabel_ptr].label = getlabel(); +// printf("new label %s id %d stkp %ld\n", name, clabels[clabel_ptr].label, (long) stkp); + gnlabel(clabels[clabel_ptr].label); + clabel_ptr++; +} + +void dogoto (void) +{ + int i; + char sname[NAMESIZE]; + + if (!symname(sname)) { + error("invalid label name"); + return; + } + for (i = 0; i < clabel_ptr; i++) { + if (!strcmp(clabels[i].name, sname)) { + /* This label has already been defined. All we have + to do is to adjust the stack pointer and jump. */ + printf("goto found label %s id %d stkp %d\n", sname, clabels[i].label, clabels[i].stkp); + modstk(clabels[i].stkp); + jump(clabels[i].label); + return; + } + } + + /* This label has not been defined yet. We have to create a new + entry in the label array. We also don't know yet what the relative + SP will be at the label, so we have to emit a stack pointer + operation with a symbolic operand that will be defined to the + appropriate value at the label definition. */ + clabels = realloc(clabels, (i + 1) * sizeof(*clabels)); + strcpy(clabels[i].name, sname); + /* Save our relative SP in the label entry; this will be corrected + to the label's relative SP at the time of definition. */ + clabels[i].stkp = stkp; + clabels[i].label = getlabel(); + sprintf(sname, "LL%d_stkp", clabels[i].label); + /* XXX: memleak */ + out_ins(I_MODSP, T_LITERAL, (intptr_t)strdup(sname)); + jump(clabels[i].label); + clabel_ptr++; +} + +/* + * dump switch table + * + * case_table: + * + 0 db 6 ; #bytes of case values. + * + 12 dw val1 + * + 34 dw val2 + * + 56 dw val3 + * + 78 dw jmpdefault + * + 9A dw jmp1 + * + BC dw jmp2 + * + DE dw jmp3 + */ +void dumpswitch (int *ws) +{ + int i, j, column; + + gnlabel(ws[WS_TABLE_LABEL]); + flush_ins(); + + i = ws[WS_CASE_INDEX]; + + if ((swstp - i) > 63) { + error("too many case statements in switch(), there must be less than 64"); + return; + } + + defbyte(); + outdec((swstp - i) << 1); + nl(); + + j = swstp; + while (j > i) { + defbyte(); + column = 8; + while (column--) { + outbyte('>'); + outdec(swstcase[--j]); + outbyte(','); + outbyte('<'); + outdec(swstcase[j]); + if ((column == 0) | (j == i)) { + nl(); + break; + } + outbyte(','); + } + } + + defword(); + outlabel(ws[WS_DEFAULT_LABEL]); + nl(); + + j = swstp; + while (j > i) { + defword(); + column = 8; + while (column--) { + outlabel(swstlabel[--j]); + if ((column == 0) | (j == i)) { + nl(); + break; + } + outbyte(','); + } + } + nl(); +} + +void test (int label, int ft) +{ + needbracket("("); + expression(YES); + needbracket(")"); + testjump(label, ft); +} diff --git a/src/hucc/stmt.h b/src/hucc/stmt.h new file mode 100644 index 00000000..03668151 --- /dev/null +++ b/src/hucc/stmt.h @@ -0,0 +1,30 @@ +/* File stmt.c: 2.1 (83/03/20,16:02:17) */ +/*% cc -O -c % + * + */ + + +#ifndef _STMT_H +#define _STMT_H + +int statement (int func); +int stdecl (void); +int doldcls (int stclass); +void stst (void); +void compound (int func); +void doif (void); +void dowhile (void); +void dodo (void); +void dofor (void); +void doswitch (void); +void docase (void); +void dodefault (void); +void doreturn (void); +void dobreak (void); +void docont (void); +void dolabel (char *name); +void dogoto (void); +void dumpswitch (int *ws); +void test (int label, int ft); + +#endif diff --git a/src/hucc/struct.c b/src/hucc/struct.c new file mode 100644 index 00000000..9444c000 --- /dev/null +++ b/src/hucc/struct.c @@ -0,0 +1,121 @@ +/* + * File struct.c: (12/12/12,21:31:33) + */ + +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "lex.h" +#include "error.h" +#include "main.h" + +/** + * look up a tag in tag table by name + * @param sname + * @return index + */ +int find_tag (char *sname) +{ + int index; + + index = 0; + while (index < tag_table_index) { + if (astreq(sname, tag_table[index].name, NAMEMAX)) + return (index); + + ++index; + } + return (-1); +} + +/** + * determine if 'sname' is a member of the struct with tag 'tag' + * @param tag + * @param sname + * @return pointer to member symbol if it is, else 0 + */ +SYMBOL *find_member (TAG_SYMBOL *tag, char *sname) +{ + int member_idx; + + member_idx = tag->member_idx; + + while (member_idx < tag->member_idx + tag->number_of_members) { + if (strcmp(member_table[member_idx].name, sname) == 0) + return (&member_table[member_idx]); + + ++member_idx; + } + return (0); +} + +/** + * add new structure member to table + * @param sname + * @param identity - variable, array, pointer, function + * @param typ + * @param offset + * @param storage + * @return + */ +void add_member (char *sname, char identity, char type, int offset, int storage_class, int otag, int ptr_order, int funcptr_type, int funcptr_order, int arg_count) +{ + char *buffer_ptr; + SYMBOL *symbol; + + if (member_table_index >= NUMMEMB) { + error("symbol table overflow"); + return; + } + symbol = &member_table[member_table_index]; + buffer_ptr = symbol->name; + while (alphanum(*buffer_ptr++ = *sname++)) ; + symbol->identity = identity; + symbol->sym_type = type; + symbol->storage = storage_class; + symbol->offset = offset; + symbol->ptr_order = ptr_order; + symbol->funcptr_type = funcptr_type; + symbol->funcptr_order = funcptr_order; + symbol->arg_count = arg_count; + + if (type == CSTRUCT) + symbol->tagidx = otag; + + member_table_index++; +} + +int define_struct (char *sname, int storage, int is_struct) +{ + TAG_SYMBOL *symbol; + char *buffer_ptr; + int tti; + + // tag_table_index++; + if (tag_table_index >= NUMTAG) { + error("struct table overflow"); + return (0); + } + tti = tag_table_index++; + symbol = &tag_table[tti]; + buffer_ptr = symbol->name; + while (alphanum(*buffer_ptr++ = *sname++)) ; + symbol->size = 0; + symbol->member_idx = member_table_index; + + needbracket("{"); + while (!match("}")) { + if (!dodcls(storage, &tag_table[tti], is_struct)) + break; + /* We need to keep number_of_members up-to-date to make sure that + find_member() works so we can catch duplicate member names. */ + symbol->number_of_members = member_table_index - symbol->member_idx; + } + ; + /* XXX: still necessary? */ + symbol->number_of_members = member_table_index - symbol->member_idx; + return (tti); +} diff --git a/src/hucc/struct.h b/src/hucc/struct.h new file mode 100644 index 00000000..aeeae10b --- /dev/null +++ b/src/hucc/struct.h @@ -0,0 +1,3 @@ +int find_tag (char *sname); +int define_struct (char *sname, int storage, int is_struct); +void add_member (char *sname, char identity, char type, int offset, int storage_class, int otag, int ptr_order, int funcptr_type, int funcptr_order, int arg_count); diff --git a/src/hucc/sym.c b/src/hucc/sym.c new file mode 100644 index 00000000..4e2ae5c9 --- /dev/null +++ b/src/hucc/sym.c @@ -0,0 +1,759 @@ +/* File sym.c: 2.1 (83/03/20,16:02:19) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "code.h" +#include "const.h" +#include "error.h" +#include "gen.h" +#include "initials.h" +#include "io.h" +#include "lex.h" +#include "primary.h" +#include "pragma.h" +#include "sym.h" +#include "function.h" +#include "struct.h" + +/** + * evaluate one initializer, add data to table + * @param symbol_name + * @param type + * @param identity + * @param dim + * @param tag + * @return + */ +static int init (char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL *tag) +{ + int value; + int number_of_chars; + + if (identity == POINTER) { + error("initializing non-const pointers unimplemented"); + kill(); + return (0); + } + + if (qstr(&value)) { + if ((identity == VARIABLE) || (type != CCHAR && type != CUCHAR)) + error("found string: must assign to char pointer or array"); /* XXX: make this a warning? */ + if (identity == POINTER) { + /* unimplemented */ + printf("initptr %s value %ld\n", symbol_name, (long) value); + abort(); + // add_data_initials(symbol_name, CUINT, value, tag); + } + else { + number_of_chars = litptr - value; + *dim = *dim - number_of_chars; + while (number_of_chars > 0) { + add_data_initials(symbol_name, CCHAR, litq[value++], tag); + number_of_chars = number_of_chars - 1; + } + } + } + else if (number(&value)) { + add_data_initials(symbol_name, CINT, value, tag); + *dim = *dim - 1; + } + else if (qstr(&value)) { + add_data_initials(symbol_name, CCHAR, value, tag); + *dim = *dim - 1; + } + else + return (0); + + return (1); +} + +/** + * initialise structure + * @param tag + */ +void struct_init (TAG_SYMBOL *tag, char *symbol_name) +{ + int dim; + int member_idx; + + member_idx = tag->member_idx; + while (member_idx < tag->member_idx + tag->number_of_members) { + init(symbol_name, member_table[tag->member_idx + member_idx].sym_type, + member_table[tag->member_idx + member_idx].identity, &dim, tag); + ++member_idx; + if ((match(",") == 0) && (member_idx != (tag->member_idx + tag->number_of_members))) { + error("struct initialisaton out of data"); + break; + } + } +} + +/** + * initialize global objects + * @param symbol_name + * @param type char or integer or struct + * @param identity + * @param dim + * @return 1 if variable is initialized + */ +int initials (char *symbol_name, int type, int identity, int dim, int otag) +{ + int dim_unknown = 0; + + if (dim == 0) // allow for xx[] = {..}; declaration + dim_unknown = 1; + if (match("=")) { + if (type != CCHAR && type != CUCHAR && type != CINT && type != CUINT && type != CSTRUCT) + error("unsupported storage size"); + // an array or struct + if (match("{")) { + // aggregate initialiser + if ((identity == POINTER || identity == VARIABLE) && type == CSTRUCT) { + // aggregate is structure or pointer to structure + dim = 0; + struct_init(&tag_table[otag], symbol_name); + } + else { + while ((dim > 0) || dim_unknown) { + if (identity == ARRAY && type == CSTRUCT) { + // array of struct + needbracket("{"); + struct_init(&tag_table[otag], symbol_name); + --dim; + needbracket("}"); + } + else { + if (init(symbol_name, type, identity, &dim, 0)) + dim_unknown++; + } + if (match(",") == 0) + break; + } + } + needbracket("}"); + // single constant + } + else + init(symbol_name, type, identity, &dim, 0); + } + return (identity); +} + + +/* + * declare a static variable + * + * David, added support for const arrays and improved error detection + * + */ +int declglb (char typ, char stor, TAG_SYMBOL *mtag, int otag, int is_struct) +{ + int k, id; + char sname[NAMESIZE]; + char typ_now; + int ptr_order; + int funcptr_type; + int funcptr_order; + int arg_count; + SYMBOL *s; + + for (;;) { + for (;;) { + typ_now = typ; + ptr_order = 0; + funcptr_type = 0; + funcptr_order = 0; + arg_count = -1; + if (endst()) + return (0); + + k = 1; + id = VARIABLE; + while (match("*")) { + id = POINTER; + ptr_order++; + } + if (amatch("__fastcall", 10)) { + newfunc(NULL, ptr_order, typ, otag, 1); + return (2); + } + if (match("(")) { + if (typ == 0) { + error("syntax error, a function pointer must declare its return type"); + typ_now = CINT; + } + funcptr_type = typ_now; + funcptr_order = ptr_order; + typ_now = CUINT; + ptr_order = 0; + while (match("*")) { + id = POINTER; + ptr_order++; + } + if (ptr_order == 0) { + error("syntax error, expected function pointer declaration"); + return (1); + } + id = (--ptr_order) ? POINTER : VARIABLE; + +// if (ptr_order >= 2) { +// error("syntax error, no pointer to a function pointer in HuCC"); +// return (1); +// } + } + + if (!symname(sname)) + illname(); + if (match("(")) { + if (funcptr_type) { + error("syntax error, expected function pointer declaration"); + return (1); + } + newfunc(sname, ptr_order, typ, otag, 0); + return (2); + } + if ((s = findglb(sname))) { + if ((s->storage & STORAGE) != EXTERN && !mtag) + multidef(sname); + } + if (mtag && find_member(mtag, sname)) + multidef(sname); + + if (match("[")) { + k = needsub(); + + if (funcptr_type) { + arg_count = needarguments(); + if (arg_count < 0) { + error("syntax error, expected function pointer declaration"); + junk(); + return (1); + } + } + if (stor == CONST) + k = array_initializer(typ_now, id, stor, k); + if (k == -1) + return (1); + + /* XXX: This doesn't really belong here, but I + can't think of a better place right now. */ + if (id == POINTER && (typ_now == CCHAR || typ_now == CUCHAR || typ_now == CVOID)) + k *= INTSIZE; + if (k || (stor == EXTERN)) + id = ARRAY; + else { + if (stor == CONST) { + error("empty const array"); + id = ARRAY; + } + else if (id == POINTER) + id = ARRAY; + else { + id = POINTER; + ptr_order++; + } + } + } + else { + if (funcptr_type) { + arg_count = needarguments(); + if (arg_count < 0) { + error("syntax error, expected function pointer declaration"); + junk(); + return (1); + } + } + if (stor == CONST) { + /* stor = PUBLIC; XXX: What is this for? */ + scalar_initializer(typ_now, id, stor); + } + } + + if (mtag == 0) { + if (typ_now == CSTRUCT) { + if (id == VARIABLE) + k = tag_table[otag].size; + else if (id == POINTER) + k = INTSIZE; + else if (id == ARRAY) + k *= tag_table[otag].size; + } + if (stor != CONST) { + id = initials(sname, typ_now, id, k, otag); + SYMBOL *c = addglb(sname, id, typ_now, k, stor, s); + if (typ_now == CSTRUCT) + c->tagidx = otag; + c->ptr_order = ptr_order; + c->funcptr_type = funcptr_type; + c->funcptr_order = funcptr_order; + c->arg_count = arg_count; + } + else { + SYMBOL *c = addglb(sname, id, typ_now, k, CONST, s); + if (c) { + add_const(typ_now); + if (typ_now == CSTRUCT) + c->tagidx = otag; + } + c->ptr_order = ptr_order; + c->funcptr_type = funcptr_type; + c->funcptr_order = funcptr_order; + c->arg_count = arg_count; + } + } + else if (is_struct) { + add_member(sname, id, typ_now, mtag->size, stor, otag, ptr_order, funcptr_type, funcptr_order, arg_count); + if (id == POINTER) + typ_now = CUINT; + scale_const(typ_now, otag, &k); + mtag->size += k; + } + else { + add_member(sname, id, typ_now, 0, stor, otag, ptr_order, funcptr_type, funcptr_order, arg_count); + if (id == POINTER) + typ_now = CUINT; + scale_const(typ_now, otag, &k); + if (mtag->size < k) + mtag->size = k; + } + break; + } + if (endst()) + return (0); + + if (!match(",")) { + error("syntax error"); + return (1); + } + } + return (0); +} + +/* + * declare local variables + * + * works just like "declglb", but modifies machine stack and adds + * symbol table entry with appropriate stack offset to find it again + * + * zeo : added "totalk" stuff and global stack modification (00/04/12) + */ +void declloc (char typ, char stclass, int otag) +{ + int k = 0, j; + int elements = 0; + char sname[NAMESIZE]; + int totalk = 0; + + for (;;) { + SYMBOL * sym = NULL; + for (;;) { + int ptr_order = 0; + if (endst()) { + if (!norecurse) + stkp = modstk(stkp - totalk); + return; + } + j = VARIABLE; + while (match("*")) { + j = POINTER; + ptr_order++; + } + if (!symname(sname)) + illname(); + if (findloc(sname)) + multidef(sname); + if (match("[")) { + elements = k = needsub(); + if (k) { + if (typ == CINT || typ == CUINT || j == POINTER) + k = k * INTSIZE; + else if (typ == CSTRUCT) + k *= tag_table[otag].size; + j = ARRAY; + } + else { + j = POINTER; + ptr_order++; + k = INTSIZE; + elements = 1; + } + } + else { + elements = 1; + if ((typ == CCHAR || typ == CUCHAR) & (j != POINTER)) + k = 1; + else if (typ == CSTRUCT) { + if (j == VARIABLE) + k = tag_table[otag].size; + else if (j == POINTER) + k = INTSIZE; + } + else + k = INTSIZE; + } + if ((stclass & STORAGE) == LSTATIC) { + /* Local statics are identified in two + different ways: The human-readable + identifier as given in the source text, + and the internal label that is used in + the assembly output. + + The initializer code wants the label, and + it is also used to add a global to make + sure the right amount of space is + reserved in .bss and the initialized data + is dumped eventually. + + addloc(), OTOH, wants the identifier so + it can be found when referenced further + down in the source text. */ + SYMBOL *loc; + char lsname[NAMESIZE]; + int label = getlabel(); + sprintf(lsname, "SL%d", label); + + /* do static initialization unless from norecurse */ + if ((stclass & WASAUTO) == 0) + j = initials(lsname, typ, j, k, otag); + + /* NB: addglb() expects the number of + elements, not a byte size. Unless, of + course, we have a CSTRUCT. *sigh* */ + if (typ == CSTRUCT) + sym = addglb(lsname, j, typ, k, stclass, 0); + else + sym = addglb(lsname, j, typ, elements, stclass, 0); + + loc = addloc(sname, j, typ, label, stclass, k); + if (typ == CSTRUCT) + loc->tagidx = otag; + loc->ptr_order = ptr_order; + + /* link the local and global symbols together */ + sym->linked = loc; + loc->linked = sym; + } + else { +// k = galign(k); + totalk += k; + // stkp = modstk (stkp - k); + // addloc (sname, j, typ, stkp, AUTO); +#if ULI_NORECURSE + if (!norecurse) + sym = addloc(sname, j, typ, stkp - totalk, AUTO, k); + else + sym = addloc(sname, j, typ, local_offset - totalk, AUTO, k); +#else + sym = addloc(sname, j, typ, stkp - totalk, AUTO, k); +#endif + if (typ == CSTRUCT) + sym->tagidx = otag; + sym->ptr_order = ptr_order; + } + break; + } + if (match("=")) { + int num; + + /* this should have been done in initials() above */ + if (stclass == LSTATIC) + error("initialization of static local variables unimplemented"); + +#if ULI_NORECURSE + if (!norecurse) + stkp = modstk(stkp - totalk); + else + local_offset -= totalk; + totalk -= k; +#else + if (!norecurse) { + stkp = modstk(stkp - totalk); + totalk -= k; + } +#endif + + if (const_expr(&num, ",", ";")) { + gtext(); + if (k == 1) { +#if ULI_NORECURSE + if (norecurse) { + /* XXX: bit of a memory leak, but whatever... */ + SYMBOL * locsym = copysym(sym); + sprintf(locsym->name, "_%s_end - %d", current_fn, -local_offset); + locsym->linked = sym; + out_ins_ex(I_ST_UMIQ, T_SYMBOL, (intptr_t)locsym, T_VALUE, num); + } + else +#else + if (stclass == (LSTATIC | WASAUTO)) { + out_ins_ex(I_ST_UMIQ, T_SYMBOL, (intptr_t)ssym, T_VALUE, num); + } + else +#endif + out_ins_ex(X_ST_USIQ, T_VALUE, 0, T_VALUE, num); + } + else if (k == 2) { +#if ULI_NORECURSE + if (norecurse) { + /* XXX: bit of a memory leak, but whatever... */ + SYMBOL * locsym = copysym(sym); + sprintf(locsym->name, "_%s_end - %d", current_fn, -local_offset); + locsym->linked = sym; + out_ins_ex(I_ST_WMIQ, T_SYMBOL, (intptr_t)locsym, T_VALUE, num); + } + else +#else + if (stclass == (LSTATIC | WASAUTO)) { + out_ins_ex(I_ST_WMIQ, T_SYMBOL, (intptr_t)ssym, T_VALUE, num); + } + else +#endif + out_ins_ex(X_ST_WSIQ, T_VALUE, 0, T_VALUE, num); + } + else + error("complex type initialization not implemented"); + } + else + error("cannot parse initializer"); + } + if (!match(",")) { + if (!norecurse) + stkp = modstk(stkp - totalk); +#if ULI_NORECURSE + else + local_offset -= totalk; +#endif + return; + } + } +} + +/* + * get required array size + */ +int needsub (void) +{ + int num[1]; + + if (match("]")) + return (0); + + if (!const_expr(num, "]", NULL)) { + error("must be constant"); + num[0] = 1; + } + if (!match("]")) + error("internal error"); + if (num[0] < 0) { + error("negative size illegal"); + num[0] = (-num[0]); + } + return (num[0]); +} + +/* + * get definition of function pointer arguments + */ +int needarguments (void) +{ + struct type_type t; + int arg_count = 0; + + if (!match(")")) + return (-1); + if (!match("(")) + return (-1); + if (match(")")) + return (0); + + do { + if (!match_type(&t, YES, NO)) + return (-1); + if (t.type_type == CVOID && t.ptr_order == 0) { + if (arg_count > 0) + return (-1); + break; + } + ++arg_count; + } while (match(",")); + + if (!match(")")) + return (-1); + + return arg_count; +} + +SYMBOL *findglb (char *sname) +{ + SYMBOL *ptr; + + ptr = symtab + STARTGLB; + while (ptr != (symtab + glbsym_index)) { + if (astreq(sname, ptr->name, NAMEMAX)) + return (ptr); + + ptr++; + } + return (NULL); +} + +SYMBOL *findloc (char *sname) +{ + SYMBOL *ptr; + + ptr = symtab + locsym_index; + while (ptr != (symtab + STARTLOC)) { + ptr--; + if (astreq(sname, ptr->name, NAMEMAX)) + return (ptr); + } + return (NULL); +} + +SYMBOL *addglb (char *sname, char id, char typ, int value, char stor, SYMBOL *replace) +{ + char *ptr; + + if (!replace) { + cptr = findglb(sname); + if (cptr) + return (cptr); + + if (glbsym_index >= ENDGLB) { + /* the compiler can't recover from this */ + /* and will write to NULL* if we return */ + errcnt = 0; + error("too many global C symbols, aborting"); + error("fix SYMTBSZ and NUMGLBS then rebuild the compiler"); + exit(1); + } + cptr = symtab + glbsym_index; + glbsym_index++; + } + else + cptr = replace; + memset(cptr, 0, sizeof(SYMBOL)); + + ptr = cptr->name; + while (alphanum(*ptr++ = *sname++)) ; + + cptr->identity = id; + cptr->sym_type = typ; + cptr->storage = stor; + cptr->offset = value; + cptr->alloc_size = value; + cptr->far = 0; + cptr->linked = NULL; + cptr->arg_count = -1; + cptr->ptr_order = 0; + cptr->funcptr_order = 0; + + if (id == FUNCTION) + cptr->alloc_size = 0; + else if (id == POINTER) + cptr->alloc_size = INTSIZE; + else if (typ == CINT || typ == CUINT) + cptr->alloc_size *= 2; + return (cptr); +} + +SYMBOL *addglb_far (char *sname, char typ) +{ + SYMBOL *ptr; + + ptr = addglb(sname, ARRAY, typ, 0, EXTERN, 0); + if (ptr) + ptr->far = 1; + return (ptr); +} + + +SYMBOL *addloc (char *sname, char id, char typ, int value, char stclass, int size) +{ + char *ptr; + + cptr = findloc(sname); + if (cptr) + return (cptr); + + if (locsym_index >= ENDLOC) { + /* the compiler can't recover from this */ + /* and will write to NULL* if we return */ + errcnt = 0; + error("too many local C symbols, aborting"); + error("fix SYMTBSZ and NUMGLBS then rebuild the compiler"); + exit(1); + } + cptr = symtab + locsym_index; + memset(cptr, 0, sizeof(SYMBOL)); + + ptr = symtab[locsym_index].name; + while (alphanum(*ptr++ = *sname++)) ; + + cptr->identity = id; + cptr->sym_type = typ; + cptr->storage = stclass; + cptr->offset = value; + cptr->alloc_size = size; + cptr->linked = NULL; + cptr->arg_count = -1; + locsym_index++; + return (cptr); +} + +/* + * test if next input string is legal symbol name + * + */ +bool symname (char *sname) +{ + int k; + +/* char c; */ + + blanks(); + if (!alpha(ch())) + return (false); + + k = 0; + while (alphanum(ch())) + sname[k++] = gch(); + sname[k] = 0; + return (true); +} + +void illname (void) +{ + error("illegal symbol name"); +} + +void multidef (char *sname) +{ + error("already defined"); + comment(); + outstr(sname); + nl(); +} + +int glint (SYMBOL *sym) +{ + return (sym->offset); +} + +SYMBOL *copysym (SYMBOL *sym) +{ + SYMBOL *ptr = malloc(sizeof(SYMBOL)); + if (ptr == NULL) + error("out of memory to copy symbol"); + else + memcpy(ptr, sym, sizeof(SYMBOL)); + return (ptr); +} diff --git a/src/hucc/sym.h b/src/hucc/sym.h new file mode 100644 index 00000000..ff4ab66c --- /dev/null +++ b/src/hucc/sym.h @@ -0,0 +1,18 @@ +#ifndef _SYM_H +#define _SYM_H + +int declglb (char typ, char stor, TAG_SYMBOL *mtag, int otag, int is_struct); +void declloc (char typ, char stclass, int otag); +int needsub (void); +int needarguments (void); +SYMBOL *findglb (char *sname); +SYMBOL *findloc (char *sname); +SYMBOL *addglb (char *sname, char id, char typ, int value, char stor, SYMBOL *replace); +SYMBOL *addglb_far (char *sname, char typ); +SYMBOL *addloc (char *sname, char id, char typ, int value, char stclass, int size); +bool symname (char *sname); +void illname (void); +void multidef (char *sname); +int glint (SYMBOL *sym); +SYMBOL *copysym (SYMBOL *sym); +#endif diff --git a/src/hucc/uncrustify.cfg b/src/hucc/uncrustify.cfg new file mode 100644 index 00000000..302ed1d3 --- /dev/null +++ b/src/hucc/uncrustify.cfg @@ -0,0 +1,143 @@ +# +# uncrustify config file for HuC +# +# Copyright (c) 2014, Ulrich Hecht +# All rights reserved. +# See LICENSE for details on use and redistribution. +# + +# +# Attempt to find a consistent style that is as close as possible to the +# existing formatting. In some cases the settings deviate from that rule +# if the option is considered a substantial win; those cases are marked +# as "deliberate". +# +# Options that have no effect on the current codebase, but that are +# desirable when an applicable construct appears in the future are +# marked as "no effect". +# + +indent_with_tabs = 2 # ok (1=indent to level only, 2=indent with tabs) +input_tab_size = 8 # ok (original tab size) +output_tab_size = 8 # ok (new tab size) +indent_columns = output_tab_size # ok + +indent_label = 1 # ok (pos: absolute col, neg: relative column) +indent_cmt_with_tabs = true # ok + +# +# inter-symbol newlines +# + +nl_enum_brace = remove # no effect ("enum {" vs "enum \n {") +nl_union_brace = remove # no effect ("union {" vs "union \n {") +nl_struct_brace = remove # ok ("struct {" vs "struct \n {") +nl_do_brace = remove # ok ("do {" vs "do \n {") +nl_if_brace = remove # ok ("if () {" vs "if () \n {") +nl_for_brace = remove # ok ("for () {" vs "for () \n {") +nl_else_brace = remove # ok ("else {" vs "else \n {") +nl_while_brace = remove # ok ("while () {" vs "while () \n {") +nl_switch_brace = remove # ok ("switch () {" vs "switch () \n {") +nl_brace_while = remove # ok ("} while" vs "} \n while" - cuddle while) +nl_brace_else = add # ok ("} else" vs "} \n else" - cuddle else) +sp_brace_else = force # no effect +sp_else_brace = force # ok +nl_func_var_def_blk = 1 # deliberate +nl_fcall_brace = remove # no effect ("list_for_each() {" vs "list_for_each()\n{") +nl_fdef_brace = add # ok ("int foo() {" vs "int foo()\n{") +nl_after_return = true # deliberate +# nl_before_case = 1 + +nl_after_brace_open = true # deliberate +nl_after_brace_open_cmt = true # deliberate + +nl_func_type_name = remove # ok + +# +# Source code modifications +# + +mod_paren_on_return = add # ok ("return 1;" vs "return (1);") +mod_full_brace_if = remove # ok ("if (a) a--;" vs "if (a) { a--; }") +mod_full_brace_if_chain = false # no effect +mod_full_brace_for = remove # deliberate ("for () a--;" vs "for () { a--; }") +mod_full_brace_do = remove # ok ("do a--; while ();" vs "do { a--; } while ();") +mod_full_brace_while = remove # ok ("while (a) a--;" vs "while (a) { a--; }") +mod_full_brace_nl = 2 # ok (don't remove if more than 2 newlines) + + +# +# inter-character spacing options +# + +sp_return_paren = force # ok ("return (1);" vs "return(1);") +sp_sizeof_paren = remove # ok ("sizeof (int)" vs "sizeof(int)") +sp_before_sparen = force # ok ("if (" vs "if(") +sp_after_sparen = force # ok ("if () {" vs "if (){") +sp_after_cast = remove # ok ("(int) a" vs "(int)a") +sp_inside_braces = remove # ok ("{ 1 }" vs "{1}") +sp_inside_braces_struct = remove # no effect ("{ 1 }" vs "{1}") +sp_inside_braces_enum = remove # no effect ("{ 1 }" vs "{1}") +sp_assign = force # ok +sp_arith = force # ok +sp_bool = force # ok +sp_compare = force # ok +sp_after_comma = force # ok +sp_func_def_paren = force # ok ("int foo (){" vs "int foo(){") +sp_func_call_paren = remove # ok ("foo (" vs "foo(") +sp_func_proto_paren = force # ok ("int foo ();" vs "int foo();") + +sp_after_semi_for_empty = remove # ok + +sp_cmt_cpp_start = add # ok + +# +# Aligning stuff +# + +align_with_tabs = true # no effect (use tabs to align) +align_on_tabstop = false # no effect (align on tabstops) +align_keep_tabs = false # deliberate +align_enum_equ_span = 4 # no effect ('=' in enum definition) +align_nl_cont = false # ok +align_var_def_span = 0 # ok +align_var_def_inline = false # no effect +align_var_def_star_style = 1 # no effect +align_var_def_colon = false # no effect +align_assign_span = 0 # ok +align_struct_init_span = 0 # ok (align stuff in a structure init '= { }') +align_right_cmt_span = 3 # deliberate +align_pp_define_span = 0; # ok +align_pp_define_gap = 2; # no effect + +cmt_star_cont = false # ok + +indent_brace = 0 # ok + +nl_func_paren = remove # ok +nl_func_decl_start = remove # ok +nl_func_decl_empty = remove # ok +nl_func_decl_args = remove # ok +nl_func_decl_end = remove # ok +sp_inside_paren = remove # ok +sp_inside_square = remove # ok +sp_inside_paren_cast = remove # ok +sp_inside_fparen = remove # ok +sp_inside_sparen = remove # ok +sp_paren_paren = remove # ok +sp_before_ptr_star = force # ok +sp_after_ptr_star = remove # ok +sp_between_ptr_star = remove # ok +align_func_params = true # no effect + +align_var_struct_span = 0 # ok + +eat_blanks_after_open_brace = true # deliberate +eat_blanks_before_close_brace = true # deliberate + +pp_indent = remove # ok + +nl_start_of_file = remove # deliberate +nl_end_of_file = force # ok +nl_end_of_file_min = 1 # ok +nl_comment_func_def = 1 # ok diff --git a/src/hucc/version.h b/src/hucc/version.h new file mode 100644 index 00000000..9673f7b0 --- /dev/null +++ b/src/hucc/version.h @@ -0,0 +1,12 @@ +#ifndef HUC_VERSION_H +#define HUC_VERSION_H + +#ifndef GIT_VERSION +# define GIT_VERSION "dummy" +#endif /* !GIT_VERSION */ + +#ifndef GIT_DATE +# define GIT_DATE "1987/10/30" +#endif /* !GIT_DATE */ + +#endif /* HUC_VERSION_H */ diff --git a/src/hucc/version.h.in b/src/hucc/version.h.in new file mode 100644 index 00000000..a8115c8c --- /dev/null +++ b/src/hucc/version.h.in @@ -0,0 +1,12 @@ +#ifndef HUC_VERSION_H +#define HUC_VERSION_H + +#ifndef GIT_VERSION +# define GIT_VERSION "@GIT_VERSION@" +#endif /* !GIT_VERSION */ + +#ifndef GIT_DATE +# define GIT_DATE @GIT_DATE@ +#endif /* !GIT_DATE */ + +#endif /* HUC_VERSION_H */ diff --git a/src/hucc/while.c b/src/hucc/while.c new file mode 100644 index 00000000..f2a0d12a --- /dev/null +++ b/src/hucc/while.c @@ -0,0 +1,81 @@ +/* File while.c: 2.1 (83/03/20,16:02:22) */ +/*% cc -O -c % + * + */ + +#include +#include +#include +#include "defs.h" +#include "data.h" +#include "error.h" +#include "gen.h" +#include "io.h" +#include "while.h" + +void addwhile (int *ptr) +{ + int k; + + if (wsptr == WS_LIMIT) { + error("too many active whiles"); + return; + } + k = 0; + while (k < WS_COUNT) + *wsptr++ = ptr[k++]; +} + +void delwhile (void) +{ + if (readwhile()) + wsptr = wsptr - WS_COUNT; +} + +int *readwhile (void) +{ + if (wsptr == ws) { + error("no active do/for/while/switch"); + return (0); + } + else + return (wsptr - WS_COUNT); +} + +int *findwhile (void) +{ + int *ptr; + + for (ptr = wsptr; ptr != ws;) { + ptr = ptr - WS_COUNT; + if (ptr[WS_TYPE] != WS_SWITCH) + return (ptr); + } + error("no active do/for/while"); + return (NULL); +} + +int *readswitch (void) +{ + int *ptr; + + ptr = readwhile(); + if (ptr) + if (ptr[WS_TYPE] == WS_SWITCH) + return (ptr); + + return (0); +} + +void addcase (int val) +{ + int lab; + + if (swstp == SWST_COUNT) + error("too many case labels"); + else { + swstcase[swstp] = val; + swstlabel[swstp++] = lab = getlabel(); + gcase(lab, val); + } +} diff --git a/src/hucc/while.h b/src/hucc/while.h new file mode 100644 index 00000000..f662eb3c --- /dev/null +++ b/src/hucc/while.h @@ -0,0 +1,11 @@ +#ifndef _WHILE_H +#define _WHILE_H + +void addwhile (int *ptr); +void delwhile (void); +int *readwhile (void); +int *findwhile (void); +int *readswitch (void); +void addcase (int val); + +#endif diff --git a/src/isolink/main.c b/src/isolink/main.c index 8c4ff21f..9fd5d4e5 100644 --- a/src/isolink/main.c +++ b/src/isolink/main.c @@ -1,12 +1,9 @@ -/* ISOLINK +/* isoLINK * * This program appends the IPL header together with * a list of binary segments which may be overlays or * data, and produces an ISO output file * - * An array of segment information is also produced and - * stored (I'm not sure where yet) - * */ @@ -41,8 +38,9 @@ int cderr_ovl = 0; int pcfx_flag = 0; int asm_flag = 0; int sgx_flag = 0; -static char incpath[10][256]; -static int debug; +char prj_type[8]; +char incpath[10][256]; +int debug; int ipl_flag = 0; int ipl_load = 0x4000; @@ -54,7 +52,7 @@ int ipl_mpr5 = 0x03; int ipl_mpr6 = 0x04; int ipl_mode = 0x60; char * ipl_file = NULL; -char * ipl_name = "isoLink"; +char * ipl_name = "isoLINK"; char * ipl_nend; @@ -286,7 +284,7 @@ init_path(void) int i, l; strcpy(incpath[0], "."); - strcat(incpath[0], PATH_SEPARATOR_STRING); + strcat(incpath[0], DIR_SEPARATOR_STRING); p = getenv("PCE_INCLUDE"); @@ -295,19 +293,19 @@ init_path(void) #ifdef WIN32 "c:\\huc\\include\\huc" #else - "/usr/local/lib/huc/include/huc;" \ - "/usr/local/huc/include/huc;" \ - "/usr/local/share/huc/include/huc;" \ - "/usr/local/include/huc;" \ - "/usr/lib/huc/include/huc;" \ - "/usr/share/huc/include/huc;" \ + "/usr/local/lib/huc/include/huc:" \ + "/usr/local/huc/include/huc:" \ + "/usr/local/share/huc/include/huc:" \ + "/usr/local/include/huc:" \ + "/usr/lib/huc/include/huc:" \ + "/usr/share/huc/include/huc:" \ "/usr/include/huc" #endif ; } for (i = 1; i < 10; i++) { - pl = strchr(p, ';'); + pl = strchr(p, PATH_SEPARATOR); if (pl == NULL) l = strlen(p); @@ -317,14 +315,14 @@ init_path(void) if (l) { strncpy(incpath[i], p, l); p += l; - while (*p == ';') + while (*p == PATH_SEPARATOR) p++; } incpath[i][l] = '\0'; if (l) { - if (incpath[i][l - 1] != PATH_SEPARATOR) - strcat(incpath[i], PATH_SEPARATOR_STRING); + if (incpath[i][l - 1] != DIR_SEPARATOR) + strcat(incpath[i], DIR_SEPARATOR_STRING); } } } @@ -391,7 +389,7 @@ file_write(FILE *outfile, FILE *infile, char *filename, int curr_filenum) /* wrong place to get an incomplete read */ if ( ((sectors * 2048) == size) || ((i + 1) != sectors) ) { - printf("Error while reading file %s\n", filename); + printf("Error while reading file \"%s\"\n", filename); exit(1); } else { /* fill buffer with zeroes */ @@ -400,7 +398,7 @@ file_write(FILE *outfile, FILE *infile, char *filename, int curr_filenum) } if (code == 1) { - if (i == 0) { /* ie. boot segment */ + if (i == 0) { /* ie. the file's boot segment */ /* Confirm that this is really a HuC overlay */ if (buffer[3] != 'H' || buffer[4] != 'u' || buffer[5] != 'C') { code = 0; @@ -482,7 +480,55 @@ ipl_write(FILE *outfile) int i; size_t sectors = sector_array[1] - sector_array[0]; unsigned char * ipl_buffer = calloc(sectors, 2048); - int beyond128mb = 255; + char use_ipl_scd = 0; + + /* custom SuperCD boot sector loader code made from "examples/asm/elmer/ipl-scd/" */ + static unsigned char ipl_scd [704] = { + 0x20,0x5A,0xE0,0xE0,0x03,0x90,0x59,0x20,0xDE,0xE0,0xB0,0x54,0x22,0x29,0x7F,0x22, + 0xE0,0x03,0x90,0x4C,0xA9,0x68,0x53,0x04,0xA0,0x01,0xB9,0x01,0x36,0x38,0xF9,0x00, + 0x36,0x85,0xF8,0x64,0xF9,0x43,0x04,0x85,0xFA,0x64,0xFB,0x62,0xCC,0x00,0x37,0x90, + 0x01,0x1A,0x85,0xFC,0xB9,0x00,0x37,0x85,0xFD,0xB9,0x00,0x36,0x85,0xFE,0xA9,0x06, + 0x85,0xFF,0x20,0x09,0xE0,0xC9,0x00,0xF0,0x06,0xA9,0x67,0xA2,0x31,0x80,0x1A,0x43, + 0x04,0x1A,0x53,0x08,0x1A,0x53,0x10,0x1A,0x53,0x20,0x1A,0x53,0x40,0x4C,0x00,0x40, + 0xAC,0xFF,0x35,0xD0,0xB5,0xA9,0x46,0xA2,0x31,0x48,0xDA,0x20,0x99,0xE0,0x20,0x7B, + 0xE0,0x20,0x84,0x31,0xA9,0x7D,0x85,0xEC,0xA9,0x32,0x85,0xED,0x20,0xC4,0x31,0x62, + 0xA2,0x20,0xA0,0x1C,0x20,0x6F,0xE0,0xA9,0x01,0x20,0x69,0xE0,0xA9,0x5D,0x8D,0x20, + 0x22,0xA9,0x32,0x8D,0x21,0x22,0xA9,0x01,0x8D,0x22,0x22,0x9C,0x23,0x22,0x9C,0x24, + 0x22,0x9C,0x25,0x22,0xA9,0x02,0x8D,0x1F,0x22,0xFA,0x68,0x20,0x1D,0x32,0x20,0x8A, + 0xE0,0x20,0x7B,0xE0,0x80,0xFE,0x01,0x0D,0x41,0x42,0x43,0x44,0x45,0x40,0x46,0x47, + 0x48,0x49,0x4A,0x4B,0x4C,0x40,0x41,0x4D,0x4E,0x4F,0x44,0x50,0x40,0x45,0x44,0x57, + 0x42,0x58,0x45,0x44,0x52,0x53,0x00,0x03,0x0D,0x46,0x47,0x40,0x44,0x45,0x45,0x54, + 0x45,0x53,0x40,0x46,0x55,0x51,0x51,0x54,0x4F,0x40,0x45,0x42,0x51,0x40,0x56,0x55, + 0x50,0x44,0x53,0x00,0x44,0x14,0xA2,0x1C,0xC2,0x13,0x00,0x23,0x00,0x23,0x00,0x23, + 0x00,0x23,0x00,0x88,0xD0,0xF5,0xCA,0xD0,0xF2,0x60,0xA9,0x05,0x85,0xF7,0x03,0x05, + 0x23,0x00,0xA9,0x00,0x85,0xF7,0x03,0x00,0x9C,0x02,0x02,0x9C,0x03,0x02,0xA9,0x02, + 0x85,0xF7,0x03,0x02,0xA2,0x08,0xC2,0x13,0x40,0x23,0x01,0x23,0x01,0x88,0xD0,0xF9, + 0xCA,0xD0,0xF6,0x60,0xA2,0x14,0xA9,0xFF,0x48,0xA9,0x00,0x85,0xF7,0x03,0x00,0x9C, + 0x02,0x02,0x8E,0x03,0x02,0xA9,0x02,0x85,0xF7,0x03,0x02,0xA9,0x19,0x85,0xF8,0xC2, + 0x82,0x9E,0x00,0x21,0xB1,0xEC,0x9D,0x01,0x21,0x0A,0x11,0xEC,0x9D,0x02,0x21,0x1D, + 0x00,0x21,0x5D,0x01,0x21,0x9D,0x00,0x21,0xC8,0xD0,0x02,0xE6,0xED,0xE8,0xE8,0xE0, + 0x10,0xD0,0xE1,0xE3,0x00,0x21,0x02,0x02,0x10,0x00,0x68,0xA2,0x08,0x8D,0x02,0x02, + 0x8D,0x03,0x02,0xCA,0xD0,0xFA,0x48,0xC6,0xF8,0xD0,0xC5,0x68,0x60,0x85,0xF8,0x86, + 0xF9,0xA0,0x01,0xB1,0xF8,0x4A,0xAA,0x62,0x6A,0x22,0x4A,0x22,0x6A,0x12,0xF8,0xC8, + 0x08,0x78,0x03,0x01,0x8D,0x02,0x02,0x8E,0x03,0x02,0x03,0x00,0x8D,0x02,0x02,0x8E, + 0x03,0x02,0x03,0x02,0xA9,0x02,0x85,0xF7,0x28,0xB1,0xF8,0xF0,0x0F,0xC8,0x18,0x69, + 0x00,0x8D,0x02,0x02,0x62,0x69,0x01,0x8D,0x03,0x02,0x80,0xED,0x60,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x4C,0x00,0x69,0x01,0xB2,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x3C,0x06,0x66,0x3C,0x00,0x00,0x00,0x66, + 0x66,0x66,0x66,0x3E,0x00,0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x60,0x00,0x00,0x3C, + 0x66,0x7E,0x60,0x3C,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x60,0x00,0x3C,0x66,0x60, + 0x60,0x60,0x66,0x3C,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00, + 0x7E,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00,0x3C,0x66,0x66, + 0x66,0x66,0x66,0x3C,0x00,0x63,0x77,0x7F,0x6B,0x6B,0x63,0x63,0x00,0x3E,0x03,0x1E, + 0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x3C,0x00,0x00,0x3E, + 0x60,0x3C,0x06,0x7C,0x00,0x00,0x18,0x7E,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x36, + 0x7F,0x6B,0x6B,0x63,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x00,0x06,0x06,0x3E, + 0x66,0x66,0x66,0x3E,0x00,0x18,0x3C,0x3C,0x18,0x18,0x00,0x18,0x00,0x00,0x00,0x3C, + 0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x3E,0x00,0x00,0x00,0x3E, + 0x66,0x66,0x3E,0x06,0x3C,0x00,0x00,0x3E,0x66,0x66,0x3E,0x07,0x06,0x18,0x00,0x38, + 0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; /* initialize the CD's IPL sector contents */ if (ipl_file != NULL) { @@ -523,43 +569,122 @@ ipl_write(FILE *outfile) } else { /* Set boot parameters for PC Engine */ - /* prg sector base */ - ipl_buffer[0x802] = sector_array[1]; + /* Does the 1st file on the CD identify the project type? */ + if (prj_type[0] == 0x4C) { + if (memcmp("HuC", prj_type + 3, 3) == 0) { + /* HuC v4 with startup.asm changes from 2022 */ + use_ipl_scd = 0; + asm_flag = 0; + } + else + if (memcmp(" CD", prj_type + 3, 3) == 0) { + /* HuCC or CORE asm-library CD */ + use_ipl_scd = 0; + asm_flag = 1; + } + else + if (memcmp("SCD", prj_type + 3, 3) == 0) { + /* HuCC or CORE asm-library SuperCD */ + use_ipl_scd = 1; + asm_flag = 1; + } + else + if (memcmp("SGX", prj_type + 3, 3) == 0) { + /* HuCC or CORE asm-library SuperGRAFX SuperCD */ + use_ipl_scd = 1; + asm_flag = 1; + sgx_flag = 1; + } + else + if (memcmp("SC1", prj_type + 3, 3) == 0) { + /* HuCC or CORE asm-library SuperCD Stage1 loader */ + /* If use_ipl_scd then the kernel won't be loaded */ + /* when running on the wrong System Card! */ + use_ipl_scd = 0; + asm_flag = 1; + } + else + if (memcmp("SG1", prj_type + 3, 3) == 0) { + /* HuCC or CORE asm-library SuperGRAFX SuperCD Stage1 loader */ + /* If use_ipl_scd then the kernel won't be loaded */ + /* when running on the wrong System Card! */ + use_ipl_scd = 0; + asm_flag = 1; + sgx_flag = 1; + } + } + + /* Use isoLINK's built-in IPL-SCD loader? */ + if (use_ipl_scd) { + + /* IPL-SCD loader code from the asm example project */ + memcpy(ipl_buffer + 0x890, ipl_scd, sizeof(ipl_scd)); + + /* prg sector base */ + ipl_buffer[0x802] = 0; + + /* nb_sectors */ + ipl_buffer[0x803] = 0; + + /* loading address */ + ipl_buffer[0x804] = 0; + ipl_buffer[0x805] = 0; + + /* starting address */ + ipl_buffer[0x806] = 0x3090 & 255; + ipl_buffer[0x807] = 0; + + /* mpr registers */ + ipl_buffer[0x808] = 0; + ipl_buffer[0x809] = 1; + ipl_buffer[0x80A] = 2; + ipl_buffer[0x80B] = 3; + ipl_buffer[0x80C] = 4; + + /* load mode */ + ipl_buffer[0x80D] = 0; - /* nb_sectors */ - if (asm_flag) { - /* ASM boot segment */ - ipl_buffer[0x803] = sector_array[2] - sector_array[1]; } else { - ipl_buffer[0x803] = 16;/* HuC boot segments; up to and including */ - /* overlay array. The boot segments will load */ - /* the remaining segments and relocate code if */ - /* necessary */ - } - /* loading address */ - ipl_buffer[0x804] = (ipl_load & 255); - ipl_buffer[0x805] = (ipl_load >> 8) & 255; + /* prg sector base */ + ipl_buffer[0x802] = sector_array[1]; - /* starting address */ - ipl_buffer[0x806] = (ipl_exec & 255); - ipl_buffer[0x807] = (ipl_exec >> 8) & 255; - - /* mpr registers */ - ipl_buffer[0x808] = ipl_mpr2; - ipl_buffer[0x809] = ipl_mpr3; - ipl_buffer[0x80A] = ipl_mpr4; - ipl_buffer[0x80B] = ipl_mpr5; - ipl_buffer[0x80C] = ipl_mpr6; /* HuC boot loader also @ $C000 */ - - /* load mode */ - ipl_buffer[0x80D] = ipl_mode; + /* nb_sectors */ + if (asm_flag) { + /* ASM boot segment */ + ipl_buffer[0x803] = sector_array[2] - sector_array[1]; + } else { + ipl_buffer[0x803] = 16;/* HuC boot segments; up to and including */ + /* overlay array. The boot segments will load */ + /* the remaining segments and relocate code if */ + /* necessary */ + } + + /* loading address */ + ipl_buffer[0x804] = (ipl_load & 255); + ipl_buffer[0x805] = (ipl_load >> 8) & 255; + + /* starting address */ + ipl_buffer[0x806] = (ipl_exec & 255); + ipl_buffer[0x807] = (ipl_exec >> 8) & 255; + + /* mpr registers */ + ipl_buffer[0x808] = ipl_mpr2; + ipl_buffer[0x809] = ipl_mpr3; + ipl_buffer[0x80A] = ipl_mpr4; + ipl_buffer[0x80B] = ipl_mpr5; + ipl_buffer[0x80C] = ipl_mpr6; /* HuC boot loader also @ $C000 */ + + /* load mode */ + ipl_buffer[0x80D] = ipl_mode; + } } } /* always write this project-specific data */ if (pcfx_flag) { /* Set project-specific data for PC-FX */ + unsigned char beyond256mb = 255; /* allow game name to override the one in an ipl_file */ if (ipl_flag || ipl_file == NULL) { @@ -579,18 +704,19 @@ ipl_write(FILE *outfile) ipl_buffer[2*i + 0xE00] = lba & 255; ipl_buffer[2*i + 0xE01] = lba >> 8; - if ((beyond128mb == 255) && (lba >= 65536)) - beyond128mb = i; + if ((beyond256mb == 255) && (lba >= 65536)) + beyond256mb = i; } /* store the count of directory entries */ ipl_buffer[0xE00] = file_count; - /* store which is the first file beyond the 128Mbyte ISO boundary */ - ipl_buffer[0xE01] = beyond128mb; + /* store which is the first file beyond the 256Mbyte ISO boundary */ + ipl_buffer[0xE01] = beyond256mb; } else { /* Set project-specific data for PC Engine */ + unsigned char beyond128mb = 255; /* allow game name to override the one in an ipl_file */ if (ipl_flag || ipl_file == NULL) { @@ -648,12 +774,12 @@ void usage(void) { printf(ISOLINK_VERSION "\n"); - printf("\nUsage: isolink [] -cderr \n"); + printf("\nUsage: isoLINK [] --cderr \n"); printf("\nOptions:\n\n"); - printf("-pcfx : Write a PC-FX ISO instead of a PC Engine ISO\n\n"); - printf("-boot= : The '=' is followed ... \n"); + printf("--pcfx : Write a PC-FX ISO instead of a PC Engine ISO\n\n"); + printf("--boot= : The '=' is followed ... \n"); printf(" \n\n"); - printf("-ipl= : The '=' is followed by either ... \n"); + printf("--ipl= : The '=' is followed by either ... \n"); printf(" \n\n"); printf(" ... or (only for PC Engine) ...\n"); printf(" , \n"); @@ -668,10 +794,9 @@ usage(void) printf(" , \n"); printf(" , \n"); printf(" \n\n"); - printf(" HuC programs can only set the !\n\n"); - printf("-sgx : Add a SuperGRAFX signature string to the IPL\n\n"); - printf("-asm : Do not write HuC-specific data into overlays\n\n"); - printf("-cderr : Indicates that the following overlay should be run instead\n"); + printf(" HuC and HuCC programs can only set the !\n\n"); + printf("--sgx : Add a SuperGRAFX signature string to the IPL\n\n"); + printf("--cderr : Indicates that the following overlay should be run instead\n"); printf(" of displaying a text message when a SuperCD-ROM program is\n"); printf(" executed on plain CD-ROM system.\n\n"); } @@ -712,11 +837,14 @@ main(int argc, char *argv[]) for (i = 2; i < argc; i++) { /* is this an option? */ if (argv[i][0] == '-') { + /* Convert GNU-style "--" options into "-" options for backwards-compatibility */ + if (argv[i][1] == '-') argv[i]++; + if ((strcmp(argv[i], "-pcfx") == 0) && (pcfx_flag == 0)) { /* only valid once on line */ if (file_num != 0 || ipl_flag != 0) { - printf("\"-pcfx\" option must appear before \"-ipl\" and before any files!\n"); + printf("\"--pcfx\" option must appear before \"--ipl\" and before any files!\n"); printf("Operation aborted\n\n"); exit(1); } @@ -736,13 +864,13 @@ main(int argc, char *argv[]) ipl_file = argv[i] + 6; if (*ipl_file == '\0') { - printf("\"-boot=\" option without a file name!\n"); + printf("\"--boot=\" option without a file name!\n"); printf("Operation aborted\n\n"); exit(1); } if (file_num != 0 || ipl_flag != 0) { - printf("\"-boot\" option must appear before -ipl or any files!\n"); + printf("\"--boot\" option must appear before --ipl or any files!\n"); printf("Operation aborted\n\n"); exit(1); } @@ -756,13 +884,13 @@ main(int argc, char *argv[]) char * nxt; if (*ptr == '\0') { - printf("\"-ipl=\" option without any parameters!\n"); + printf("\"--ipl=\" option without any parameters!\n"); printf("Operation aborted\n\n"); exit(1); } if (file_num >= 2 || ipl_flag != 0) { - printf("\"-ipl\" option must appear before any files!\n"); + printf("\"--ipl\" option must appear before any files!\n"); printf("Operation aborted\n\n"); exit(1); } @@ -832,13 +960,13 @@ main(int argc, char *argv[]) (cderr_flag == 0)) { /* only valid once on line */ if (file_num < 2) { - printf("\"-cderr\" cannot be first file!\n"); + printf("\"--cderr\" cannot be first file!\n"); printf("Operation aborted\n\n"); exit(1); } if (i >= (argc - 1)) { - printf("\"-cderr\" must be followed by a filename!\n"); + printf("\"--cderr\" must be followed by a filename!\n"); printf("Operation aborted\n\n"); exit(1); } @@ -865,6 +993,13 @@ main(int argc, char *argv[]) } } + /* is the custom name too long? */ + if ((ipl_nend - ipl_name) > (pcfx_flag ? 32 : 22)) { + printf("\"--ipl=\" name must be 22 characters or less for PCE, 32 or less for PC-FX!\n"); + printf("Operation aborted\n\n"); + exit(1); + } + /* is the directory full? */ if (file_num == MAX_FILES) { printf("Too many files on the CD!\nThe maximum is %d.\n", MAX_FILES); @@ -886,11 +1021,19 @@ main(int argc, char *argv[]) infile = file_open(inname, "rb"); if (infile == NULL) { - printf("Could not open file: %s\n", inname); + printf("Could not open file: \"%s\"\n", inname); printf("Operation aborted\n\n"); exit(1); } + if (file_num == 1) { + /* read the 1st file's header for identification */ + if (fread((void *)prj_type, 1, 8, infile) != 8) { + printf("Error while reading file \"%s\"\n", inname); + exit(1); + } + } + fseek(infile, 0L, SEEK_END); file_len = ftell(infile); rewind(infile); @@ -913,7 +1056,7 @@ main(int argc, char *argv[]) } if (ipl_flag < 0) { - printf("Malformed -ipl option: \"%s\"\n", argv[i]); + printf("Malformed --ipl option: \"%s\"\n", argv[i]); printf("Operation aborted\n\n"); exit(1); } diff --git a/src/isolink/main.h b/src/isolink/main.h index 08c63c58..d2237a7e 100644 --- a/src/isolink/main.h +++ b/src/isolink/main.h @@ -2,11 +2,13 @@ #define ISOLINK_VERSION "isolink (" GIT_VERSION ", " GIT_DATE ")" -#if defined(WIN32) -#define PATH_SEPARATOR '\\' -#define PATH_SEPARATOR_STRING "\\" +#ifdef _WIN32 +#define PATH_SEPARATOR ';' +#define DIR_SEPARATOR '\\' +#define DIR_SEPARATOR_STRING "\\" #else -#define PATH_SEPARATOR '/' -#define PATH_SEPARATOR_STRING "/" +#define PATH_SEPARATOR ':' +#define DIR_SEPARATOR '/' +#define DIR_SEPARATOR_STRING "/" #endif diff --git a/src/mkit/as/assemble.c b/src/mkit/as/assemble.c index 656ce854..95036097 100644 --- a/src/mkit/as/assemble.c +++ b/src/mkit/as/assemble.c @@ -26,8 +26,6 @@ int continued_line; /* set when a line is the continuation of another line */ void assemble(int do_label) { - struct t_line *ptr; - char *buf; char c; int flag; int ip, i, j; /* prlnbuf pointer */ @@ -52,7 +50,7 @@ assemble(int do_label) if (oplook(&i) >= 0) { if (opflg == PSEUDO) { if (opval == P_MACRO) { - error("Can not nest macro definitions!"); + error("Cannot nest macro definitions!"); return; } if (opval == P_ENDM) { @@ -64,19 +62,20 @@ assemble(int do_label) } } if (pass == FIRST_PASS) { + struct t_line *ptr; + const char *buf; if (preproc_modidx != 0) { /* Remove C-style comments within a macro */ prlnbuf[preproc_modidx] = '\0'; } ptr = (void *)malloc(sizeof(struct t_line)); - buf = (void *)malloc(strlen(&prlnbuf[preproc_sfield]) + 1); + buf = (void *)remember_string(&prlnbuf[preproc_sfield], strlen(&prlnbuf[preproc_sfield]) + 1); if ((ptr == NULL) || (buf == NULL)) { error("Out of memory!"); return; } - strcpy(buf, &prlnbuf[preproc_sfield]); ptr->next = NULL; - ptr->data = buf; + ptr->line = buf; if (mlptr) mlptr->next = ptr; else @@ -86,6 +85,28 @@ assemble(int do_label) return; } + /* unused PROC/PROCGROUP that has been stripped out; + * check for a '.endp' or '.endprocgroup' + * to toggle state + */ + if (skipping_stripped) { + i = preproc_sfield; + while (isspace(prlnbuf[i])) { i++; } + if ((oplook(&i) >= 0) && (opflg == PSEUDO)) { + switch (opval) { + + case P_ENDP: // .endp + case P_ENDPG: // .endprocgroup + if (optype != skipping_stripped) + break; + skipping_stripped = 0; + if (pass == LAST_PASS) + println(); + } + } + return; + } + /* IF/ELSE section; * check for a '.else' or '.endif' * to toggle state @@ -113,15 +134,13 @@ assemble(int do_label) /* check that expression matches if_level */ save_if_expr(&i); if (strcmp(if_txt[if_level], if_txt[if_level-1]) != 0) { - char message [128]; - sprintf(message, "Condition does not match \".if %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); - fatal_error(message); + fatal_error("Condition does not match \".IF %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); return; } } if (if_state[if_level]) { skip_lines = !if_flag[if_level]; - if (pass == LAST_PASS) + if (pass == LAST_PASS && !expand_macro) println(); } return; @@ -132,13 +151,11 @@ assemble(int do_label) /* check that expression matches if_level */ save_if_expr(&i); if (strcmp(if_txt[if_level], if_txt[if_level-1]) != 0) { - char message [128]; - sprintf(message, "Condition does not match \".if %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); - fatal_error(message); + fatal_error("Condition does not match \".IF %s\" at line %d!", if_txt[if_level-1], if_line[if_level-1]); return; } } - if (if_state[if_level] && (pass == LAST_PASS)) + if (if_state[if_level] && (pass == LAST_PASS) && !expand_macro) println(); skip_lines = !if_state[if_level]; if_level--; @@ -155,7 +172,6 @@ assemble(int do_label) /* comment line */ c = prlnbuf[preproc_sfield]; -// if (c == ';' || c == '*' || c == '\0') { /* Let's see if anyone really uses '*' for a comment line! */ if (c == ';' || c == '\0') { lastlabl = NULL; if (pass == LAST_PASS) @@ -168,15 +184,19 @@ assemble(int do_label) j = 0; while (isspace(prlnbuf[i])) i++; - for (;;) { - c = prlnbuf[i + j]; - if ((j == 0) && isdigit(c)) - break; - if (isalnum(c) || (c == '_') || (c == '.') || (j == 0 && (c == '@' || c == '!'))) { - ++j; - } else { - break; + + c = prlnbuf[i]; + + if (isdigit(c)) { + /* check for an SDCC local-symbol */ + if (sdcc_mode && (prlnbuf[i+5] == '$') && (prlnbuf[i+6] == ':') + && isdigit(prlnbuf[i+1]) && isdigit(prlnbuf[i+2]) + && isdigit(prlnbuf[i+3]) && isdigit(prlnbuf[i+4])) { + j = 6; c = ':'; } + } else + while (isalnum(c) || (c == '_') || (c == '.') || (j == 0 && (c == '@' || c == '!'))) { + c = prlnbuf[i + (++j)]; } if ((j == 0) || ((i != preproc_sfield) && (c != ':'))) { @@ -222,12 +242,12 @@ assemble(int do_label) mptr = macro_look(&ip); if (mptr) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output location counter */ if (pass == LAST_PASS) { if (!asm_opt[OPT_MACRO]) - loadlc((page << 13) + loccnt, 0); + loadlc(loccnt + (page << 13), 0); } /* get macro args */ @@ -256,7 +276,7 @@ assemble(int do_label) return; } - labldef(0, 0, LOCATION); + labldef(LOCATION); if (flag == -1) error("Unknown instruction!"); if ((flag == -2) && (pass == LAST_PASS)) { @@ -271,15 +291,15 @@ assemble(int do_label) /* generate code */ if (opflg == PSEUDO) do_pseudo(&ip); - else if (labldef(0, 0, LOCATION) == -1) + else if (labldef(LOCATION) == -1) return; else { /* output infos */ data_loccnt = loccnt; /* check if we are in the CODE section */ - if (section != S_CODE) - fatal_error("Instructions not allowed in this section!"); + if ((section_flags[section] & S_IS_CODE) == 0) + fatal_error("Instructions are not allowed in this section!"); /* generate code */ opproc(&ip); @@ -414,7 +434,7 @@ addinst(struct t_opcode *optbl) while (optbl->name) { /* calculate instruction hash value */ hash = 0; - len = strlen(optbl->name); + len = (int)strlen(optbl->name); ptr = optbl->name; for (i = 0; i < len; i++) { @@ -484,7 +504,7 @@ save_if_expr(int *ip) void do_if(int *ip) { - labldef(0, 0, LOCATION); + labldef(LOCATION); /* save condition text */ save_if_expr(ip); @@ -499,7 +519,7 @@ do_if(int *ip) /* check for '.if' stack overflow */ if (if_level == 255) { - fatal_error("Too many nested IF/ENDIF!"); + fatal_error("Too many nested .IF/.ENDIF!"); return; } in_if = 1; @@ -508,7 +528,7 @@ do_if(int *ip) if (!skip_lines) skip_lines = if_flag[if_level] = value ? 0 : 1; - if (pass == LAST_PASS) { + if (pass == LAST_PASS && !expand_macro) { loadlc(value, 1); println(); } @@ -520,7 +540,7 @@ void do_else(int *ip) { if (!in_if) - fatal_error("Unexpected ELSE!"); + fatal_error("Unexpected .ELSE!"); } /* .endif pseudo */ @@ -529,7 +549,7 @@ void do_endif(int *ip) { if (!in_if) - fatal_error("Unexpected ENDIF!"); + fatal_error("Unexpected .ENDIF!"); } /* .ifdef/.ifndef pseudo */ @@ -537,7 +557,7 @@ do_endif(int *ip) void do_ifdef(int *ip) { - labldef(0, 0, LOCATION); + labldef(LOCATION); /* skip spaces */ while (isspace(prlnbuf[*ip])) @@ -553,11 +573,17 @@ do_ifdef(int *ip) } if (!check_eol(ip)) return; + + /* this check does not count as a refererence! */ lablptr = stlook(SYM_CHK); + /* is it undefined */ + if ((lablptr != NULL) && ((lablptr->type == IFUNDEF) || (lablptr->type == UNDEF))) + lablptr = NULL; + /* check for '.if' stack overflow */ if (if_level == 255) { - fatal_error("Too many nested IF/ENDIF!"); + fatal_error("Too many nested .IF/.ENDIF!"); return; } in_if = 1; @@ -574,7 +600,7 @@ do_ifdef(int *ip) } } - if (pass == LAST_PASS) { + if (pass == LAST_PASS && !expand_macro) { loadlc(!skip_lines, 1); println(); } diff --git a/src/mkit/as/atari.c b/src/mkit/as/atari.c index 41136739..5733f69c 100644 --- a/src/mkit/as/atari.c +++ b/src/mkit/as/atari.c @@ -105,7 +105,7 @@ fuji_carttype(int *ip) int num_banks; /* define label */ -// labldef(0, 0, LOCATION); +// labldef(LOCATION); /* get cartridge type value */ if (!evaluate(ip, ';', 0)) @@ -207,7 +207,7 @@ fuji_pack_8x8_tile(unsigned char *buffer, void *data, int line_offset, int forma default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_8x8_tile'!"); + error("Unsupported format passed to 'pack_8x8_tile'!"); break; } diff --git a/src/mkit/as/atari.h b/src/mkit/as/atari.h index 4950949b..d6f732a2 100644 --- a/src/mkit/as/atari.h +++ b/src/mkit/as/atari.h @@ -14,7 +14,7 @@ struct t_opcode fuji_pseudo[3] = { /* *INDENT-ON* */ const char defdirs_fuji[] = -#ifdef WIN32 +#ifdef _WIN32 "c:\\huc\\include\\atari" #else "/usr/local/lib/huc/include/atari;" \ @@ -43,7 +43,7 @@ struct t_machine fuji = { 0xFFF6, /* ram_limit */ 0, /* ram_base */ 0, /* ram_page */ - RESERVED_BANK, /* ram_bank */ + UNDEFINED_BANK, /* ram_bank */ m6502_inst, /* base_inst */ undoc_inst, /* plus_inst */ fuji_pseudo, /* pseudo_inst */ diff --git a/src/mkit/as/code.c b/src/mkit/as/code.c index 2bdf1056..8696dde3 100644 --- a/src/mkit/as/code.c +++ b/src/mkit/as/code.c @@ -52,6 +52,13 @@ classC(int *ip) void classR(int *ip) { + /* Check for someone exiting a C function from within a #asm section. */ + if (hucc_mode && proc_ptr) + { + error("You cannot exit a C function with an RTS in HuCC!\nPlease read the documentation!"); + return; + } + /* Only if ".kickc" and currently inside a C function/procedure */ if (kickc_mode && scopeptr && proc_ptr) { @@ -110,11 +117,10 @@ class2(int *ip) return; /* all branches tracked for long-branch handling */ - if ((branch = getbranch(2)) == NULL) - return; + branch = getbranch(2); /* need more space for a long-branch */ - if (branch->convert) { + if ((branch) && (branch->convert)) { if ((opval & 0x1F) == 0x10) /* conditional branch */ loccnt += 3; @@ -125,7 +131,7 @@ class2(int *ip) /* generate code */ if (pass == LAST_PASS) { - if (branch->convert) { + if ((branch) && (branch->convert)) { /* long-branch opcode */ if ((opval & 0x1F) == 0x10) { /* conditional-branch */ @@ -144,7 +150,7 @@ class2(int *ip) putbyte(data_loccnt, opval); /* calculate branch offset */ - addr = (value & 0xFFFF) - (loccnt + (page << 13)); + addr = (value & 0xFFFF) - (loccnt + (page << 13) + phase_offset); /* check range */ if (addr > 0x7Fu && addr < ~0x7Fu) { @@ -344,16 +350,15 @@ class5(int *ip) return; /* all branches tracked for long-branch handling */ - if ((branch = getbranch(3)) == NULL) - return; + branch = getbranch(3); /* need more space for a long-branch */ - if (branch->convert) + if ((branch) && (branch->convert)) loccnt += 3; /* generate code */ if (pass == LAST_PASS) { - if (branch->convert) { + if ((branch) && (branch->convert)) { /* long-branch opcode */ putbyte(data_loccnt, opval ^ 0x80); putbyte(data_loccnt + 1, zp); @@ -367,7 +372,7 @@ class5(int *ip) putbyte(data_loccnt + 1, zp); /* calculate branch offset */ - addr = (value & 0xFFFF) - (loccnt + (page << 13)); + addr = (value & 0xFFFF) - (loccnt + (page << 13) + phase_offset); /* check range */ if (addr > 0x7Fu && addr < ~0x7Fu) { @@ -405,7 +410,7 @@ class6(int *ip) if (!evaluate(ip, (i < 2) ? ',' : ';', 0)) return; if (pass == LAST_PASS) { - if (value & 0x007F0000) { + if (value & ~0xFFFF) { error("Operand size error!"); return; } @@ -610,11 +615,10 @@ class10(int *ip) return; /* all branches tracked for long-branch handling */ - if ((branch = getbranch(3)) == NULL) - return; + branch = getbranch(3); /* need more space for a long-branch */ - if (branch->convert) + if ((branch) && (branch->convert)) loccnt += 3; /* generate code */ @@ -625,7 +629,7 @@ class10(int *ip) return; } - if (branch->convert) { + if ((branch) && (branch->convert)) { /* long-branch opcode */ putbyte(data_loccnt, (opval + (bit << 4)) ^ 0x80); putbyte(data_loccnt + 1, zp); @@ -639,7 +643,7 @@ class10(int *ip) putbyte(data_loccnt + 1, zp); /* calculate branch offset */ - addr = (value & 0xFFFF) - (loccnt + (page << 13)); + addr = (value & 0xFFFF) - (loccnt + (page << 13) + phase_offset); /* check range */ if (addr > 0x7Fu && addr < ~0x7Fu) { @@ -706,7 +710,13 @@ getoperand(int *ip, int flag, int last_char) default: /* other */ - switch (prlnbuf[*ip]) { + c = prlnbuf[*ip]; + if (c == '*' && sdcc_mode) { + /* change SDCC's '*' for ZP to '<' */ + c = '<'; + } + + switch (c) { case '#': /* immediate */ mode = IMM; @@ -729,6 +739,10 @@ getoperand(int *ip, int flag, int last_char) /* indirect */ mode = ABS_IND | ABS_IND_X | ZP_IND | ZP_IND_X | ZP_IND_Y; (*ip)++; + if (prlnbuf[*ip] == '*' && sdcc_mode) { + /* skip SDCC's redundant '*' */ + (*ip)++; + } break; case '(': @@ -768,8 +782,7 @@ getoperand(int *ip, int flag, int last_char) if (mode == (ABS | ABS_X | ABS_Y | ZP | ZP_X | ZP_Y)) { /* was there an undefined or undefined-this-pass symbol? */ if (undef || notyetdef || - ((value & 0x007FFF00) != machine->ram_base)) { -// ((value & 0x007FFF00) && ((value & 0x007FFF00) != machine->ram_base))) { + ((value & ~0xFF) != machine->ram_base)) { /* use ABS addressing, if available */ if (flag & ABS) mode &= ~ZP; @@ -895,8 +908,8 @@ getoperand(int *ip, int flag, int last_char) if (opext == 'H') value++; } - /* check address validity */ - if ((value & 0x007FFF00) && ((value & 0x007FFF00) != machine->ram_base)) + /* check address validity (accept $00xx as well for 6502-compatibility) */ + if ((value & ~0xFF) && ((value & ~0xFF) != machine->ram_base)) error("Incorrect zero page address!"); } @@ -910,9 +923,10 @@ getoperand(int *ip, int flag, int last_char) else if (opext != 0) error("Instruction extension not supported in immediate mode!"); else { - /* check value validity */ - if (((value & 0x007FFF00) > 0xFF) && ((value & 0x007FFF00) < 0x007FFF00)) - error("Incorrect immediate value!"); + /* check for overflow, except in SDCC code (-256..255 are ok) */ + /* SDCC's code generator assumes that the assembler doesn't care */ + if ((sdcc_mode == 0) && (value & ~0xFF) && ((value & ~0xFF) != ~0xFF)) + error("Operand too large to fit in a byte!"); } } @@ -926,7 +940,7 @@ getoperand(int *ip, int flag, int last_char) value++; } /* check address validity */ - if (value & 0x007F0000) + if (value & ~0xFFFF) error("Incorrect absolute address!"); /* if HuC6280 and currently inside a ".kickc" C function/procedure */ @@ -1008,6 +1022,10 @@ getstring(int *ip, char *buffer, int size) c = prlnbuf[(*ip)++]; if (c == '\"') break; + if (c == '\0') { + error("String terminator missing!"); + return (0); + } if (i >= size) { error("String too long!"); return (0); @@ -1039,8 +1057,21 @@ getbranch(int opcode_length) struct t_branch * branch; unsigned int addr; +#if 1 + /* do not track yet, because .ifref can change after the first */ + /* pass which can then change the sequence of tracked branches */ + if (pass == FIRST_PASS) + return (NULL); + + /* no tracking info if transitioned from FIRST_PASS to LAST_PASS */ + if ((branchlst == NULL) && (pass == LAST_PASS)) + return (NULL); + /* track all branches for long-branch handling */ + if (pass_count == 2) { +#else if (pass == FIRST_PASS) { +#endif /* remember this branch instruction */ if ((branch = malloc(sizeof(struct t_branch))) == NULL) { error("Out of memory!"); @@ -1065,7 +1096,7 @@ getbranch(int opcode_length) } else { /* update this branch instruction */ if (branchptr == NULL) { - error("Untracked branch instruction!"); + fatal_error("Untracked branch instruction!"); return NULL; } @@ -1074,41 +1105,46 @@ getbranch(int opcode_length) /* sanity check */ if ((branch->label != NULL) && (branch->label != expr_lablptr)) { +#if 0 if (branch->label == expr_toplabl) { /* resolve branch outside of label-scope */ /* disable for now, because this is more */ /* likely to be an error than deliberate */ // branch->label = expr_lablptr; } else { - error("Branch label mismatch!"); + fatal_error("Branch label mismatch!"); return NULL; } +#else + fatal_error("Branch label mismatch!"); + return NULL; +#endif } } - branch->addr = (loccnt + (page << 13)) & 0xFFFF; + branch->addr = (loccnt + (page << 13) + phase_offset) & 0xFFFF; branch->checked = 0; if (pass == LAST_PASS) { /* display the branches that have been converted */ if (branch->convert && asm_opt[OPT_WARNING]) { loccnt -= opcode_length; - warning("Warning: Converted to long-branch!\n"); + warning("Converted to long-branch!\n"); loccnt += opcode_length; } } else { - /* has target already been defined (this pass)? */ - if ((branch->convert == 0) && - (branch->label != NULL) && - (branch->label->defcnt != 0) && + /* check if it is outside short-branch range */ + if ((branch->label != NULL) && + (branch->label->defthispass) && (branch->label->type == DEFABS)) { - /* check if it is outside short-branch range */ addr = (branch->label->value & 0xFFFF) - branch->addr; if (addr > 0x7Fu && addr < ~0x7Fu) { + if (branch->convert == 0) + ++branches_changed; branch->convert = 1; - ++xvertlong; } + branch->checked = 1; } } @@ -1120,7 +1156,8 @@ getbranch(int opcode_length) /* ---- * branchopt() * ---- - * convert out-of-range short-branches into long-branches + * convert out-of-range short-branches into long-branches, also + * convert incorrectly-guessed long-branches back to short-branches */ int @@ -1128,32 +1165,38 @@ branchopt(void) { struct t_branch * branch; unsigned int addr; - int changed = 0; + int just_changed = 0; /* look through the entire list of branch instructions */ for (branch = branchlst; branch != NULL; branch = branch->next) { - /* check to see if a short-branch needs to be converted */ - if ((branch->convert == 0) && - (branch->checked == 0) && + /* check to see if a branch needs to be converted */ + if ((branch->checked == 0) && (branch->label != NULL) && (branch->label->type == DEFABS)) { /* check if it is outside short-branch range */ addr = (branch->label->value & 0xFFFF) - branch->addr; if (addr > 0x7Fu && addr < ~0x7Fu) { + if (branch->convert == 0) + ++just_changed; branch->convert = 1; - ++changed; +#if 0 /* This saving just doesn't seem to be worth an extra pass */ + } else { + if (branch->convert == 1) + ++just_changed; + branch->convert = 0; +#endif } } } /* report total changes this pass */ - xvertlong += changed; - if (xvertlong) - printf("Changed %d branches from short to long.\n", xvertlong); + branches_changed += just_changed; + if (branches_changed) + printf(" Changed %4d branches from short to long.\n", branches_changed); /* do another pass if anything just changed, except if KickC because */ /* any changes during the pass itself can change a forward-reference */ - return ((kickc_opt) ? xvertlong : changed); + return ((kickc_opt) ? branches_changed : just_changed); } diff --git a/src/mkit/as/command.c b/src/mkit/as/command.c index 0e5abf6b..e1683dd3 100644 --- a/src/mkit/as/command.c +++ b/src/mkit/as/command.c @@ -7,15 +7,90 @@ #include "externs.h" #include "protos.h" +/* section types mask for pseudo_allowed */ +#define IN_NONE (1 << S_NONE) +#define IN_ZP (1 << S_ZP) +#define IN_BSS (1 << S_BSS) +#define IN_CODE (1 << S_CODE) +#define IN_DATA (1 << S_DATA) +#define IN_HOME (1 << S_HOME) +#define IN_XDATA (1 << S_XDATA) +#define IN_XINIT (1 << S_XINIT) +#define IN_CONST (1 << S_CONST) +#define IN_OSEG (1 << S_OSEG) +#define ANYWHERE (0xFFFF) + /* pseudo instructions section flag */ -char pseudo_flag[] = { - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0F, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, - 0x0C, 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0F, - 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x04, 0x0F, 0x04, 0x0F, - 0x04, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0F, 0x0F, 0x0F, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F +unsigned short pseudo_allowed[] = { +/* P_DB */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS + IN_CONST + IN_XINIT, +/* P_DW */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS + IN_CONST + IN_XINIT, +/* P_DD */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS + IN_CONST + IN_XINIT, +/* P_DS */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS + IN_CONST + IN_XINIT + IN_XDATA + IN_OSEG, +/* P_EQU */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ORG */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_PAGE */ IN_CODE + IN_HOME + IN_DATA, +/* P_BANK */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCBIN */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCLUDE */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_INCCHR */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCSPR */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCPAL */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCBAT */ IN_CODE + IN_HOME + IN_DATA, +/* P_MACRO */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ENDM */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_LIST */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_MLIST */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_NOLIST */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_NOMLIST */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_RSSET */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_RS */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_IF */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ELSE */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ENDIF */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_FAIL */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ZP */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_BSS */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_CODE */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_DATA */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_DEFCHR */ IN_CODE + IN_HOME + IN_DATA, +/* P_FUNC */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_IFDEF */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_IFNDEF */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_VRAM */ IN_CODE + IN_HOME + IN_DATA, +/* P_PAL */ IN_CODE + IN_HOME + IN_DATA, +/* P_DEFPAL */ IN_CODE + IN_HOME + IN_DATA, +/* P_DEFSPR */ IN_CODE + IN_HOME + IN_DATA, +/* P_INESPRG */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_INESCHR */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_INESMAP */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_INESMIR */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_OPT */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_INCTILE */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCMAP */ IN_CODE + IN_HOME + IN_DATA, +/* P_MML */ IN_CODE + IN_HOME + IN_DATA, +/* P_PROC */ IN_CODE + IN_HOME, +/* P_ENDP */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_PGROUP */ IN_CODE + IN_HOME, +/* P_ENDPG */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_CALL */ IN_CODE + IN_HOME, +/* P_DWL */ IN_CODE + IN_HOME + IN_DATA + IN_CONST + IN_XINIT, +/* P_DWH */ IN_CODE + IN_HOME + IN_DATA + IN_CONST + IN_XINIT, +/* P_INCCHRPAL */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCSPRPAL */ IN_CODE + IN_HOME + IN_DATA, +/* P_INCTILEPAL */ IN_CODE + IN_HOME + IN_DATA, +/* P_CARTRIDGE */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ALIGN */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_KICKC */ ANYWHERE, +/* P_IGNORE */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS + IN_CONST + IN_XINIT, +/* P_SEGMENT */ ANYWHERE, +/* P_LABEL */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ENCODING */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_STRUCT */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ENDS */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_3PASS */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_ALIAS */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_REF */ IN_CODE + IN_HOME + IN_DATA + IN_ZP + IN_BSS, +/* P_PHASE */ IN_CODE + IN_HOME }; @@ -28,13 +103,13 @@ char pseudo_flag[] = { void do_pseudo(int *ip) { - char str[80]; int old_bank; int size; /* check if the directive is allowed in the current section */ - if (!(pseudo_flag[opval] & (1 << section))) - fatal_error("Directive not allowed in the current section!"); + if (!(pseudo_allowed[opval] & (1 << section))) { + fatal_error("Directive not allowed in the %s section!", section_name[section]); + } /* save current location */ old_bank = bank; @@ -82,8 +157,7 @@ do_pseudo(int *ip) if (bank != old_bank) { size = ((bank - old_bank - 1) * 8192) + loccnt; if (size) { - sprintf(str, "Warning, bank overflow by %i bytes!\n", size); - warning(str); + warning("Bank overflow by %i bytes!\n", size); } } break; @@ -165,7 +239,9 @@ do_nomlist(int *ip) /* ---- * do_db() * ---- - * .db pseudo + * .db pseudo (optype == 0) + * .text pseudo (optype == 1) + * .ascii pseudo (optype == 2) */ void @@ -175,7 +251,7 @@ do_db(int *ip) unsigned char h; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -190,7 +266,7 @@ do_db(int *ip) if (prlnbuf[*ip] == '\"') { /* check for non-zero value in ZP or BSS sections */ if (section == S_ZP || section == S_BSS) { - error("Cannot store non-zero data in .zp or .bss sections!"); + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } @@ -297,6 +373,10 @@ do_db(int *ip) } /* bytes */ else { + /* skip SDCC's junk at the start of some .db output */ + if (sdcc_mode && prlnbuf[*ip] == '#') + (*ip)++; + /* get a byte */ if (!evaluate(ip, 0, 0)) return; @@ -307,14 +387,15 @@ do_db(int *ip) /* store byte on last pass */ if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ - if ((value != 0) && (section == S_ZP || section == S_BSS)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + if ((value != 0) && (section_flags[section] & S_NO_DATA)) { + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } - /* check for overflow */ - if (((value & 0x007FFFFF) > 0xFF) && ((value & 0x007FFFFF) < 0x007FFF80)) { - error("Overflow error!"); + /* check for overflow, except in SDCC code (-256..255 are ok) */ + /* SDCC's code generator assumes that the assembler doesn't care */ + if ((sdcc_mode == 0) && (value & ~0xFF) && ((value & ~0xFF) != ~0xFF)) { + error("Operand too large to fit in a byte!"); return; } @@ -351,7 +432,7 @@ do_db(int *ip) /* output line */ if (pass == LAST_PASS) { /* just output an address in S_ZP and S_BSS, else show the data */ - if (section == S_ZP || section == S_BSS) { + if (section_flags[section] & S_NO_DATA) { loadlc(data_loccnt, 0); data_loccnt = -1; } @@ -372,7 +453,7 @@ do_dw(int *ip) char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -381,6 +462,13 @@ do_dw(int *ip) /* get data */ for (;;) { + /* skip spaces */ + while (isspace(prlnbuf[*ip])) { ++(*ip); } + + /* skip SDCC's junk at the start of some .dw output */ + if (sdcc_mode && prlnbuf[*ip] == '#') + (*ip)++; + /* get a word */ if (!evaluate(ip, 0, 0)) return; @@ -391,14 +479,15 @@ do_dw(int *ip) /* store word on last pass */ if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ - if ((value != 0) && (section == S_ZP || section == S_BSS)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + if ((value != 0) && (section_flags[section] & S_NO_DATA)) { + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } - /* check for overflow */ - if (((value & 0x007FFFFF) > 0xFFFF) && ((value & 0x007FFFFF) < 0x007F8000)) { - error("Overflow error!"); + /* check for overflow, except in SDCC code (-65536..65535 are ok) */ + /* SDCC's code generator assumes that the assembler doesn't care */ + if ((sdcc_mode == 0) && (value & ~0xFFFF) && ((value & ~0xFFFF) != ~0xFFFF)) { + error("Operand too large to fit in a word!"); return; } @@ -434,7 +523,7 @@ do_dw(int *ip) /* output line */ if (pass == LAST_PASS) { /* just output an address in S_ZP and S_BSS, else show the data */ - if (section == S_ZP || section == S_BSS) { + if (section_flags[section] & S_NO_DATA) { loadlc(data_loccnt, 0); data_loccnt = -1; } @@ -455,7 +544,7 @@ do_dwl(int *ip) char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -474,14 +563,14 @@ do_dwl(int *ip) /* store word on last pass */ if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ - if ((value != 0) && (section == S_ZP || section == S_BSS)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + if ((value != 0) && (section_flags[section] & S_NO_DATA)) { + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } - /* check for overflow */ - if (((value & 0x007FFFFF) > 0xFFFF) && ((value & 0x007FFFFF) < 0x007F8000)) { - error("Overflow error!"); + /* check for overflow (-65536..65535 are ok) */ + if ((value & ~0xFFFF) && ((value & ~0xFFFF) != ~0xFFFF)) { + error("Operand too large to fit in a word!"); return; } @@ -517,7 +606,7 @@ do_dwl(int *ip) /* output line */ if (pass == LAST_PASS) { /* just output an address in S_ZP and S_BSS, else show the data */ - if (section == S_ZP || section == S_BSS) { + if (section_flags[section] & S_NO_DATA) { loadlc(data_loccnt, 0); data_loccnt = -1; } @@ -538,7 +627,7 @@ do_dwh(int *ip) char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -557,14 +646,14 @@ do_dwh(int *ip) /* store word on last pass */ if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ - if ((value != 0) && (section == S_ZP || section == S_BSS)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + if ((value != 0) && (section_flags[section] & S_NO_DATA)) { + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } - /* check for overflow */ - if (((value & 0x007FFFFF) > 0xFFFF) && ((value & 0x007FFFFF) < 0x007F8000)) { - error("Overflow error!"); + /* check for overflow (-65536..65535 are ok) */ + if ((value & ~0xFFFF) && ((value & ~0xFFFF) != ~0xFFFF)) { + error("Operand too large to fit in a word!"); return; } @@ -600,7 +689,7 @@ do_dwh(int *ip) /* output line */ if (pass == LAST_PASS) { /* just output an address in S_ZP and S_BSS, else show the data */ - if (section == S_ZP || section == S_BSS) { + if (section_flags[section] & S_NO_DATA) { loadlc(data_loccnt, 0); data_loccnt = -1; } @@ -621,7 +710,7 @@ do_dd(int *ip) char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -640,8 +729,8 @@ do_dd(int *ip) /* store dword on last pass */ if (pass == LAST_PASS) { /* check for non-zero value in ZP or BSS sections */ - if ((value != 0) && (section == S_ZP || section == S_BSS)) { - error("Cannot store non-zero data in .zp or .bss sections!"); + if ((value != 0) && (section_flags[section] & S_NO_DATA)) { + error("Cannot store non-zero data in .ZP or .BSS sections!"); return; } @@ -677,7 +766,7 @@ do_dd(int *ip) /* output line */ if (pass == LAST_PASS) { /* just output an address in S_ZP and S_BSS, else show the data */ - if (section == S_ZP || section == S_BSS) { + if (section_flags[section] & S_NO_DATA) { loadlc(data_loccnt, 0); data_loccnt = -1; } @@ -690,7 +779,8 @@ do_dd(int *ip) /* ---- * do_equ() * ---- - * .equ pseudo + * .equ pseudo (optype == 0) + * .set pseudo (optype == 1) */ void @@ -710,24 +800,17 @@ do_equ(int *ip) if (!evaluate(ip, ';', 1)) return; - /* check for undefined symbols - they are not allowed in .equ or .set */ - if ((undef != 0) && (kickc_mode == 0)) { - error("Symbols must be defined before their use in .EQU or .SET!"); + /* check for undefined symbols - they are only allowed in the FIRST_PASS */ + if (undef != 0) { + if ((asm_opt[OPT_FORWARD] == 0) || (pass != FIRST_PASS)) + error("Undefined symbol in operand field!"); + else + need_another_pass = 1; return; } - /* allow ".set" to change a label's value */ - if ((optype == 1) && (lablptr->type == DEFABS)) { - lablptr->value = value; - lablptr->bank = expr_valbank; - } else - if (undef != 0) { - /* needed for KickC forward-references */ - need_another_pass = 1; - } else { - /* assign value to the label */ - labldef(value, expr_valbank, CONSTANT); - } + /* assign value to the label */ + labldef(CONSTANT + optype); /* or VARIABLE */ /* output line */ if (pass == LAST_PASS) { @@ -746,14 +829,20 @@ do_equ(int *ip) void do_page(int *ip) { + /* not allowed while .phase is active */ + if (phase_offset) { + fatal_error(".PAGE cannot be changed within a .PHASE'd chunk of code!"); + return; + } + /* not allowed in procs */ - if (proc_ptr) { - fatal_error("PAGE can not be changed in procs!"); + if (proc_ptr && (section_flags[section] & S_IS_CODE)) { + fatal_error("Code .PAGE cannot be changed within a .PROC!"); return; } /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* get page index */ if (!evaluate(ip, ';', 0)) @@ -781,6 +870,12 @@ do_page(int *ip) void do_org(int *ip) { + /* not allowed while .phase is active */ + if (phase_offset) { + fatal_error(".ORG cannot be changed within a .PHASE'd chunk of code!"); + return; + } + /* get the .org value */ if (!evaluate(ip, ';', 0)) return; @@ -794,8 +889,8 @@ do_org(int *ip) /* section switch */ switch (section) { case S_ZP: - /* zero page section */ - if ((value & 0x007FFF00) && ((value & 0x007FFF00) != machine->ram_base)) { + /* zero page section (accept traditional 6502 zero-page) */ + if ((value & ~0xFF) && ((value & ~0xFF) != machine->ram_base)) { error("Invalid address!"); return; } @@ -803,7 +898,7 @@ do_org(int *ip) case S_BSS: /* ram section */ - if (((value & 0x007FFFFF) < machine->ram_base) || ((value & 0x007FFFFF) >= (machine->ram_base + machine->ram_limit))) { + if ((value < machine->ram_base) || (value >= (machine->ram_base + machine->ram_limit))) { error("Invalid address!"); return; } @@ -812,13 +907,13 @@ do_org(int *ip) case S_CODE: case S_DATA: /* not allowed in procs */ - if (proc_ptr) { - fatal_error("ORG can not be changed in procs!"); + if (proc_ptr && (section_flags[section] & S_IS_CODE)) { + fatal_error("Code .ORG cannot be changed within a .PROC!"); return; } /* code and data section */ - if (value & 0x007F0000) { + if (value & ~0xFFFF) { error("Invalid address!"); return; } @@ -833,7 +928,7 @@ do_org(int *ip) discontiguous = 1; /* set label value if there was one */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output line on last pass */ if (pass == LAST_PASS) { @@ -854,20 +949,32 @@ do_bank(int *ip) { char name[128]; + /* not allowed while .phase is active */ + if (phase_offset) { + fatal_error(".BANK cannot be changed within a .PHASE'd chunk of code!"); + return; + } + /* not allowed in procs */ - if (proc_ptr) { - fatal_error("Bank can not be changed in procs!"); + if (proc_ptr && (section_flags[section] & S_IS_CODE)) { + fatal_error("Code .BANK cannot be changed within a .PROC!"); return; } /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* get bank index */ if (!evaluate(ip, 0, 0)) return; - if (value > bank_limit) { + /* check for undefined symbol - they are not allowed in .bank */ + if (undef != 0) { + error("Undefined symbol in operand field!"); + return; + } + + if (value > (unsigned)bank_limit) { error("Bank index out of range!"); return; } @@ -944,12 +1051,14 @@ do_incbin(int *ip) { FILE *fp; char *p; - char fname[128]; + char fname[PATHSZ]; int size; int step; + int offset = 0; + int length = -1; /* get file name */ - if (!getstring(ip, fname, 127)) + if (!getstring(ip, fname, PATHSZ - 1)) return; /* get file extension */ @@ -973,8 +1082,49 @@ do_incbin(int *ip) } } + /* get the optional offset and length */ + if (prlnbuf[*ip] == ',') { + /* get the offset */ + ++(*ip); + if (!evaluate(ip, 0, 0)) + return; + + if (undef != 0) { + error("Undefined symbol in offset field!"); + return; + } + + if (0 > (int)value) { + error(".INCBIN offset cannot be negative!"); + return; + } + offset = value; + + if (prlnbuf[*ip] == ',') { + /* get a byte */ + ++(*ip); + if (!evaluate(ip, 0, 0)) + return; + + if (undef != 0) { + error("Undefined symbol in length field!"); + return; + } + + if (0 > (int)value) { + error(".INCBIN length cannot be negative!"); + return; + } + length = value; + } + } + + /* check end of line */ + if (!check_eol(ip)) + return; + /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -982,23 +1132,34 @@ do_incbin(int *ip) /* open file */ if ((fp = open_file(fname, "rb")) == NULL) { - fatal_error("Can not open file!"); + fatal_error("Unable to open file!"); return; } /* get file size */ fseek(fp, 0, SEEK_END); - size = ftell(fp); - fseek(fp, 0, SEEK_SET); + size = ftell(fp) - offset; - /* check if it will fit in the rom */ - if (bank >= RESERVED_BANK) { - if ((loccnt + size) > 0x2000) { + if (size < 0) { + fclose(fp); + error(".INCBIN offset is greater than the file's length!"); + return; + } + + if (length >= 0) { + if (length > size) { fclose(fp); - fatal_error("PROC overflow!"); + error(".INCBIN length is greater than the file's length!"); return; - } - } else { + } + size = length; + } + + /* seek to the file offset */ + fseek(fp, offset, SEEK_SET); + + /* check if it will fit in the rom */ + if ((section_flags[section] & S_IS_ROM) && (bank < UNDEFINED_BANK)) { /* check if it will fit in the rom */ if (((bank << 13) + loccnt + size) > rom_limit) { fclose(fp); @@ -1030,6 +1191,12 @@ do_incbin(int *ip) /* output line */ println(); } + } else { + if ((loccnt + size) > section_limit[section]) { + fclose(fp); + fatal_error("Too large to fit in the current section!"); + return; + } } /* close file */ @@ -1051,7 +1218,7 @@ do_incbin(int *ip) } /* update rom size */ - if (bank < RESERVED_BANK) { + if ((section_flags[section] & S_IS_ROM) && (bank < UNDEFINED_BANK)) { if (bank > max_bank) { if (loccnt) max_bank = bank; @@ -1096,7 +1263,7 @@ do_mx(char *fname) /* open the file */ if ((fp = open_file(fname, "r")) == NULL) { - fatal_error("Can not open file!"); + fatal_error("Unable to open file!"); return; } @@ -1170,7 +1337,7 @@ do_mx(char *fname) /* define label */ if (flag == 0) { flag = 1; - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1195,7 +1362,7 @@ do_mx(char *fname) /* define label */ if (flag == 0) { - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1220,31 +1387,6 @@ do_mx(char *fname) } -/* ---- - * forget_included_files() - * ---- - * keep a list of the .include files during each pass - */ - -typedef struct t_filelist { - struct t_filelist * next; - int size; - char name[128]; -} t_filelist; - -t_filelist * included_files = NULL; - -void -forget_included_files(void) -{ - t_filelist * list = included_files; - while ((list = included_files) != NULL) { - included_files = list->next; - free(list); - } -} - - /* ---- * do_include() * ---- @@ -1254,55 +1396,37 @@ forget_included_files(void) void do_include(int *ip) { - char fname[128]; - int fsize; - int found_include; - t_filelist * list; + char fname[PATHSZ]; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); #if 0 // This breaks @turboxray's code, so disable it for now. /* avoid problems */ if (expand_macro) { - error("Cannot use INCLUDE inside a macro!"); + error("Cannot use .INCLUDE inside a macro!"); return; } #endif - /* get file name */ - if (!getstring(ip, fname, 127)) - return; - - /* have we already included this file on this pass? */ - fsize = strlen(fname); - found_include = 0; - - for (list = included_files; list != NULL; list = list->next) { - if ((list->size == fsize) && (strcasecmp(list->name, fname) == 0)) { - found_include = 1; - break; - } - } - - /* do not include the file a 2nd time on this pass */ - if (!found_include) { - /* remember include file name */ - if ((list = malloc(sizeof(t_filelist) + fsize - 127)) == NULL) { - fatal_error("Out of memory!"); + /* if this is an SDCC .module pseudo-op then auto-include sdcc.asm */ + if (optype == 1) { + /* ignore the module name and everything else on the line */ + strcpy(fname, "sdcc.asm"); + } else { + /* get file name */ + if (!getstring(ip, fname, PATHSZ - 1)) return; - } - - strcpy(list->name, fname); - list->size = fsize; - list->next = included_files; - included_files = list; - /* open file */ - if (open_input(fname) == -1) { - fatal_error("Can not open file!"); + /* check end of line */ + if (!check_eol(ip)) return; - } + } + + /* open file */ + if (open_input(fname) == -1) { + fatal_error("Unable to open file!"); + return; } /* output line */ @@ -1321,23 +1445,24 @@ void do_rsset(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* get value */ if (!evaluate(ip, ';', 1)) return; - if (value & 0x007F0000) { + if (value & ~0xFFFF) { error("Address out of range!"); return; } /* set 'rs' base and bank */ - rsbase = value & 0xFFFF; - rsbank = expr_valbank; + rs_base = value; + rs_mprbank = expr_mprbank; + rs_overlay = expr_overlay; /* output line */ if (pass == LAST_PASS) { - loadlc(rsbase, 1); + loadlc(rs_base, 1); println(); } } @@ -1352,10 +1477,13 @@ do_rsset(int *ip) void do_rs(int *ip) { - int oldrs = rsbase; + int old_rs = rs_base; /* define label */ - labldef(rsbase, rsbank, CONSTANT); + value = rs_base; + expr_mprbank = rs_mprbank; + expr_overlay = rs_overlay; + labldef(CONSTANT); /* get the number of bytes to reserve */ if (!evaluate(ip, ';', 0)) @@ -1363,20 +1491,20 @@ do_rs(int *ip) /* ouput line */ if (pass == LAST_PASS) { - loadlc(rsbase, 1); + loadlc(rs_base, 1); println(); } /* update 'rs' base */ - rsbase += value; - if (rsbase & 0x007F0000) + rs_base += value; + if (rs_base & ~0xFFFF) error("Address out of range!"); /* update 'rs' bank */ - if (rsbank != RESERVED_BANK) { - while ((oldrs & 0xE000) != (rsbase & 0xE000)) { - oldrs += 0x2000; - ++rsbank; + if (rs_mprbank != UNDEFINED_BANK) { + while ((old_rs & 0xE000) != (rs_base & 0xE000)) { + old_rs += 0x2000; + ++rs_mprbank; } } } @@ -1391,15 +1519,14 @@ do_rs(int *ip) void do_ds(int *ip) { - int limit = 0; int addr; int step; - unsigned int nbytes; + int nbytes; unsigned int filler = 0; unsigned char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -1411,7 +1538,10 @@ do_ds(int *ip) /* check for undefined symbol - they are not allowed in .ds */ if (undef != 0) { - error("Undefined symbol in operand field!"); + if ((asm_opt[OPT_FORWARD] == 0) || (pass != FIRST_PASS)) + error("Undefined symbol in operand field!"); + else + need_another_pass = 1; return; } @@ -1442,34 +1572,22 @@ do_ds(int *ip) return; } - /* section switch */ - switch (section) { - case S_ZP: - /* zero page section */ - limit = machine->zp_limit; - break; - - case S_BSS: - /* ram section */ - limit = machine->ram_limit; - break; + /* check range */ + addr = loccnt + nbytes; - case S_CODE: - case S_DATA: - /* code and data sections */ - limit = 0x2000; - break; + if ((section_flags[section] & S_IS_ROM) && (bank < UNDEFINED_BANK)) { + if (((bank << 13) + addr) > rom_limit) { + error("ROM overflow!"); + return; + } } - - /* check range */ - if ((loccnt + nbytes) > limit) { + else + if (addr > section_limit[section]) { error("The .DS is too large for the current bank or section!"); return; } /* update max counter for zp and bss sections */ - addr = loccnt + nbytes; - switch (section) { case S_ZP: /* zero page */ @@ -1482,13 +1600,6 @@ do_ds(int *ip) if (addr > max_bss) max_bss = addr; break; - - default: - /* rom page */ - if (((bank << 13) + addr) > rom_limit) { - error("ROM overflow!"); - return; - } } /* output line on last pass */ @@ -1539,7 +1650,7 @@ do_ds(int *ip) } /* update rom size */ - if (bank < RESERVED_BANK) { + if ((section_flags[section] & S_IS_ROM) && (bank < UNDEFINED_BANK)) { if (bank > max_bank) { if (loccnt) max_bank = bank; @@ -1588,31 +1699,13 @@ do_fail(int *ip) /* ---- * do_section() * ---- - * .zp/.bss/.code/.data pseudo + * .zp/.bss/.home/.code/.data pseudo */ void do_section(int *ip) { - if (section != optype) { - /* backup current section data */ - section_bank[section] = bank; - bank_glabl[section][bank] = glablptr; - bank_loccnt[section][bank] = loccnt; - bank_page[section][bank] = page; - - /* change section */ - section = optype; - - /* switch to the new section */ - bank = section_bank[section]; - page = bank_page[section][bank]; - loccnt = bank_loccnt[section][bank]; - glablptr = bank_glabl[section][bank]; - - /* signal discontiguous change in loccnt */ - discontiguous = 1; - } + set_section(optype); /* output line */ if (pass == LAST_PASS) { @@ -1632,14 +1725,14 @@ void do_incchr(int *ip) { unsigned char buffer[32]; - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int tx, ty; + int tx, ty; int total = 0; int size; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1752,6 +1845,8 @@ do_opt(int *ip) asm_opt[OPT_LBRANCH] = i; else if (!strcasecmp(name, "d")) asm_opt[OPT_DATAPAGE] = i; + else if (!strcasecmp(name, "f")) + asm_opt[OPT_FORWARD] = i; else { error("Unknown option!"); return; @@ -1792,6 +1887,12 @@ do_align(int *ip) { int offset; + /* not allowed while .phase is active - but could be implemented if needed */ + if (phase_offset) { + fatal_error("Cannot .ALIGN within a .PHASE'd chunk of code!"); + return; + } + /* get the .align value */ if (!evaluate(ip, ';', 0)) return; @@ -1804,7 +1905,7 @@ do_align(int *ip) /* check for power-of-two, 1 bank maximum */ if ((value > 8192) || (value == 0) || ((value & (value - 1)) != 0)) { - error(".align value must be a power-of-two, with a maximum of 8192!"); + error(".ALIGN value must be a power-of-two, with a maximum of 8192!"); return; } @@ -1837,7 +1938,7 @@ do_align(int *ip) } /* set label value if there was one */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output line on last pass */ if (pass == LAST_PASS) { @@ -1847,34 +1948,81 @@ do_align(int *ip) } +/* ---- + * do_3pass() + * ---- + * .3pass pseudo (optype == 0) + */ + +void +do_3pass(int *ip) +{ + /* define label */ + labldef(LOCATION); + + /* check end of line */ + if (optype == 0 && !check_eol(ip)) + return; + + /* signal that an extra pass is wanted */ + if (pass == FIRST_PASS) + need_another_pass = 1; + + /* enable forward-reference support in 3pass mode */ + asm_opt[OPT_FORWARD] = 1; + + /* output line */ + if (pass == LAST_PASS) + println(); +} + + /* ---- * do_kickc() * ---- - * .pceas pseudo - * .kickc pseudo + * .pceas pseudo (optype == 0) + * .kickc pseudo (optype == 1) (for KickC code) + * .r6502 pseudo (optype == 2) (for compatibility with SDCC) + * .r65c02 pseudo (optype == 2) (for compatibility with SDCC) */ void do_kickc(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* check end of line */ if (!check_eol(ip)) return; - /* enable/disable KickC mode */ - kickc_mode = optype; + /* enable/disable KickC, SDCC or HuCC mode */ + kickc_mode = (optype & 1) >> 0; + sdcc_mode = (optype & 2) >> 1; + hucc_mode = (optype & 4) >> 2; + + /* signal to include final.asm, but not if already inside final.asm */ + if (!in_final) { + kickc_final |= kickc_mode; + hucc_final |= (sdcc_mode | hucc_mode); + } - /* enable () for indirect addressing in KickC mode */ - asm_opt[OPT_INDPAREN] = optype; + /* enable () for indirect addressing during KickC code */ + asm_opt[OPT_INDPAREN] = kickc_mode; - /* enable auto-detect ZP addressing in KickC mode */ - asm_opt[OPT_ZPDETECT] = optype; + /* enable auto-detect ZP addressing during KickC and SDCC code */ + /* for SDCC, this is needed to assemble library function params into ZP */ + asm_opt[OPT_ZPDETECT] = (kickc_mode | sdcc_mode | hucc_mode); - /* enable long-branch support in KickC mode */ - asm_opt[OPT_LBRANCH] = optype; + /* enable long-branch support when building KickC code */ + asm_opt[OPT_LBRANCH] |= (kickc_mode | hucc_mode); + + /* enable forward-references when building KickC code */ + asm_opt[OPT_FORWARD] |= kickc_mode; + + /* disable C comments in HuCC code, it breaks HuCC's macro comments */ + if (hucc_mode) + asm_opt[OPT_CCOMMENT] = 0; /* output line */ if (pass == LAST_PASS) @@ -1883,17 +2031,21 @@ do_kickc(int *ip) /* ---- - * do_cpu() + * do_ignore() * ---- - * .cpu pseudo (ignored, only for compatibility with KickC) + * .cpu pseudo (ignored, for compatibility with KickC) + * .encoding pseudo (ignored, for compatibility with KickC) + * .optsdcc pseudo (ignored, for compatibility with SDCC) + * .globl pseudo (ignored, for compatibility with SDCC) */ void -do_cpu(int *ip) +do_ignore(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); +#if 0 /* skip spaces */ while (isspace(prlnbuf[*ip])) (*ip)++; @@ -1908,6 +2060,7 @@ do_cpu(int *ip) /* check end of line */ if (!check_eol(ip)) return; +#endif /* output line */ if (pass == LAST_PASS) @@ -1918,14 +2071,15 @@ do_cpu(int *ip) /* ---- * do_segment() * ---- - * .segment pseudo (for KickC code) + * .segment pseudo (optype == 0) (for compatibility with KickC) + * .area pseudo (optype == 1) (for compatibility with SDCC) */ void do_segment(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* skip spaces */ while (isspace(prlnbuf[*ip])) @@ -1939,7 +2093,7 @@ do_segment(int *ip) } /* check end of line */ - if (!check_eol(ip)) + if (sdcc_mode == 0 && !check_eol(ip)) return; /* which segment? */ @@ -1952,10 +2106,51 @@ do_segment(int *ip) if (!strcasecmp(&symbol[1], "CODE")) optype = S_CODE; else - if (!strcasecmp(&symbol[1], "DATA")) - optype = S_DATA; + if (!strcasecmp(&symbol[1], "DATA")) { + if (sdcc_mode) + optype = S_XDATA; + else + optype = S_DATA; + } + else + if (!strcasecmp(&symbol[1], "XDATA")) + optype = S_XDATA; + else + if (!strcasecmp(&symbol[1], "XINIT")) + optype = S_XINIT; + else + if (!strcasecmp(&symbol[1], "CONST")) + optype = S_CONST; + else + if (!strcasecmp(&symbol[1], "RODATA")) + optype = S_CONST; + else + if (!strcasecmp(&symbol[1], "OSEG")) + optype = S_OSEG; + else + if (!strcasecmp(&symbol[1], "_CODE")) + optype = S_HOME; + else + if (!strcasecmp(&symbol[1], "_DATA")) { + if (sdcc_mode) + optype = S_DATA; + else + optype = S_NONE; + } + else + if (!strcasecmp(&symbol[1], "CABS")) + optype = S_NONE; + else + if (!strcasecmp(&symbol[1], "DABS")) + optype = S_NONE; + else + if (!strcasecmp(&symbol[1], "GSINIT")) + optype = S_NONE; + else + if (!strcasecmp(&symbol[1], "GSFINAL")) + optype = S_NONE; else { - fatal_error("Segment can only be CODE, DATA, BSS or ZP!"); + fatal_error("Unknown %s name!", (optype) ? ".AREA" : ".SEGMENT"); return; } @@ -1990,14 +2185,14 @@ do_star(int *ip) /* ---- * do_label() * ---- - * .label & .const pseudo (for KickC code) + * .label & .const pseudo (for compatibility with KickC) */ void do_label(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* skip spaces */ while (isspace(prlnbuf[*ip])) @@ -2028,41 +2223,6 @@ do_label(int *ip) } -/* ---- - * do_encoding() - * ---- - * .encoding pseudo (ignored, only for compatibility with KickC) - */ - -void -do_encoding(int *ip) -{ - /* define label */ - labldef(0, 0, LOCATION); - - /* skip spaces */ - while (isspace(prlnbuf[*ip])) - (*ip)++; - -#if 0 - /* extract name */ - if (!colsym(ip, 0)) { - if (symbol[0] == 0) - fatal_error("Syntax error!"); - return; - } - - /* check end of line */ - if (!check_eol(ip)) - return; -#endif - - /* output line */ - if (pass == LAST_PASS) - println(); -} - - /* ---- * do_struct() * ---- @@ -2072,35 +2232,41 @@ do_encoding(int *ip) void do_struct(int *ip) { + /* not allowed while .phase is active */ + if (phase_offset) { + fatal_error("Cannot declare a .STRUCT within a .PHASE'd chunk of code!"); + return; + } + /* the code is written to handle nesting, but try */ /* this temporarily, while we see if it is needed */ if (scopeptr != NULL) { - fatal_error("Cannot nest .struct scopes!"); + fatal_error("Cannot nest .STRUCT scopes!"); return; } /* do not mix different types of label-scope */ if (proc_ptr) { - fatal_error("Cannot declare a .struct inside a .proc/.procgroup!"); + fatal_error("Cannot declare a .STRUCT inside a .PROC/.PROCGROUP!"); return; } /* check symbol */ if (lablptr == NULL) { - fatal_error("Label name missing from .struct!"); + fatal_error("Label name missing from .STRUCT!"); return; } if (lablptr->name[1] == '.' || lablptr->name[1] == '@') { - fatal_error("Cannot open .struct scope on a local label!"); + fatal_error("Cannot open .STRUCT scope on a local label!"); return; } if (lablptr->name[1] == '!') { - fatal_error("Cannot open .struct scope on a multi-label!"); + fatal_error("Cannot open .STRUCT scope on a multi-label!"); return; } /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* check end of line */ if (!check_eol(ip)) @@ -2130,7 +2296,7 @@ do_ends(int *ip) /* sanity check */ if (scopeptr == NULL) { - fatal_error("Unexpected '.ends'!"); + fatal_error("Unexpected .ENDS!"); return; } @@ -2143,11 +2309,17 @@ do_ends(int *ip) do_section(ip); /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* remember the size of the scope */ scopeptr->data_type = P_STRUCT; - scopeptr->data_size = (loccnt + (bank << 13)) - ((scopeptr->value & 0x1FFF) + (scopeptr->bank << 13)); + + // fixme: + fatal_error("This needs to be fixed, but not today!"); + return; + // end of fixme: + + scopeptr->data_size = (loccnt + (bank << 13)) - ((scopeptr->value & 0x1FFF) + (scopeptr->mprbank << 13)); /* add a label with the scope size */ i = addscope(scopeptr, 0); @@ -2164,7 +2336,7 @@ do_ends(int *ip) return; /* assign value to the label */ - labldef(scopeptr->data_size, RESERVED_BANK, CONSTANT); +// labldef(scopeptr->data_size, UNDEFINED_BANK, 0, CONSTANT); /* restore the previous label */ lablptr = curlabl; @@ -2178,6 +2350,271 @@ do_ends(int *ip) } +/* ---- + * do_alias() + * ---- + * .alias pseudo + */ + +void +do_alias(int *ip) +{ + struct t_symbol *alias; + int i; + + + /* get alias name */ + if (lablptr) { + /* go back to the unaliased label */ + if (lablptr != unaliased) { + lablptr = unaliased; + } + + /* copy the procedure name from the label */ + strcpy(symbol, lablptr->name); + } + else { + /* skip spaces */ + while (isspace(prlnbuf[*ip])) + (*ip)++; + + /* extract name */ + if (!colsym(ip, 0)) { + /* was there a bad symbol */ + if (symbol[0]) + return; + /* or just no symbol at all */ + fatal_error(".ALIAS name is missing!"); + return; + } + + /* lookup symbol table */ + if ((lablptr = stlook(SYM_DEF)) == NULL) + return; + + /* go back to the unaliased label */ + if (lablptr != unaliased) { + lablptr = unaliased; + } + + /* skip spaces */ + while (isspace(prlnbuf[*ip])) + (*ip)++; + + if (prlnbuf[(*ip)++] != '=') { + fatal_error("Syntax error!"); + return; + } + } + + /* check symbol */ + if (symbol[1] == '.' || symbol[1] == '@') { + error(".ALIAS name cannot be a local label!"); + return; + } + if (symbol[1] == '!') { + error(".ALIAS name cannot be a multi-label!"); + return; + } + + /* is the symbol already used for somthing else */ + if (lablptr->type == MACRO) { + error("Symbol already used by a macro!"); + return; + } + if (lablptr->type == FUNC) { + error("Symbol already used by a function!"); + return; + } + if (lablptr->type == DEFABS || lablptr->type == MDEF ) { + error("Symbol already used by a label!"); + return; + } + if (lablptr->reserved) { + error("Reserved symbol!"); + return; + } + + /* skip spaces */ + while (isspace(prlnbuf[*ip])) + (*ip)++; + + /* make sure that it's not an instruction or pseudo op, N.B. "i" is altered by oplook() */ + i = *ip; + if (oplook(&i) >= 0) { + fatal_error("Cannot create a .ALIAS to an instruction name!"); + return; + } + + /* extract symbol name of .ALIAS target */ + if (!colsym(ip, 0)) { + /* was there a bad symbol */ + if (symbol[0] == 0) + return; + /* or just no symbol at all */ + error(".ALIAS target symbol name is missing!"); + return; + } + + /* check end of line */ + if (!check_eol(ip)) + return; + + /* check symbol */ + if (symbol[1] == '.' || symbol[1] == '@') { + fatal_error("Cannot create a .ALIAS to a local label!"); + return; + } + if (symbol[1] == '!') { + fatal_error("Cannot create a .ALIAS to a multi-label!"); + return; + } + + /* check for redefinition */ + if (lablptr->type == ALIAS) { + alias = lablptr->local; + if (strcmp(alias->name, symbol) != 0) { + error(".ALIAS was already defined differently!"); + return; + } + } else { + /* lookup or create the target symbol name */ + if ((alias = stlook(SYM_DEF)) == NULL) + return; + + /* is the symbol already used for somthing else */ + if (alias->type == MACRO) { + error("Cannot create a .ALIAS to a macro!"); + return; + } + if (alias->type == FUNC) { + error("Cannot create a .ALIAS to a function!"); + return; + } + if (alias->reserved) { + error("Cannot create a .ALIAS to a reserved symbol!"); + return; + } + + /* define alias */ + lablptr->type = ALIAS; + lablptr->local = alias; + + /* remember where this was defined */ + lablptr->fileinfo = input_file[infile_num].file; + lablptr->fileline = slnum; + + /* the alias needs to inherit any previous references to the label */ + alias->refthispass += lablptr->refthispass; + } + + /* check for circular definition */ + if (strcmp(lablptr->name, alias->name) == 0) { + error(".ALIAS cannot refer to itself!"); + return; + } + + /* record definition */ + lablptr->defthispass = 1; + + /* output */ + if (pass == LAST_PASS) { + loadlc(loccnt, 0); + println(); + } +} + + +/* ---- + * do_ref() + * ---- + * .ref pseudo + */ + +void +do_ref(int *ip) +{ + /* define label */ + labldef(LOCATION); + + /* evaluate expression to increment a label's reference count */ + if (!evaluate(ip, ';', 0)) + return; + + /* output line */ + if (pass == LAST_PASS) { + loadlc(loccnt, 0); + println(); + } +} + + +/* ---- + * do_phase() + * ---- + * .phase pseudo (optype == 0) + * .dephase pseudo (optype == 1) + */ + +void +do_phase(int *ip) +{ + /* set label value if there was one */ + labldef(LOCATION); + + if (optype == 0) { + /* not allowed while .phase is active */ + if (phase_offset) { + error("Already in a .PHASE'd chunk of code!"); + return; + } + + /* get the .phase value */ + if (!evaluate(ip, ';', 0)) + return; + + /* check for undefined symbols - they are only allowed in the FIRST_PASS */ + if (undef != 0) { + phase_offset = 1; + + if ((asm_opt[OPT_FORWARD] == 0) || (pass != FIRST_PASS)) + error("Undefined symbol in operand field!"); + else + need_another_pass = 1; + return; + } + + /* check for address out of range */ + if (value > 0xFFFF) { + error(".PHASE value must be an address $0000..$FFFF!"); + return; + } + + } else { + /* not allowed while .phase is inactive */ + if (!phase_offset) { + error("Not in a .PHASE'd chunk of code!"); + return; + } + + /* check end of line */ + if (!check_eol(ip)) + return; + + value = (loccnt + (page << 13)); + } + + /* output line on last pass */ + if (pass == LAST_PASS) { + loadlc(loccnt, 0); + println(); + } + + /* set the phase_offset to add to subsequent location labels */ + phase_offset = value - (loccnt + (page << 13)); +} + + /* ---- * htoi() * ---- @@ -2206,3 +2643,35 @@ htoi(char *str, int nb) /* ok */ return (val); } + + +/* ---- + * set_section(int new_section) + * ---- + */ + +void +set_section(int new_section) +{ + if (section != new_section) { + /* backup current section data */ + section_bank[section] = bank; + bank_glabl[section][bank] = glablptr; + bank_loccnt[section][bank] = loccnt; + bank_page[section][bank] = page; + section_phase[section] = phase_offset; + + /* change section */ + section = new_section; + + /* switch to the new section */ + bank = section_bank[section]; + page = bank_page[section][bank]; + loccnt = bank_loccnt[section][bank]; + glablptr = bank_glabl[section][bank]; + phase_offset = section_phase[section]; + + /* signal discontiguous change in loccnt */ + discontiguous = 1; + } +} diff --git a/src/mkit/as/crc.c b/src/mkit/as/crc.c index 2aae688d..1978575b 100644 --- a/src/mkit/as/crc.c +++ b/src/mkit/as/crc.c @@ -1,55 +1,191 @@ -/* locals */ -static unsigned int crc_table[256]; +/* ---- + * crc32_table + * ---- + * The following CRC lookup table was generated automagically by the + * Rocksoft(tm) Model CRC Algorithm Table Generation Program V1.0 using + * the following model parameters: + * + * Width : 4 bytes. + * Poly : 0x04C11DB7L + * Reverse : true. + * + * For more information on the Rocksoft(tm) Model CRC Algorithm, see the + * document titled "A Painless Guide to CRC Error Detection Algorithms" + * by Ross Williams (ross@guest.adelaide.edu.au.). This document is + * likely to be in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". + */ + +unsigned int crc32_table[256] = +{ + 0x00000000u, 0x77073096u, 0xEE0E612Cu, 0x990951BAu, + 0x076DC419u, 0x706AF48Fu, 0xE963A535u, 0x9E6495A3u, + 0x0EDB8832u, 0x79DCB8A4u, 0xE0D5E91Eu, 0x97D2D988u, + 0x09B64C2Bu, 0x7EB17CBDu, 0xE7B82D07u, 0x90BF1D91u, + 0x1DB71064u, 0x6AB020F2u, 0xF3B97148u, 0x84BE41DEu, + 0x1ADAD47Du, 0x6DDDE4EBu, 0xF4D4B551u, 0x83D385C7u, + 0x136C9856u, 0x646BA8C0u, 0xFD62F97Au, 0x8A65C9ECu, + 0x14015C4Fu, 0x63066CD9u, 0xFA0F3D63u, 0x8D080DF5u, + 0x3B6E20C8u, 0x4C69105Eu, 0xD56041E4u, 0xA2677172u, + 0x3C03E4D1u, 0x4B04D447u, 0xD20D85FDu, 0xA50AB56Bu, + 0x35B5A8FAu, 0x42B2986Cu, 0xDBBBC9D6u, 0xACBCF940u, + 0x32D86CE3u, 0x45DF5C75u, 0xDCD60DCFu, 0xABD13D59u, + 0x26D930ACu, 0x51DE003Au, 0xC8D75180u, 0xBFD06116u, + 0x21B4F4B5u, 0x56B3C423u, 0xCFBA9599u, 0xB8BDA50Fu, + 0x2802B89Eu, 0x5F058808u, 0xC60CD9B2u, 0xB10BE924u, + 0x2F6F7C87u, 0x58684C11u, 0xC1611DABu, 0xB6662D3Du, + 0x76DC4190u, 0x01DB7106u, 0x98D220BCu, 0xEFD5102Au, + 0x71B18589u, 0x06B6B51Fu, 0x9FBFE4A5u, 0xE8B8D433u, + 0x7807C9A2u, 0x0F00F934u, 0x9609A88Eu, 0xE10E9818u, + 0x7F6A0DBBu, 0x086D3D2Du, 0x91646C97u, 0xE6635C01u, + 0x6B6B51F4u, 0x1C6C6162u, 0x856530D8u, 0xF262004Eu, + 0x6C0695EDu, 0x1B01A57Bu, 0x8208F4C1u, 0xF50FC457u, + 0x65B0D9C6u, 0x12B7E950u, 0x8BBEB8EAu, 0xFCB9887Cu, + 0x62DD1DDFu, 0x15DA2D49u, 0x8CD37CF3u, 0xFBD44C65u, + 0x4DB26158u, 0x3AB551CEu, 0xA3BC0074u, 0xD4BB30E2u, + 0x4ADFA541u, 0x3DD895D7u, 0xA4D1C46Du, 0xD3D6F4FBu, + 0x4369E96Au, 0x346ED9FCu, 0xAD678846u, 0xDA60B8D0u, + 0x44042D73u, 0x33031DE5u, 0xAA0A4C5Fu, 0xDD0D7CC9u, + 0x5005713Cu, 0x270241AAu, 0xBE0B1010u, 0xC90C2086u, + 0x5768B525u, 0x206F85B3u, 0xB966D409u, 0xCE61E49Fu, + 0x5EDEF90Eu, 0x29D9C998u, 0xB0D09822u, 0xC7D7A8B4u, + 0x59B33D17u, 0x2EB40D81u, 0xB7BD5C3Bu, 0xC0BA6CADu, + 0xEDB88320u, 0x9ABFB3B6u, 0x03B6E20Cu, 0x74B1D29Au, + 0xEAD54739u, 0x9DD277AFu, 0x04DB2615u, 0x73DC1683u, + 0xE3630B12u, 0x94643B84u, 0x0D6D6A3Eu, 0x7A6A5AA8u, + 0xE40ECF0Bu, 0x9309FF9Du, 0x0A00AE27u, 0x7D079EB1u, + 0xF00F9344u, 0x8708A3D2u, 0x1E01F268u, 0x6906C2FEu, + 0xF762575Du, 0x806567CBu, 0x196C3671u, 0x6E6B06E7u, + 0xFED41B76u, 0x89D32BE0u, 0x10DA7A5Au, 0x67DD4ACCu, + 0xF9B9DF6Fu, 0x8EBEEFF9u, 0x17B7BE43u, 0x60B08ED5u, + 0xD6D6A3E8u, 0xA1D1937Eu, 0x38D8C2C4u, 0x4FDFF252u, + 0xD1BB67F1u, 0xA6BC5767u, 0x3FB506DDu, 0x48B2364Bu, + 0xD80D2BDAu, 0xAF0A1B4Cu, 0x36034AF6u, 0x41047A60u, + 0xDF60EFC3u, 0xA867DF55u, 0x316E8EEFu, 0x4669BE79u, + 0xCB61B38Cu, 0xBC66831Au, 0x256FD2A0u, 0x5268E236u, + 0xCC0C7795u, 0xBB0B4703u, 0x220216B9u, 0x5505262Fu, + 0xC5BA3BBEu, 0xB2BD0B28u, 0x2BB45A92u, 0x5CB36A04u, + 0xC2D7FFA7u, 0xB5D0CF31u, 0x2CD99E8Bu, 0x5BDEAE1Du, + 0x9B64C2B0u, 0xEC63F226u, 0x756AA39Cu, 0x026D930Au, + 0x9C0906A9u, 0xEB0E363Fu, 0x72076785u, 0x05005713u, + 0x95BF4A82u, 0xE2B87A14u, 0x7BB12BAEu, 0x0CB61B38u, + 0x92D28E9Bu, 0xE5D5BE0Du, 0x7CDCEFB7u, 0x0BDBDF21u, + 0x86D3D2D4u, 0xF1D4E242u, 0x68DDB3F8u, 0x1FDA836Eu, + 0x81BE16CDu, 0xF6B9265Bu, 0x6FB077E1u, 0x18B74777u, + 0x88085AE6u, 0xFF0F6A70u, 0x66063BCAu, 0x11010B5Cu, + 0x8F659EFFu, 0xF862AE69u, 0x616BFFD3u, 0x166CCF45u, + 0xA00AE278u, 0xD70DD2EEu, 0x4E048354u, 0x3903B3C2u, + 0xA7672661u, 0xD06016F7u, 0x4969474Du, 0x3E6E77DBu, + 0xAED16A4Au, 0xD9D65ADCu, 0x40DF0B66u, 0x37D83BF0u, + 0xA9BCAE53u, 0xDEBB9EC5u, 0x47B2CF7Fu, 0x30B5FFE9u, + 0xBDBDF21Cu, 0xCABAC28Au, 0x53B39330u, 0x24B4A3A6u, + 0xBAD03605u, 0xCDD70693u, 0x54DE5729u, 0x23D967BFu, + 0xB3667A2Eu, 0xC4614AB8u, 0x5D681B02u, 0x2A6F2B94u, + 0xB40BBE37u, 0xC30C8EA1u, 0x5A05DF1Bu, 0x2D02EF8Du +}; /* ---- - * crc_init() + * ascii_lower_case * ---- + * Characters 0x00-0x7F = ASCII (incorporated in the Unicode standard). + * Characters 0x80-0xFF = unchanged + * + * N.B. This also remaps the DOS path separator "\" to the UNIX "/". */ -void -crc_init(void) +#if defined(_WIN32) || defined(__APPLE__) +unsigned char ascii_lower_case[256] = { - int i; - unsigned int t, *p, *q; - unsigned int poly = 0x864CFB; - - p = q = crc_table; - *q++ = 0; - *q++ = poly; - - for (i = 1; i < 128; i++) { - t = *(++p); - if (t & 0x800000) { - t <<= 1; - *q++ = t ^ poly; - *q++ = t; - } - else { - t <<= 1; - *q++ = t; - *q++ = t ^ poly; - } - } -} + 0x00u, 0x01u, 0x02u, 0x03u, 0x04u, 0x05u, 0x06u, 0x07u, // + 0x08u, 0x09u, 0x0Au, 0x0Bu, 0x0Cu, 0x0Du, 0x0Eu, 0x0Fu, // + 0x10u, 0x11u, 0x12u, 0x13u, 0x14u, 0x15u, 0x16u, 0x17u, // + 0x18u, 0x19u, 0x1Au, 0x1Bu, 0x1Cu, 0x1Du, 0x1Eu, 0x1Fu, // + + 0x20u, 0x21u, 0x22u, 0x23u, 0x24u, 0x25u, 0x26u, 0x27u, // " !"#$%&'" + 0x28u, 0x29u, 0x2Au, 0x2Bu, 0x2Cu, 0x2Du, 0x2Eu, 0x2Fu, // "()*+,-./" + 0x30u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u, // "01234567" + 0x38u, 0x39u, 0x3Au, 0x3Bu, 0x3Cu, 0x3Du, 0x3Eu, 0x3Fu, // "89:;<=>?" + + 0x40u, 0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, // "@ABCDEFG" + 0x68u, 0x69u, 0x6Au, 0x6Bu, 0x6Cu, 0x6Du, 0x6Eu, 0x6Fu, // "HIJKLMNO" + 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, 0x75u, 0x76u, 0x77u, // "PQRSTUVW" +#if defined(_WIN32) + 0x78u, 0x79u, 0x7Au, 0x5Bu, 0x2Fu, 0x5Du, 0x5Eu, 0x5Fu, // "XYZ[\]^_" +#else + 0x78u, 0x79u, 0x7Au, 0x5Bu, 0x5Cu, 0x5Du, 0x5Eu, 0x5Fu, // "XYZ[\]^_" +#endif + + 0x60u, 0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, // "`abcdefg" + 0x68u, 0x69u, 0x6Au, 0x6Bu, 0x6Cu, 0x6Du, 0x6Eu, 0x6Fu, // "hijklmno" + 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, 0x75u, 0x76u, 0x77u, // "pqrstuvw" + 0x78u, 0x79u, 0x7Au, 0x7Bu, 0x7Cu, 0x7Du, 0x7Eu, 0x7Fu, // "xyz{|}~" + + 0x80u, 0x81u, 0x82u, 0x83u, 0x84u, 0x85u, 0x86u, 0x87u, // + 0x88u, 0x89u, 0x8Au, 0x8Bu, 0x8Cu, 0x8Du, 0x8Eu, 0x8Fu, // + 0x90u, 0x91u, 0x92u, 0x93u, 0x94u, 0x95u, 0x96u, 0x97u, // + 0x98u, 0x99u, 0x9Au, 0x9Bu, 0x9Cu, 0x9Du, 0x9Eu, 0x9Fu, // + + 0xA0u, 0xA1u, 0xA2u, 0xA3u, 0xA4u, 0xA5u, 0xA6u, 0xA7u, // + 0xA8u, 0xA9u, 0xAAu, 0xABu, 0xACu, 0xADu, 0xAEu, 0xAFu, // + 0xB0u, 0xB1u, 0xB2u, 0xB3u, 0xB4u, 0xB5u, 0xB6u, 0xB7u, // + 0xB8u, 0xB9u, 0xBAu, 0xBBu, 0xBCu, 0xBDu, 0xBEu, 0xBFu, // + + 0xC0u, 0xC1u, 0xC2u, 0xC3u, 0xC4u, 0xC5u, 0xC6u, 0xC7u, // + 0xC8u, 0xC9u, 0xCAu, 0xCBu, 0xCCu, 0xCDu, 0xCEu, 0xCFu, // + 0xD0u, 0xD1u, 0xD2u, 0xD3u, 0xD4u, 0xD5u, 0xD6u, 0xD7u, // + 0xD8u, 0xD9u, 0xDAu, 0xDBu, 0xDCu, 0xDDu, 0xDEu, 0xDFu, // + + 0xE0u, 0xE1u, 0xE2u, 0xE3u, 0xE4u, 0xE5u, 0xE6u, 0xE7u, // + 0xE8u, 0xE9u, 0xEAu, 0xEBu, 0xECu, 0xEDu, 0xEEu, 0xEFu, // + 0xF0u, 0xF1u, 0xF2u, 0xF3u, 0xF4u, 0xF5u, 0xF6u, 0xF7u, // + 0xF8u, 0xF9u, 0xFAu, 0xFBu, 0xFCu, 0xFDu, 0xFEu, 0xFFu // +}; +#endif /* ---- - * crc_calc() + * crc_calc * ---- - * 24-bit crc + * the crc32 calculation as used in ethernet, pkzip, etc. */ unsigned int -crc_calc(unsigned char *data, int len) +crc_calc(const unsigned char *data, int len) { - unsigned int crc = 0; - int i; + unsigned int crc = 0xFFFFFFFFu; + + while (len--) + crc = crc32_table[((crc ^ *data++) & 0xFFu)] ^ (crc >> 8); - for (i = 0; i < len; i++) - crc = (crc << 8) ^ crc_table[(unsigned char)(crc >> 16) ^ *data++]; + // All Done, return result. - /* ok */ - return (crc & 0xFFFFFF); + return (crc ^ 0xFFFFFFFFu); } + +/* ---- + * filename_crc + * ---- + * characters 0x00-0x7F = ASCII (incorporated in the Unicode standard). + * characters 0x80-0xFF = unchanged + * + * this also remaps the DOS path separator "\" to the UNIX "/". + */ + +unsigned int +filename_crc(const char *name) +{ + const unsigned char *data = (const unsigned char *)name; + unsigned int crc = 0xFFFFFFFFu; + unsigned char byte; + +#if defined(_WIN32) || defined(__APPLE__) + while ((byte = *data++) != 0) + crc = crc32_table[((crc ^ ((unsigned int)ascii_lower_case[byte])) & 0xFFu)] ^ (crc >> 8); +#else + while ((byte = *data++) != 0) + crc = crc32_table[((crc ^ ((unsigned int)byte)) & 0xFFu)] ^ (crc >> 8); +#endif + + return (crc); // (crc ^ 0xFFFFFFFFu); +} diff --git a/src/mkit/as/defs.h b/src/mkit/as/defs.h index b6340965..e2353d4e 100644 --- a/src/mkit/as/defs.h +++ b/src/mkit/as/defs.h @@ -7,8 +7,11 @@ #define PCE_ASM_VERSION ("PC Engine Assembler (" GIT_VERSION ", " GIT_DATE ")") #define FUJI_ASM_VERSION ("Fuji Assembler for Atari (" GIT_VERSION ", " GIT_DATE ")") +/* send errors and warnings to either stdout or stderr */ +#define ERROUT stdout + /* path separator */ -#if defined(WIN32) +#if defined(_WIN32) #define PATH_SEPARATOR '\\' #define PATH_SEPARATOR_STRING "\\" #else @@ -21,20 +24,38 @@ #define MACHINE_NES 1 #define MACHINE_FUJI 2 +/* maximum user rom size */ +#define ROM_BANKS 1024 + /* reserved bank index */ -#define RESERVED_BANK 0xF0 -#define PROC_BANK 0xF1 -#define GROUP_BANK 0xF2 -#define STRIPPED_BANK 0xF3 +#define UNDEFINED_BANK (ROM_BANKS + 0) +#define PROC_BANK (ROM_BANKS + 1) +#define GROUP_BANK (ROM_BANKS + 2) +#define STRIPPED_BANK (ROM_BANKS + 3) + +/* number of reserved banks used beyond ROM_BANKS */ +#define RESERVED_BANKS 4 + +/* total number of banks to allocate for workspace */ +#define MAX_BANKS (ROM_BANKS + RESERVED_BANKS) /* tile format for encoder */ #define CHUNKY_TILE 1 #define PACKED_TILE 2 +/* max nesting of include files */ +#define MAX_NESTING 31 + /* line buffer length */ -#define LAST_CH_POS 512 -#define SFIELD 29 -#define SBOLSZ 64 +#define LAST_CH_POS (32768 - 4) +#define SFIELD 30 + +/* symbol name size, including length byte and '\0' */ +/* must be <= 129 if "char" is signed */ +#define SBOLSZ 128 + +/* file name size, including the '\0' */ +#define PATHSZ 260 /* macro argument types */ #define NO_ARG 0 @@ -46,11 +67,29 @@ #define ARG_LABEL 6 /* section types */ -#define S_ZP 0 -#define S_BSS 1 -#define S_CODE 2 -#define S_DATA 3 -#define S_PROC 4 /* trampolines for .proc */ +/* update pseudo_allowed when adding or changing! */ +/* update section_name when adding or changing! */ +/* update section_flags when adding or changing! */ +/* update section_limit when adding or changing! */ +#define S_NONE 0 /* SDCC: sections that should always be empty! */ +#define S_ZP 1 +#define S_BSS 2 +#define S_CODE 3 +#define S_DATA 4 +#define S_HOME 5 /* SDCC: permanently-mapped code */ +#define S_XDATA 6 /* SDCC: BSS copy of initialized variables */ +#define S_XINIT 7 /* SDCC: ROM copy of initialized variables */ +#define S_CONST 8 /* SDCC: permanent const data */ +#define S_OSEG 9 /* SDCC: overlayed variables in ZP */ +#define MAX_S 10 /* selectable section types */ +#define S_PROC 10 /* info only, thunks for .proc */ + +/* section flag mask */ +#define S_IS_RAM 1 +#define S_IS_ROM 2 +#define S_IS_SF2 4 +#define S_IS_CODE 8 +#define S_NO_DATA 16 /* assembler options */ #define OPT_LIST 0 @@ -62,8 +101,11 @@ #define OPT_ZPDETECT 6 #define OPT_LBRANCH 7 #define OPT_DATAPAGE 8 +#define OPT_FORWARD 9 +#define MAX_OPTS 10 /* assembler directives */ +/* update pseudo_allowed when adding or changing! */ #define P_DB 0 // .db #define P_DW 1 // .dw #define P_DD 2 // .dd @@ -122,13 +164,17 @@ #define P_INCTILEPAL 55 // .inctilepal #define P_CARTRIDGE 56 // .cartridge #define P_ALIGN 57 // .align -#define P_KICKC 58 // .kickc -#define P_CPU 59 // .cpu -#define P_SEGMENT 60 // .segment -#define P_LABEL 61 // .label or .const +#define P_KICKC 58 // .kickc .r6502 .r65c02 +#define P_IGNORE 59 // .cpu .optsdcc .globl +#define P_SEGMENT 60 // .segment .area +#define P_LABEL 61 // .label .const #define P_ENCODING 62 // .encoding #define P_STRUCT 63 // .struct #define P_ENDS 64 // .ends +#define P_3PASS 65 // .3pass +#define P_ALIAS 66 // .alias +#define P_REF 67 // .ref +#define P_PHASE 68 // .phase /* symbol flags */ #define UNDEF 1 /* undefined - may be zero page */ @@ -137,6 +183,7 @@ #define DEFABS 4 /* defined - two byte address */ #define MACRO 5 /* used for a macro name */ #define FUNC 6 /* used for a function */ +#define ALIAS 7 /* used for an alias */ /* symbol lookup flags */ #define SYM_CHK 0 /* does it exist? */ @@ -144,8 +191,9 @@ #define SYM_REF 2 /* symbol reference */ /* symbol definition source */ -#define CONSTANT 0 /* constant value */ -#define LOCATION 1 /* location (current PC) */ +#define LOCATION 0 /* location (current PC) */ +#define CONSTANT 1 /* constant value */ +#define VARIABLE 2 /* variable value */ /* operation code flags */ #define PSEUDO 0x0008000 @@ -172,11 +220,17 @@ #define ABS_IND 0x0000800 #define ABS_IND_X 0x0001000 -/* pass flags */ +/* pass type flags */ #define FIRST_PASS 0 -#define BRANCH_PASS 1 +#define EXTRA_PASS 1 #define LAST_PASS 2 +/* size of various hashing tables */ +#define HASH_COUNT 256 + +/* size of remembered filename strings */ +#define STR_POOL_SIZE 65536 + /* structs */ typedef struct t_opcode { struct t_opcode *next; @@ -187,12 +241,25 @@ typedef struct t_opcode { int type_idx; } t_opcode; -typedef struct t_input_info { +typedef struct t_str_pool { + struct t_str_pool *next; + int remain; + char buffer [STR_POOL_SIZE]; +} t_str_pool; + +typedef struct t_file { + struct t_file *next; + int number; + int included; + const char *name; +} t_file; + +typedef struct t_input { + struct t_file *file; FILE *fp; int lnum; int if_level; - char name[116]; -} t_input_info; +} t_input; typedef struct t_proc { struct t_proc *next; @@ -211,29 +278,38 @@ typedef struct t_proc { int type; int kickc; int defined; - char name[SBOLSZ]; + int is_skippable; } t_proc; +/* update pc_symbol when adding or changing! */ typedef struct t_symbol { struct t_symbol *next; struct t_symbol *local; struct t_symbol *scope; struct t_proc *proc; + const char *name; + struct t_file *fileinfo; + int fileline; + int reason; int type; int value; + int phase; int section; - int bank; + int overlay; + int mprbank; + int rombank; int page; int nb; int size; int vram; int pal; - int defcnt; - int refcnt; int reserved; int data_type; int data_size; - char name[SBOLSZ]; + int deflastpass; + int reflastpass; + int defthispass; + int refthispass; } t_symbol; typedef struct t_branch { @@ -246,19 +322,19 @@ typedef struct t_branch { typedef struct t_line { struct t_line *next; - char *data; + const char *line; } t_line; typedef struct t_macro { struct t_macro *next; + struct t_symbol *label; struct t_line *line; - char name[SBOLSZ]; } t_macro; typedef struct t_func { struct t_func *next; - char line[128]; - char name[SBOLSZ]; + struct t_symbol *label; + char *line; } t_func; typedef struct t_tile { @@ -287,6 +363,6 @@ typedef struct t_machine { int (*pack_16x16_tile)(unsigned char *, void *, int, int); int (*pack_16x16_sprite)(unsigned char *, void *, int, int); void (*write_header)(FILE *, int); -} MACHINE; +} t_machine; #endif // DEFS_H diff --git a/src/mkit/as/expr.c b/src/mkit/as/expr.c index 28cf0f18..33320f25 100644 --- a/src/mkit/as/expr.c +++ b/src/mkit/as/expr.c @@ -15,40 +15,47 @@ static char allow_numeric_bank = 0; */ t_symbol pc_symbol = { - NULL, /* next */ - NULL, /* local */ - NULL, /* scope */ - NULL, /* proc */ - DEFABS, /* type */ - 0, /* value */ - 0, /* section */ - 0, /* bank */ - 0, /* page */ - 0, /* nb */ - 0, /* size */ - 0, /* vram */ - 0, /* pal */ - 1, /* defcnt */ - 1, /* refcnt */ - 1, /* reserved */ - 0, /* data_type */ - 0, /* data_size */ - "*" /* name */ + NULL, /* next */ + NULL, /* local */ + NULL, /* scope */ + NULL, /* proc */ + "\1*", /* name */ + NULL, /* fileinfo */ + 0, /* fileline */ + CONSTANT, /* reason */ + DEFABS, /* type */ + 0, /* value */ + 0, /* phase */ + S_NONE, /* section */ + 0, /* overlay */ + 0, /* mprbank */ + UNDEFINED_BANK, /* bank */ + 0, /* page */ + 0, /* nb */ + 0, /* size */ + 0, /* vram */ + 0, /* pal */ + 1, /* reserved */ + 0, /* data_type */ + 0, /* data_size */ + 1, /* deflastpass */ + 1, /* reflastpass */ + 1, /* defthispass */ + 1 /* refthispass */ }; /* ---- - * is_expr_symbol() + * is_nameless_ref() * ---- - * is the next string a symbol? + * is the next string a reference to a "multi-label" symbol? * this is complicated because a "multi-label" looks like a "not" or a "not-equal". */ -inline int is_expr_symbol (char * pstr) +static inline int is_multi_label_ref (const char * pstr) { unsigned char c = *pstr++; - if (isalpha(c) || c == '_' || c == '.' || c == '@') - return 1; + if (c != '!') return 0; for (;;) { @@ -76,7 +83,7 @@ evaluate(int *ip, char last_char, char allow_bank) int end, level; int op, type; int arg; - int i; + int skip; unsigned char c; end = 0; @@ -91,7 +98,8 @@ evaluate(int *ip, char last_char, char allow_bank) expr_toplabl = NULL; expr_lablptr = NULL; expr_lablcnt = 0; - expr_valbank = RESERVED_BANK; + expr_mprbank = UNDEFINED_BANK; + expr_overlay = 0; complex_expr = 0; op = OP_START; func_idx = 0; @@ -109,7 +117,7 @@ evaluate(int *ip, char last_char, char allow_bank) /* search for a continuation char */ if (*expr == '\\') { /* skip spaces */ - i = 1; + int i = 1; while (isspace(expr[i])) i++; @@ -145,14 +153,21 @@ evaluate(int *ip, char last_char, char allow_bank) if (isdigit(c)) { if (need_operator) goto error; - if (!push_val(T_DECIMAL)) - return (0); + + /* is this an SDCC local-symbol rather than a number? */ + if (sdcc_mode && (expr[5] == '$') && isdigit(expr[4]) && + isdigit(expr[3]) && isdigit(expr[2]) && isdigit(expr[1])) { + if (!push_val(T_SYMBOL)) + return (0); + } else { + if (!push_val(T_DECIMAL)) + return (0); + } } /* symbol */ else -// if (isalpha(c) || c == '_' || c == '.' || c == '@') { - if (is_expr_symbol(expr)) { + if (isalpha(c) || c == '_' || c == '.' || c == '@' || is_multi_label_ref(expr)) { if (need_operator) goto error; if (!push_val(T_SYMBOL)) @@ -245,7 +260,7 @@ evaluate(int *ip, char last_char, char allow_bank) break; default: if (!need_operator) - op = OP_dotLO; + op = OP_LOW_SYMBOL; else op = OP_LOWER; expr++; @@ -272,7 +287,7 @@ evaluate(int *ip, char last_char, char allow_bank) break; default: if (!need_operator) - op = OP_dotHI; + op = OP_HIGH_SYMBOL; else op = OP_HIGHER; expr++; @@ -352,24 +367,37 @@ evaluate(int *ip, char last_char, char allow_bank) break; } - /* modulo, mul, add, div, and, xor, or */ + /* modulo, mul, add, div, and, or */ case '+': case '/': case '&': case '|': if (!need_operator) goto error; + skip = 1; switch (c) { case '%': op = OP_MOD; break; case '*': op = OP_MUL; break; case '+': op = OP_ADD; break; case '/': op = OP_DIV; break; - case '&': op = OP_AND; break; - case '|': op = OP_OR; break; + case '&': + op = OP_AND; + if (expr[1] == '&') { + op = OP_LOGICAL_AND; + skip = 2; + } + break; + case '|': + op = OP_OR; + if (expr[1] == '|') { + op = OP_LOGICAL_OR; + skip = 2; + } + break; } if (!push_op(op)) return (0); - expr++; + expr += skip; break; /* skip immediate operand prefix if in macro */ @@ -441,7 +469,7 @@ evaluate(int *ip, char last_char, char allow_bank) } /* convert back the pointer to an array index */ - *ip = expr - prlnbuf; + *ip = (int)(expr - prlnbuf); /* ok */ return (1); @@ -462,9 +490,9 @@ evaluate(int *ip, char last_char, char allow_bank) int push_val(int type) { - unsigned int mul, val; + unsigned int val; int op; - char c; + char c, mul; char *symexpr; val = 0; @@ -581,32 +609,26 @@ push_val(int type) symbol[2] = '\0'; expr++; + pc_symbol.fileinfo = input_file[infile_num].file; + pc_symbol.fileline = slnum; + /* complicated because loccnt & data_loccnt can be >= $2000 */ if (data_loccnt == -1) pc_symbol.value = loccnt; else pc_symbol.value = data_loccnt; - pc_symbol.page = page; - - if (bank >= RESERVED_BANK) - pc_symbol.bank = bank; - else - pc_symbol.bank = bank + bank_base; + pc_symbol.rombank = bank + (pc_symbol.value >> 13); + pc_symbol.mprbank = bank2mprbank(pc_symbol.rombank, section); + pc_symbol.overlay = bank2overlay(pc_symbol.rombank, section); + pc_symbol.section = section; - if (pc_symbol.value >= 0x2000) { - pc_symbol.bank = (pc_symbol.bank + 1); - pc_symbol.page = (pc_symbol.page + 1) & 7; - } + pc_symbol.page = page; - pc_symbol.value += (page << 13); + pc_symbol.value = (pc_symbol.value + (page << 13) + phase_offset) & 0xFFFF; - /* KickC can't call bank(), so put it in the label */ - if (kickc_mode) { - pc_symbol.value += pc_symbol.bank << 23; - } - - expr_valbank = pc_symbol.bank; + expr_mprbank = pc_symbol.mprbank; + expr_overlay = pc_symbol.overlay; expr_toplabl = expr_lablptr = &pc_symbol; @@ -630,7 +652,7 @@ push_val(int type) } /* a predefined function? */ - op = check_keyword(); + op = check_keyword(symbol); if (op) { if (!push_op(op)) return (0); @@ -638,7 +660,18 @@ push_val(int type) return (1); } - c = *symexpr; + /* a predefined function as a prefix? */ + if (sdcc_mode || kickc_mode) + { + op = check_prefix(symbol); + if (op) { + if (!push_op(op)) + return (0); + // process the symbol + } + } + + c = symbol[1]; if ((scopeptr != NULL) && (c != '.') && (c != '@') && (c != '!')) { struct t_symbol * curscope = scopeptr; for (;;) { @@ -677,15 +710,29 @@ push_val(int type) undef++; else if (expr_lablptr->type == IFUNDEF) undef++; - else if ((expr_lablptr->bank == STRIPPED_BANK) && + else if ((expr_lablptr->mprbank == STRIPPED_BANK) && ((proc_ptr == NULL) || (proc_ptr->bank != STRIPPED_BANK))) { error("Symbol from an unused procedure that was stripped out!"); undef++; } else { - expr_valbank = expr_lablptr->bank; - val = expr_lablptr->value; - if (expr_lablptr->defcnt == 0) { + /* resolve newproc procedure labels to their thunk location in the last pass */ + struct t_proc *proc; + + if ((pass == LAST_PASS) && (newproc_opt != 0) && + ((proc = expr_lablptr->proc) != NULL) && (proc->label == expr_lablptr)) { + if (!proc->call) + add_thunk(proc); + expr_overlay = 0; + expr_mprbank = bank2mprbank(call_bank, S_CODE); + val = proc->call; + } else { + expr_overlay = expr_lablptr->overlay; + expr_mprbank = expr_lablptr->mprbank; + val = expr_lablptr->value; + } + + if (expr_lablptr->defthispass == 0) { notyetdef++; } } @@ -740,7 +787,31 @@ push_val(int type) val = (val * mul) + c; } if (c == ':' && mul == 16 && allow_numeric_bank) { - expr_valbank = val; + if (expr_mprbank != UNDEFINED_BANK) { + if (expr_overlay != 0) { + error("Overlay number already set in this expression!"); + return (0); + } + if ((expr_mprbank < 1) || (expr_mprbank > 15)) { + error("Overlay number must be in the range $1..$F!"); + return (0); + } + if ((val < 0x40) || (val > 0x7F)) { + error("Overlay bank number must be in the range $40..$7F!"); + return (0); + } + expr_overlay = expr_mprbank; + expr_mprbank = UNDEFINED_BANK; + } + if (expr_mprbank != UNDEFINED_BANK) { + error("Bank number already set in this expression!"); + return (0); + } + if ((val < 0x00) || (val > 0xFF)) { + error("Bank number must be in the range $00..$FF!"); + return (0); + } + expr_mprbank = val; return push_val(T_HEXA); } break; @@ -775,10 +846,20 @@ getsym(struct t_symbol * curscope) { int i = 0; int j; - char c; + char c = *expr; + + /* convert an SDCC local-symbol into a PCEAS local-symbol */ + if (sdcc_mode && isdigit(c)) { + /* this was already parsed and verified in evaluate() */ + symbol[0] = 6; + symbol[1] = '@'; + memcpy(&symbol[2], expr, 5); + symbol[7] = '\0'; + expr += 6; + return (6); + } /* prepend the current scope? */ - c = *expr; if ((curscope != NULL) && (c != '.') && (c != '@') && (c != '!')) { i = addscope(curscope, i); } @@ -846,7 +927,7 @@ getsym(struct t_symbol * curscope) if (whichlabl < 0) { ++whichlabl; } /* add the current multi-label instance */ - whichlabl += baselabl->defcnt; + whichlabl += baselabl->defthispass; if ((whichlabl < 0) || (whichlabl > 0x7FFFF)) { /* illegal value */ whichlabl = 0; @@ -855,13 +936,11 @@ getsym(struct t_symbol * curscope) /* create the target multi-label name */ sprintf(tail, "!%d", 0x7FFFF & whichlabl); strncat(symbol, tail, SBOLSZ - 1 - strlen(symbol)); - i = symbol[0] = strlen(&symbol[1]); + i = symbol[0] = (char)strlen(&symbol[1]); } if (i >= SBOLSZ - 1) { - char errorstr[512]; - snprintf(errorstr, 512, "Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); - fatal_error(errorstr); + fatal_error("Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); return (0); } @@ -876,31 +955,33 @@ getsym(struct t_symbol * curscope) */ int -check_keyword(void) +check_keyword(char * name) { int op = 0; /* check if its an assembler function */ - if (symbol[0] == keyword[0][0] && !strcasecmp(symbol, keyword[0])) + if (name[0] == keyword[0][0] && !strcasecmp(name, keyword[0])) op = OP_DEFINED; - else if (symbol[0] == keyword[1][0] && !strcasecmp(symbol, keyword[1])) - op = OP_HIGH; - else if (symbol[0] == keyword[2][0] && !strcasecmp(symbol, keyword[2])) - op = OP_LOW; - else if (symbol[0] == keyword[3][0] && !strcasecmp(symbol, keyword[3])) + else if (name[0] == keyword[1][0] && !strcasecmp(name, keyword[1])) + op = OP_HIGH_KEYWORD; + else if (name[0] == keyword[2][0] && !strcasecmp(name, keyword[2])) + op = OP_LOW_KEYWORD; + else if (name[0] == keyword[3][0] && !strcasecmp(name, keyword[3])) op = OP_PAGE; - else if (symbol[0] == keyword[4][0] && !strcasecmp(symbol, keyword[4])) + else if (name[0] == keyword[4][0] && !strcasecmp(name, keyword[4])) op = OP_BANK; - else if (symbol[0] == keyword[7][0] && !strcasecmp(symbol, keyword[7])) + else if (name[0] == keyword[7][0] && !strcasecmp(name, keyword[7])) op = OP_SIZEOF; - else if (symbol[0] == keyword[8][0] && !strcasecmp(symbol, keyword[8])) + else if (name[0] == keyword[8][0] && !strcasecmp(name, keyword[8])) op = OP_LINEAR; + else if (name[0] == keyword[9][0] && !strcasecmp(name, keyword[9])) + op = OP_OVERLAY; else { if (machine->type == MACHINE_PCE) { /* PCE specific functions */ - if (symbol[0] == keyword[5][0] && !strcasecmp(symbol, keyword[5])) + if (name[0] == keyword[5][0] && !strcasecmp(name, keyword[5])) op = OP_VRAM; - else if (symbol[0] == keyword[6][0] && !strcasecmp(symbol, keyword[6])) + else if (name[0] == keyword[6][0] && !strcasecmp(name, keyword[6])) op = OP_PAL; } } @@ -908,14 +989,15 @@ check_keyword(void) /* extra setup for functions that send back symbol infos */ switch (op) { case OP_DEFINED: - case OP_HIGH: - case OP_LOW: + case OP_HIGH_KEYWORD: + case OP_LOW_KEYWORD: case OP_PAGE: case OP_BANK: - case OP_VRAM: - case OP_PAL: case OP_SIZEOF: case OP_LINEAR: + case OP_OVERLAY: + case OP_VRAM: + case OP_PAL: expr_lablptr = NULL; expr_lablcnt = 0; break; @@ -926,6 +1008,57 @@ check_keyword(void) } +/* ---- + * check_prefix() + * ---- + * verify if the current symbol has a reserved function name as a prefix + * like "___bank_" or "___page_", which is a hack that C code can employ + * to access the functions. + */ + +int +check_prefix(char * name) +{ + char prefix[SBOLSZ]; + char c; + int op; + int prefix_end; + + /* is this a compiler-reserved C symbol ? */ + if ((name[0] < 4) || (name[3] != '_') || (name[1] != '_') || (name[2] != '_')) + return 0; + + /* find the next '_' after the prefix keyword */ + /* offset: 0123456789AB */ + /* symbol: A___bank_xx0 */ + /* prefix: 4bank0 */ + prefix_end = 3; + do { + ++prefix_end; + c = prefix[prefix_end-3] = name[prefix_end]; + } while ((c != '_') && (c != '\0')); + + /* return if no prefix keyword, or if there is no symbol afterwards */ + if (prefix_end >= name[0]) + return 0; + + /* set up the prefix for checking */ + prefix[0] = prefix_end - 4; + prefix[prefix_end - 3] = '\0'; + + op = check_keyword(prefix); + + /* if it was a keyword, then remove the prefix from the symbol */ + if (op != 0) { + int i = 0; + while ((name[++i] = name[++prefix_end]) != '\0'); + name[0] = i - 1; + } + + return (op); +} + + /* ---- * push_op() * ---- @@ -983,33 +1116,39 @@ do_op(void) case OP_LINEAR: if (!check_func_args("LINEAR")) return (0); - if (pass == LAST_PASS) { - if (expr_lablptr->bank >= RESERVED_BANK) { - error("No LINEAR index for this symbol!"); - val[0] = 0; - break; - } + if (((expr_lablptr->mprbank < UNDEFINED_BANK) && ((section_flags[expr_lablptr->section] & S_IS_ROM) == 0)) || + ((expr_lablptr->mprbank == UNDEFINED_BANK) && (pass == LAST_PASS))) { + error("No LINEAR() index for this symbol!"); + val[0] = 0; + break; } + exbank = 0; /* complicated math to deal with LINEAR(label+value) */ - exbank = (expr_lablptr->bank + (val[0] / 8192) - (expr_lablptr->value / 8192)); - if (expr_lablptr->bank < RESERVED_BANK) - exbank -= bank_base; + if (expr_lablptr->mprbank < UNDEFINED_BANK) { + exbank = (expr_lablptr->rombank + (val[0] / 8192) - (expr_lablptr->value / 8192)); + } val[0] = (exbank << 13) + (val[0] & 0x1FFF); break; + /* OVERLAY */ + case OP_OVERLAY: + if (!check_func_args("OVERLAY")) + return (0); + val[0] = expr_lablptr->overlay; + break; + /* BANK */ case OP_BANK: if (!check_func_args("BANK")) return (0); - if (pass == LAST_PASS) { - if (expr_lablptr->bank == RESERVED_BANK) { - error("No BANK index for this symbol!"); - val[0] = 0; - break; - } + if (expr_lablptr->mprbank >= UNDEFINED_BANK) { + if ((pass == LAST_PASS) && (expr_lablptr->mprbank == UNDEFINED_BANK)) + error("No BANK() number for this symbol!"); + val[0] = 0; + break; } /* complicated math to deal with BANK(label+value) */ - val[0] = (expr_lablptr->bank + (val[0] / 8192) - (expr_lablptr->value / 8192)); + val[0] = (expr_lablptr->mprbank + (val[0] / 8192) - (expr_lablptr->value / 8192)); break; /* PAGE */ @@ -1026,7 +1165,7 @@ do_op(void) return (0); if (pass == LAST_PASS) { if (expr_lablptr->vram == -1) - error("No VRAM address for this symbol!"); + error("No VRAM() address for this symbol!"); } val[0] = expr_lablptr->vram; break; @@ -1037,7 +1176,7 @@ do_op(void) return (0); if (pass == LAST_PASS) { if (expr_lablptr->pal == -1) - error("No palette index for this symbol!"); + error("No PAL() index for this symbol!"); } val[0] = expr_lablptr->pal; break; @@ -1046,6 +1185,7 @@ do_op(void) case OP_DEFINED: if (!check_func_args("DEFINED")) return (0); + if ((expr_lablptr->type != IFUNDEF) && (expr_lablptr->type != UNDEF)) val[0] = 1; else { @@ -1060,7 +1200,7 @@ do_op(void) return (0); if (pass == LAST_PASS) { if (expr_lablptr->data_type == -1) { - error("No size attributes for this symbol!"); + error("No SIZEOF() attribute for this symbol!"); return (0); } } @@ -1068,14 +1208,14 @@ do_op(void) break; /* HIGH */ - case OP_dotHI: - case OP_HIGH: + case OP_HIGH_SYMBOL: + case OP_HIGH_KEYWORD: val[0] = (val[0] & 0xFF00) >> 8; break; /* LOW */ - case OP_dotLO: - case OP_LOW: + case OP_LOW_SYMBOL: + case OP_LOW_KEYWORD: val[0] = val[0] & 0xFF; break; @@ -1163,6 +1303,14 @@ do_op(void) val[0] = (val[1] >= val[0]); break; + case OP_LOGICAL_OR: + val[0] = ((val[1] != 0) || (val[0] != 0)); + break; + + case OP_LOGICAL_AND: + val[0] = ((val[1] != 0) && (val[0] != 0)); + break; + default: error("Invalid operator in expression!"); return (0); @@ -1177,23 +1325,19 @@ do_op(void) /* ---- * check_func_args() * ---- - * check BANK/PAGE/VRAM/PAL function arguments + * check OVERLAY/LINEAR/BANK/PAGE/VRAM/PAL function arguments */ int check_func_args(char *func_name) { - char string[64]; - if (expr_lablcnt == 1) return (1); else if (expr_lablcnt == 0) - sprintf(string, "No symbol in function %s!", func_name); + error("No symbol in function %s!", func_name); else { - sprintf(string, "Too many symbols in function %s!", func_name); + error("Too many symbols in function %s!", func_name); } - /* output message */ - error(string); return (0); } diff --git a/src/mkit/as/expr.h b/src/mkit/as/expr.h index 9a2d438e..ae21e744 100644 --- a/src/mkit/as/expr.h +++ b/src/mkit/as/expr.h @@ -28,64 +28,122 @@ #define OP_HIGHER 19 #define OP_HIGHER_EQUAL 20 #define OP_DEFINED 21 -#define OP_HIGH 22 -#define OP_LOW 23 +#define OP_HIGH_KEYWORD 22 +#define OP_LOW_KEYWORD 23 #define OP_PAGE 24 #define OP_BANK 25 #define OP_VRAM 26 #define OP_PAL 27 #define OP_SIZEOF 28 #define OP_LINEAR 29 -#define OP_dotLO 30 -#define OP_dotHI 31 +#define OP_OVERLAY 30 +#define OP_LOW_SYMBOL 31 +#define OP_HIGH_SYMBOL 32 +#define OP_LOGICAL_OR 33 +#define OP_LOGICAL_AND 34 -/* operator priority */ +/* operator priority (bigger number is higher precedence) */ +/* precedence is left-to-right if same priority */ const int op_pri[] = { - 0 /* START */, 0 /* OPEN */, - 8 /* ADD */, 8 /* SUB */, 9 /* MUL */, 9 /* DIV */, - 9 /* MOD */, 11 /* NEG */, 7 /* SHL */, 7 /* SHR */, - 1 /* OR */, 2 /* XOR */, 3 /* AND */, 11 /* COM */, - 10 /* NOT */, 4 /* == */, 4 /* <> */, 5 /* < */, - 5 /* <= */, 5 /* > */, 5 /* >= */, - 11 /* DEFIN.*/, 11 /* HIGH */, 11 /* LOW */, 11 /* PAGE */, - 11 /* BANK */, 11 /* VRAM */, 11 /* PAL */, 11 /* SIZEOF*/, - 11 /* LINEAR*/, 6 /* dotLO */, 6 /* dotHI */ + 0 /* OP_START */, + 0 /* OP_OPEN */, + 10 /* OP_ADD */, + 10 /* OP_SUB */, + 11 /* OP_MUL */, + 11 /* OP_DIV */, + 11 /* OP_MOD */, + 13 /* OP_NEG */, + 9 /* OP_SHL */, + 9 /* OP_SHR */, + 3 /* OP_OR */, + 4 /* OP_XOR */, + 5 /* OP_AND */, + 13 /* OP_COM */, + 12 /* OP_NOT */, + 6 /* OP_EQUAL */, + 6 /* OP_NOT_EQUAL */, + 7 /* OP_LOWER */, + 7 /* OP_LOWER_EQUAL */, + 7 /* OP_HIGHER */, + 7 /* OP_HIGHER_EQUAL */, + 13 /* OP_DEFINED */, + 13 /* OP_HIGH_KEYWORD */, + 13 /* OP_LOW_KEYWORD */, + 13 /* OP_PAGE */, + 13 /* OP_BANK */, + 13 /* OP_VRAM */, + 13 /* OP_PAL */, + 13 /* OP_SIZEOF */, + 13 /* OP_LINEAR */, + 13 /* OP_TAGOF */, + 8 /* OP_LOW_SYMBOL */, + 8 /* OP_HIGH_SYMBOL */, + 1 /* OP_LOGICAL_OR */, + 2 /* OP_LOGICAL_AND */ }; /* second argument */ const int op_2nd[] = { - 0 /* START */, 0 /* OPEN */, - 1 /* ADD */, 1 /* SUB */, 1 /* MUL */, 1 /* DIV */, - 1 /* MOD */, 0 /* NEG */, 1 /* SHL */, 1 /* SHR */, - 1 /* OR */, 1 /* XOR */, 1 /* AND */, 0 /* COM */, - 0 /* NOT */, 1 /* == */, 1 /* <> */, 1 /* < */, - 1 /* <= */, 1 /* > */, 1 /* >= */, - 0 /* DEFIN.*/, 0 /* HIGH */, 0 /* LOW */, 0 /* PAGE */, - 0 /* BANK */, 0 /* VRAM */, 0 /* PAL */, 0 /* SIZEOF*/, - 0 /* LINEAR*/, 0 /* dotLO */, 0 /* dotHI */ + 0 /* OP_START */, + 0 /* OP_OPEN */, + 1 /* OP_ADD */, + 1 /* OP_SUB */, + 1 /* OP_MUL */, + 1 /* OP_DIV */, + 1 /* OP_MOD */, + 0 /* OP_NEG */, + 1 /* OP_SHL */, + 1 /* OP_SHR */, + 1 /* OP_OR */, + 1 /* OP_XOR */, + 1 /* OP_AND */, + 0 /* OP_COM */, + 0 /* OP_NOT */, + 1 /* OP_EQUAL */, + 1 /* OP_NOT_EQUAL */, + 1 /* OP_LOWER */, + 1 /* OP_LOWER_EQUAL */, + 1 /* OP_HIGHER */, + 1 /* OP_HIGHER_EQUAL */, + 0 /* OP_DEFINED */, + 0 /* OP_HIGH_KEYWORD */, + 0 /* OP_LOW_KEYWORD */, + 0 /* OP_PAGE */, + 0 /* OP_BANK */, + 0 /* OP_VRAM */, + 0 /* OP_PAL */, + 0 /* OP_SIZEOF */, + 0 /* OP_LINEAR */, + 0 /* OP_OVERLAY */, + 0 /* OP_LOW_SYMBOL */, + 0 /* OP_HIGH_SYMBOL */, + 1 /* OP_LOGICAL_OR */, + 1 /* OP_LOGICAL_AND */ }; unsigned int op_stack[64] = { - OP_START -}; /* operator stack */ -unsigned int val_stack[64]; /* value stack */ -int op_idx, val_idx; /* index in the operator and value stacks */ -int need_operator; /* when set await an operator, else await a value */ -char *expr; /* pointer to the expression string */ -char *expr_stack[16]; /* expression stack */ -struct t_symbol *expr_toplabl; /* pointer to the innermost scope-label */ -struct t_symbol *expr_lablptr; /* pointer to the last-referenced label */ -int expr_lablcnt; /* number of label seen in an expression */ -int expr_valbank; /* last-defined bank# in an expression */ -int complex_expr; /* NZ if an expression contains operators */ -const char *keyword[9] = { /* predefined functions */ - "\7DEFINED", - "\4HIGH", - "\3LOW", - "\4PAGE", - "\4BANK", - "\4VRAM", - "\3PAL", - "\6SIZEOF", - "\6LINEAR" + OP_START +}; /* operator stack */ +unsigned int val_stack[64]; /* value stack */ +int op_idx, val_idx; /* index in the operator and value stacks */ +int need_operator; /* when set await an operator, else await a value */ +char *expr; /* pointer to the expression string */ +char *expr_stack[16]; /* expression stack */ +struct t_symbol *expr_toplabl; /* pointer to the innermost scope-label */ +struct t_symbol *expr_lablptr; /* pointer to the last-referenced label */ +int expr_lablcnt; /* number of label seen in an expression */ +int expr_mprbank; /* last-defined bank# in an expression */ +int expr_overlay; /* last-defined overlay# in an expression */ +int complex_expr; /* NZ if an expression contains operators */ +const char *keyword[10] = { /* predefined functions */ + "\7DEFINED", + "\4HIGH", + "\3LOW", + "\4PAGE", + "\4BANK", + "\4VRAM", + "\3PAL", + "\6SIZEOF", + "\6LINEAR", + "\7OVERLAY" }; diff --git a/src/mkit/as/externs.h b/src/mkit/as/externs.h index acdd0ac1..9c587ac1 100644 --- a/src/mkit/as/externs.h +++ b/src/mkit/as/externs.h @@ -1,44 +1,51 @@ -extern unsigned char rom[128][8192]; -extern unsigned char map[128][8192]; -extern char bank_name[128][64]; -extern int bank_loccnt[4][256]; -extern int bank_page[4][256]; -extern int bank_maxloc[256]; /* record max location in bank */ -extern int discontiguous; /* NZ signals a warp in loccnt */ -extern int max_zp; /* higher used address in zero page */ -extern int max_bss; /* higher used address in ram */ -extern int max_bank; /* last bank used */ -extern int data_loccnt; /* data location counter */ -extern int data_size; /* size of binary output (in bytes) */ -extern int data_level; /* data output level, must be <= listlevel to be outputed */ -extern int loccnt; /* location counter */ -extern int bank; /* current bank */ -extern int bank_base; /* bank base index */ -extern int bank_limit; /* bank limit */ -extern int rom_limit; /* rom max. size in bytes */ -extern int page; /* page */ -extern int rsbase; /* .rs counter */ -extern int rsbank; /* .rs counter */ -extern int section; /* current section: S_ZP, S_BSS, S_CODE or S_DATA */ -extern int section_bank[4]; /* current bank for each section */ -extern int in_if; /* true if in a '.if' statement */ -extern int if_expr; /* set when parsing an .if expression */ -extern int if_level; /* level of nested .if's */ -extern int if_line[256]; /* .if line number */ -extern int skip_lines; /* when true skip lines */ -extern int continued_line; /* set when a line is the continuation of another line */ -extern int pcx_w, pcx_h; /* PCX dimensions */ -extern int pcx_nb_colors; /* number of colors (16/256) in the PCX */ -extern int pcx_nb_args; /* number of argument */ -extern unsigned int pcx_arg[8]; /* PCX args array */ -extern unsigned char *pcx_buf; /* pointer to the PCX buffer */ -extern unsigned char pcx_pal[256][3]; /* palette */ -extern char *expr; /* expression string pointer */ -extern struct t_symbol *expr_toplabl; /* pointer to the innermost scope-label */ -extern struct t_symbol *expr_lablptr; /* pointer to the last-referenced label */ -extern int expr_lablcnt; /* number of label seen in an expression */ -extern int expr_valbank; /* last-defined bank# in an expression */ -extern int complex_expr; /* NZ if an expression contains operators */ +extern unsigned char rom[MAX_BANKS][8192]; +extern unsigned char map[MAX_BANKS][8192]; +extern char bank_name[MAX_BANKS][64]; +extern int bank_loccnt[MAX_S][MAX_BANKS]; +extern int bank_page[MAX_S][MAX_BANKS]; +extern int bank_maxloc[MAX_BANKS]; /* record max location in bank */ + +extern int discontiguous; /* NZ signals a warp in loccnt */ +extern int max_zp; /* higher used address in zero page */ +extern int max_bss; /* higher used address in ram */ +extern int max_bank; /* last bank used */ +extern int data_loccnt; /* data location counter */ +extern int data_size; /* size of binary output (in bytes) */ +extern int data_level; /* data output level, must be <= listlevel to be outputed */ +extern int phase_offset; /* location counter offset for .phase */ +extern int loccnt; /* location counter */ +extern int bank; /* current bank */ +extern int bank_base; /* bank base index */ +extern int bank_limit; /* bank limit */ +extern int rom_limit; /* rom max. size in bytes */ +extern int page; /* page */ +extern int rs_base; /* .rs counter */ +extern int rs_mprbank; /* .rs counter */ +extern int rs_overlay; /* .rs counter */ +extern int section; /* current section: S_ZP, S_BSS, S_CODE or S_DATA */ +extern int section_bank[MAX_S]; /* current bank for each section */ +extern int section_phase[MAX_S]; /* current phase offset for each section */ +extern int section_flags[MAX_S]; /* current flags for each section */ +extern int section_limit[MAX_S]; /* current loccnt limit for each section */ +extern int in_if; /* true if in a '.if' statement */ +extern int if_expr; /* set when parsing an .if expression */ +extern int if_level; /* level of nested .if's */ +extern int if_line[256]; /* .if line number */ +extern int skip_lines; /* when true skip lines */ +extern int continued_line; /* set when a line is the continuation of another line */ +extern int pcx_w, pcx_h; /* PCX dimensions */ +extern int pcx_nb_colors; /* number of colors (16/256) in the PCX */ +extern int pcx_nb_args; /* number of argument */ +extern unsigned int pcx_arg[8]; /* PCX args array */ +extern unsigned char *pcx_buf; /* pointer to the PCX buffer */ +extern unsigned char pcx_pal[256][3]; /* palette */ +extern char *expr; /* expression string pointer */ +extern struct t_symbol *expr_toplabl; /* pointer to the innermost scope-label */ +extern struct t_symbol *expr_lablptr; /* pointer to the last-referenced label */ +extern int expr_lablcnt; /* number of label seen in an expression */ +extern int expr_mprbank; /* last-defined bank# in an expression */ +extern int expr_overlay; /* last-defined overlay# in an expression */ +extern int complex_expr; /* NZ if an expression contains operators */ extern int mopt; extern int in_macro; extern int expand_macro; @@ -46,64 +53,89 @@ extern char marg[8][10][256]; extern int midx; extern int mcounter, mcntmax; extern int mcntstack[8]; -extern struct t_line *mstack[8]; -extern struct t_line *mlptr; -extern struct t_macro *macro_tbl[256]; -extern struct t_macro *mptr; -extern struct t_func *func_tbl[256]; -extern struct t_func *func_ptr; -extern struct t_proc *proc_ptr; +extern t_line *mstack[8]; +extern t_line *mlptr; +extern t_macro *macro_tbl[HASH_COUNT]; +extern t_macro *mptr; +extern t_func *func_tbl[HASH_COUNT]; +extern t_func *func_ptr; +extern t_proc *proc_ptr; extern int proc_nb; extern char func_arg[8][10][80]; extern int func_idx; extern int infile_error; extern int infile_num; -extern FILE *out_fp; /* file pointers, output */ -extern FILE *in_fp; /* input */ -extern FILE *lst_fp; /* listing */ -extern struct t_input_info input_file[8]; -extern struct t_machine *machine; -extern struct t_machine nes; -extern struct t_machine pce; -extern struct t_machine fuji; -extern struct t_opcode *inst_tbl[256]; /* instructions hash table */ -extern struct t_symbol *hash_tbl[256]; /* label hash table */ -extern struct t_symbol *lablptr; /* label pointer into symbol table */ -extern struct t_symbol *glablptr; /* pointer to the latest defined global symbol */ -extern struct t_symbol *scopeptr; /* pointer to the latest defined scope label */ -extern struct t_symbol *lastlabl; /* last label we have seen */ -extern struct t_symbol *bank_glabl[4][256]; /* latest global label in each bank */ -extern struct t_branch *branchlst; /* first branch instruction assembled */ -extern struct t_branch *branchptr; /* last branch instruction assembled */ -extern int xvertlong; /* count of branches fixed in pass */ -extern char need_another_pass; /* NZ if another pass if required */ -extern char hex[]; /* hexadecimal character buffer */ -extern int stop_pass; /* stop the program; set by fatal_error() */ -extern int errcnt; /* error counter */ -extern void (*opproc)(int *); /* instruction gen proc */ -extern int opflg; /* instruction flags */ -extern int opval; /* instruction value */ -extern int optype; /* instruction type */ -extern char opext; /* instruction extension (.l or .h) */ -extern int pass; /* pass counter */ -extern char prlnbuf[]; /* input line buffer */ -extern char tmplnbuf[]; /* temporary line buffer */ -extern int slnum; /* source line number counter */ -extern char symbol[]; /* temporary symbol storage */ -extern int undef; /* undefined symbol in expression flag */ -extern int notyetdef; /* undefined-in-current-pass symbol in expr */ -extern unsigned int value; /* operand field value */ -extern int newproc_opt; /* use "new" style of procedure trampolines */ -extern int strip_opt; /* strip unused procedures? */ -extern int kickc_opt; /* NZ if -kc flag on command line */ -extern int mlist_opt; /* macro listing main flag */ -extern int xlist; /* listing file main flag */ -extern int list_level; /* output level */ -extern int asm_opt[9]; /* assembler option state */ +extern FILE *out_fp; /* file pointers, output */ +extern FILE *in_fp; /* input */ +extern FILE *lst_fp; /* listing */ +extern char *section_name[MAX_S + 1]; +extern t_file *extra_file; +extern t_input input_file[MAX_NESTING + 1]; +extern char full_path[PATHSZ * 2]; /* full path name of last file opened */ + +extern t_machine *machine; +extern t_machine nes; +extern t_machine pce; +extern t_machine fuji; +extern t_opcode *inst_tbl[HASH_COUNT]; /* instructions hash table */ +extern t_symbol *hash_tbl[HASH_COUNT]; /* label hash table */ +extern t_symbol *lablptr; /* label pointer into symbol table */ +extern t_symbol *glablptr; /* pointer to the latest defined global symbol */ +extern t_symbol *scopeptr; /* pointer to the latest defined scope label */ +extern t_symbol *lastlabl; /* last label we have seen */ +extern t_symbol *bank_glabl[MAX_S][MAX_BANKS]; /* latest global label in each bank */ +extern t_symbol *unaliased; /* unaliased version of last symbol lookup */ +extern t_branch *branchlst; /* first branch instruction assembled */ +extern t_branch *branchptr; /* last branch instruction assembled */ + +extern int branches_changed; /* count of branches changed in pass */ +extern char need_another_pass; /* NZ if another pass if required */ +extern char hex[]; /* hexadecimal character buffer */ +extern int stop_pass; /* stop the program; set by fatal_error() */ +extern int errcnt; /* error counter */ +extern void (*opproc)(int *); /* instruction gen proc */ +extern int opflg; /* instruction flags */ +extern int opval; /* instruction value */ +extern int optype; /* instruction type */ +extern char opext; /* instruction extension (.l or .h) */ +extern int pass; /* pass type (FIRST_PASS, EXTRA_PASS, LAST_PASS */ +extern int pass_count; /* pass counter */ +extern char prlnbuf[]; /* input line buffer */ +extern char tmplnbuf[]; /* temporary line buffer */ +extern int slnum; /* source line number counter */ +extern char symbol[]; /* temporary symbol storage */ +extern int undef; /* undefined symbol in expression flag */ +extern int notyetdef; /* undefined-in-current-pass symbol in expr */ +extern unsigned int value; /* operand field value */ +extern int newproc_opt; /* use "new" style of procedure thunks */ +extern int strip_opt; /* strip unused procedures? */ +extern int kickc_opt; /* NZ if -kc flag on command line */ +extern int hucc_opt; /* NZ if -hucc flag on command line */ +extern int mlist_opt; /* macro listing main flag */ +extern int xlist; /* listing file main flag */ +extern int list_level; /* output level */ +extern int asm_opt[MAX_OPTS]; /* assembler option state */ extern int opvaltab[6][16]; -extern int call_bank; /* bank for .proc trampolines */ -extern int kickc_mode; /* NZ if currently in KickC mode */ -extern int kickc_incl; /* auto-include "kickc-final.asm" */ -extern int preproc_inblock; /* C-style comment: within block comment */ -extern int preproc_sfield; /* C-style comment: SFIELD as a variable */ -extern int preproc_modidx; /* C-style comment: offset to modified char */ +extern int call_bank; /* bank for .proc thunks */ +extern int kickc_mode; /* NZ if currently in KickC mode */ +extern int sdcc_mode; /* NZ if assembling SDCC code */ +extern int hucc_mode; /* NZ if assembling HuCC code */ +extern int kickc_final; /* auto-include "kickc-final.asm" */ +extern int hucc_final; /* auto-include "hucc-final.asm" */ +extern int in_final; /* set when in xxxx-final.asm include */ +extern int preproc_inblock; /* C-style comment: within block comment */ +extern int preproc_sfield; /* C-style comment: SFIELD as a variable */ +extern int preproc_modidx; /* C-style comment: offset to modified char */ + +/* this is set when suppressing the listing output of stripped procedures */ +/* n.b. fully compatible with 2-pass assembly because code is still built */ +extern int cloaking_stripped; + +/* this is set when not assembling the code within the stripped procedure */ +/* n.b. not compatible with 2-pass assembly because symbol addresses will */ +/* change because both multi-label and branch tracking counts will change */ +extern int skipping_stripped; + +/* this is set to say that skipping is an acceptable alternative to */ +/* cloaking, which means that we've decided to do a 3-pass assembly */ +extern int allow_skipping; diff --git a/src/mkit/as/func.c b/src/mkit/as/func.c index 62eb5e83..4f43ad12 100644 --- a/src/mkit/as/func.c +++ b/src/mkit/as/func.c @@ -6,8 +6,8 @@ #include "externs.h" #include "protos.h" -struct t_func *func_tbl[256]; -struct t_func *func_ptr; +t_func *func_tbl[HASH_COUNT]; +t_func *func_ptr; char func_line[128]; char func_arg[8][10][80]; int func_idx; @@ -43,10 +43,15 @@ do_func(int *ip) fatal_error("Function name cannot be a multi-label!"); return; } - if (lablptr->defcnt || lablptr->refcnt) { + if (lablptr->defthispass || lablptr->refthispass) { switch (lablptr->type) { + case ALIAS: + fatal_error("Symbol already used by an alias!"); + return; + case MACRO: fatal_error("Symbol already used by a macro!"); + return; case FUNC: fatal_error("Function already defined!"); @@ -75,7 +80,7 @@ func_look(void) hash = symhash(); func_ptr = func_tbl[hash]; while (func_ptr) { - if (!strcmp(&symbol[1], func_ptr->name)) + if (!strcmp(symbol, func_ptr->label->name)) break; func_ptr = func_ptr->next; } @@ -97,7 +102,11 @@ func_install(int ip) /* mark the function name as reserved */ lablptr->type = FUNC; - lablptr->defcnt = 1; + lablptr->defthispass = 1; + + /* remember where this was defined */ + lablptr->fileinfo = input_file[infile_num].file; + lablptr->fileline = slnum; /* check function name syntax */ if (strchr(&symbol[1], '.')) { @@ -110,14 +119,21 @@ func_install(int ip) return (0); /* allocate a new func struct */ - if ((func_ptr = (void *)malloc(sizeof(struct t_func))) == NULL) { + func_ptr = (void *)malloc(sizeof(struct t_func)); + if (func_ptr == NULL) { error("Out of memory!"); return (0); } /* initialize it */ - strcpy(func_ptr->name, &symbol[1]); + func_ptr->label = lablptr; + func_ptr->line = malloc(strlen(func_line) + 1); + if (func_ptr->line == NULL) { + error("Out of memory!"); + return (0); + } strcpy(func_ptr->line, func_line); + hash = symhash(); func_ptr->next = func_tbl[hash]; func_tbl[hash] = func_ptr; @@ -194,7 +210,7 @@ func_getargs(void) int arg, level, space, flag; int i, x; - /* can not nest too much macros */ + /* Cannot nest macros too deeply */ if (func_idx == 7) { error("Too many nested function calls!"); return (0); diff --git a/src/mkit/as/input.c b/src/mkit/as/input.c index 0673a5df..c632127d 100644 --- a/src/mkit/as/input.c +++ b/src/mkit/as/input.c @@ -7,19 +7,25 @@ #include "externs.h" #include "protos.h" -#define INITIAL_PATH_SIZE 64 -#define INCREMENT_BASE 16 -#define INCREMENT_BASE_MASK 15 - -int infile_error; -int infile_num; -struct t_input_info input_file[8]; -static char *incpath = NULL; -static int *str_offset = NULL; -static int remaining = 0; -static int incpathSize = 0; -static int str_offsetCount = 0; -static int incpathCount = 0; +int file_count; +t_str_pool * str_pool; +t_file * file_hash[HASH_COUNT]; + +#define INCREMENT_BASE 256 +#define INCREMENT_BASE_MASK 255 + +char full_path[PATHSZ * 2]; +int infile_error; +int infile_num; +t_file *extra_file; +t_input input_file[MAX_NESTING + 1]; + +static char *incpath = NULL; +static int *incpath_offset = NULL; +static int incpath_remaining = 0; +static int incpath_size = 0; +static int incpath_offset_count = 0; +static int incpath_count = 0; /* ---- * void cleanup_path() @@ -29,58 +35,66 @@ static int incpathCount = 0; void cleanup_path(void) { - if(incpath) + if (incpath) free(incpath); - - if(str_offset) - free(str_offset); -} + + if (incpath_offset) + free(incpath_offset); +} /* ---- * int add_path(char*, int) * ---- - * add a path to includes + * add a path to includes (newpath_size includes the trailing '\0') */ int -add_path(char* path, int l) +add_path(char* newpath, int newpath_size) { - /* Expand str_offset array if needed */ - if(incpathCount >= str_offsetCount) + /* sanity check */ + if (newpath_size < 2) + return 0; + + /* remove trailing PATH_SEPARATOR characters */ + while (newpath[newpath_size - 2] == PATH_SEPARATOR) + --newpath_size; + + /* Expand incpath_offset array if needed */ + if (incpath_count >= incpath_offset_count) { - str_offsetCount += INCREMENT_BASE; - str_offset = (int*)realloc(str_offset, str_offsetCount * sizeof(int)); - if(str_offset == NULL) + incpath_offset_count += 8; + incpath_offset = (int*)realloc(incpath_offset, incpath_offset_count * sizeof(int)); + if (incpath_offset == NULL) return 0; } /* Initialize string offset */ - str_offset[incpathCount] = incpathSize - remaining; + incpath_offset[incpath_count] = incpath_size - incpath_remaining; /* Realloc string buffer if needed */ - if(remaining < l) + if (incpath_remaining < newpath_size) { - remaining = incpathSize; - /* evil trick, get the greater multiple of INCREMENT_BASE closer - to (size + l). Note : this only works for INCREMENT_BASE = 2^n*/ - incpathSize = ((incpathSize + l) + INCREMENT_BASE) & ~INCREMENT_BASE_MASK; - remaining = incpathSize - remaining; - incpath = (char*)realloc(incpath, incpathSize); - if(incpath == NULL) + incpath_remaining = incpath_size; + /* evil trick, get the greater multiple of INCREMENT_BASE closer + to (size + path_len). Note : this only works for INCREMENT_BASE = 2^n*/ + incpath_size = ((incpath_size + newpath_size) + INCREMENT_BASE) & ~INCREMENT_BASE_MASK; + incpath_remaining = incpath_size - incpath_remaining; + incpath = (char*)realloc(incpath, incpath_size); + if (incpath == NULL) return 0; } - - remaining -= l; + + incpath_remaining -= newpath_size; /* Copy path */ - strncpy(incpath + str_offset[incpathCount], path, l); - incpath[str_offset[incpathCount] + l - 1] = '\0'; - - ++incpathCount; - + strncpy(incpath + incpath_offset[incpath_count], newpath, newpath_size); + incpath[incpath_offset[incpath_count] + newpath_size - 1] = '\0'; + + ++incpath_count; + return 1; } -#ifdef WIN32 +#ifdef _WIN32 #define ENV_PATH_SEPARATOR ';' #else #define ENV_PATH_SEPARATOR ':' @@ -109,18 +123,18 @@ init_path(void) pl = p; while(pl != NULL) { - + /* Jump to next separator */ pl = strchr(p, ENV_PATH_SEPARATOR); /* Compute new substring size */ - if(pl == NULL) - l = strlen(p) + 1; + if (pl == NULL) + l = (int)strlen(p) + 1; else - l = pl - p + 1; - + l = (int)(pl - p + 1); + /* Might be empty, jump to next char */ - if(l <= 1) + if (l <= 1) { ++p; continue; @@ -128,15 +142,15 @@ init_path(void) /* Add path */ ret = add_path(p, l); - if(!ret) + if (!ret) return 0; /* Eat remaining separators */ while (*p == ENV_PATH_SEPARATOR) ++p; - + p += l; } - + return 1; } @@ -150,7 +164,8 @@ init_path(void) int readline(void) { - char *ptr, *arg, num[8]; + char *arg, num[8]; + const char *ptr; int j, n; int i; /* pointer into prlnbuf */ int c; /* current character */ @@ -178,7 +193,7 @@ readline(void) /* expand line */ if (mlptr) { i = SFIELD; - ptr = mlptr->data; + ptr = mlptr->line; for (;;) { c = *ptr++; if (c == '\0') @@ -223,7 +238,7 @@ readline(void) /* \1 - \9 */ else if (c >= '1' && c <= '9') { j = c - '1'; - n = strlen(marg[midx][j]); + n = (int)strlen(marg[midx][j]); arg = marg[midx][j]; } @@ -267,14 +282,26 @@ readline(void) c = getc(in_fp); if (c == EOF) { if (close_input()) { - if (stop_pass != 0 || kickc_incl == 0) { + if (stop_pass != 0 || ((extra_file == NULL) && (hucc_final == 0) && (kickc_final == 0))) { return (-1); } else { - kickc_incl = 0; - if (open_input("kickc-final.asm") == -1) { - fatal_error("Cannot open \"kickc-final.asm\" file!"); + const char * name; + if (extra_file != NULL) { + /* include the next file from the command-line */ + name = extra_file->name; + extra_file = extra_file->next; + } else { + /* auto-include a final source file */ + name = (hucc_final) ? "hucc-final.asm" : "kickc-final.asm"; + hucc_final = kickc_final = 0; + in_final = 1; + } + if (open_input(name) == -1) { + fatal_error("Cannot open \"%s\" file!", name); return (-1); } + /* switch to the CODE section */ + set_section(S_CODE); } } goto start; @@ -367,23 +394,99 @@ readline(void) return (0); } + +/* ---- + * remember_string() + * ---- + * remember all source file names + */ + +const char * +remember_string(const char * string, size_t size) +{ + const char * output; + + if ((str_pool == NULL) || (str_pool->remain < size)) { + t_str_pool *temp = malloc(sizeof(t_str_pool)); + if (temp == NULL) + return (NULL); + temp->remain = STR_POOL_SIZE; + temp->next = str_pool; + str_pool = temp; + } + + output = memcpy(str_pool->buffer + STR_POOL_SIZE - str_pool->remain, string, size); + str_pool->remain -= (int)size; + + return (output); +} + + +/* ---- + * remember_file() + * ---- + * remember all source file names + */ + +t_file * +remember_file(int hash) +{ + t_file * file = malloc(sizeof(t_file)); + + if (file == NULL) + return (NULL); + + file->name = remember_string(full_path, strlen(full_path) + 1); + file->number = ++file_count; + file->included = 0; + + file->next = file_hash[hash]; + file_hash[hash] = file; + + return (file); +} + + +/* ---- + * clear_included() + * ---- + * remember all source file names + */ + +void +clear_included(void) +{ + t_file *file; + int i; + + for (i = 0; i < HASH_COUNT; i++) { + file = file_hash[i]; + while (file) { + file->included = 0; + file = file->next; + } + } +} + + /* ---- * open_input() * ---- - * open input files - up to 7 levels. + * open input files - up to MAX_NESTING levels. */ int -open_input(char *name) +open_input(const char *name) { FILE *fp; char *p; - char temp[128]; - int i; + t_file * file; + char temp[PATHSZ + 4]; + int hash; - /* only 7 nested input files */ - if (infile_num == 7) { - error("Too many include levels, max. 7!"); + /* only MAX_NESTING nested input files */ + if (infile_num == MAX_NESTING) { + error("Too many include levels, maximum 31!"); return (1); } @@ -393,31 +496,48 @@ open_input(char *name) input_file[infile_num].fp = in_fp; } - /* get a copy of the file name */ - strcpy(temp, name); - /* auto add the .asm file extension */ - if ((p = strrchr(temp, '.')) != NULL) { - if (strchr(p, PATH_SEPARATOR)) - strcat(temp, ".asm"); - } - else { + if (((p = strrchr(name, '.')) == NULL) || + (strchr(p, PATH_SEPARATOR) != NULL)) { + strcpy(temp, name); strcat(temp, ".asm"); + name = temp; } - /* check if this file is already opened */ - if (infile_num) { - for (i = 1; i < infile_num; i++) { - if (!strcmp(input_file[i].name, temp)) { - error("Repeated include file!"); - return (1); - } + /* open the file */ + if ((fp = open_file(name, "r")) == NULL) + return (-1); + + /* remember all filenames */ + hash = filename_crc(full_path) & (HASH_COUNT - 1); + file = file_hash[hash]; + while (file) { +#if defined(_WIN32) || defined(__APPLE__) + if (strcasecmp(file->name, full_path) == 0) + break; +#else + if (strcmp(file->name, full_path) == 0) + break; +#endif + file = file->next; + } + if (file == NULL) { + file = remember_file(hash); + if (file == NULL) { + fclose(fp); + fatal_error("No memory left to remember filename!"); + return (-1); } } - /* open the file */ - if ((fp = open_file(temp, "r")) == NULL) - return (-1); + /* do not include the same file twice in a pass */ + if (file->included) { + fclose(fp); + return (0); + } + + /* remember that this file has been included */ + file->included = 1; /* update input file infos */ in_fp = fp; @@ -425,9 +545,9 @@ open_input(char *name) infile_num++; input_file[infile_num].fp = fp; input_file[infile_num].if_level = if_level; - strcpy(input_file[infile_num].name, temp); + input_file[infile_num].file = file; if ((pass == LAST_PASS) && (xlist) && (list_level)) - fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].name); + fprintf(lst_fp, "#[%i] \"%s\"\n", infile_num, input_file[infile_num].file->name); /* ok */ return (0); @@ -444,21 +564,19 @@ int close_input(void) { if (proc_ptr) { - fatal_error("Incomplete .proc/.procgroup!"); + fatal_error("Incomplete .PROC/.PROCGROUP!"); return (-1); } if (scopeptr) { - fatal_error("Incomplete .struct!"); + fatal_error("Incomplete .STRUCT!"); return (-1); } if (in_macro) { - fatal_error("Incomplete MACRO definition!"); + fatal_error("Incomplete .MACRO definition!"); return (-1); } if (input_file[infile_num].if_level != if_level) { - char message[128]; - sprintf(message, "Incomplete IF/ENDIF statement, beginning at line %d!", if_line[if_level-1]); - fatal_error(message); + fatal_error("Incomplete .IF/.ENDIF statement, beginning at line %d!", if_line[if_level-1]); return (-1); } if (infile_num <= 1) @@ -470,7 +588,7 @@ close_input(void) slnum = input_file[infile_num].lnum; in_fp = input_file[infile_num].fp; if ((pass == LAST_PASS) && (xlist) && (list_level)) - fprintf(lst_fp, "#[%i] %s\n", infile_num, input_file[infile_num].name); + fprintf(lst_fp, "#[%i] \"%s\"\n", infile_num, input_file[infile_num].file->name); /* ok */ return (0); @@ -484,26 +602,37 @@ close_input(void) */ FILE * -open_file(char *name, char *mode) +open_file(const char *name, const char *mode) { FILE *fileptr; - char testname[256]; int i; fileptr = fopen(name, mode); - if (fileptr != NULL) return(fileptr); - - for (i = 0; i < incpathCount; ++i) { - if (strlen(incpath+str_offset[i])) { - strcpy(testname, incpath+str_offset[i]); - strcat(testname, PATH_SEPARATOR_STRING); - strcat(testname, name); - - fileptr = fopen(testname, mode); - if (fileptr != NULL) break; + if (fileptr != NULL) { + strcpy(full_path, name); + return(fileptr); + } + + for (i = 0; i < incpath_count; ++i) { +#ifdef _WIN32 + strcpy(full_path, incpath + incpath_offset[i]); + strcat(full_path, PATH_SEPARATOR_STRING); + strcat(full_path, name); +#else + char *p; + p = stpcpy(full_path, incpath + incpath_offset[i]); + p = stpcpy(p, PATH_SEPARATOR_STRING); + stpcpy(p, name); +#endif + + if (strlen(full_path) > (PATHSZ - 1)) { + error("The include-path + filename string is too long!"); + return (NULL); } + + fileptr = fopen(full_path, mode); + if (fileptr != NULL) break; } return (fileptr); } - diff --git a/src/mkit/as/inst.h b/src/mkit/as/inst.h index 2c0c6901..b114e9b8 100644 --- a/src/mkit/as/inst.h +++ b/src/mkit/as/inst.h @@ -225,7 +225,6 @@ struct t_opcode base_pseudo[] = { {NULL, "ENDS", do_ends, PSEUDO, P_ENDS, 0}, {NULL, "EQU", do_equ, PSEUDO, P_EQU, 0}, {NULL, "FAIL", do_fail, PSEUDO, P_FAIL, 0}, -// {NULL, "FILL", do_ds, PSEUDO, P_DS, 0}, {NULL, "FUNC", do_func, PSEUDO, P_FUNC, 0}, {NULL, "IF", do_if, PSEUDO, P_IF, 0}, {NULL, "IFDEF", do_ifdef, PSEUDO, P_IFDEF, 1}, @@ -247,7 +246,6 @@ struct t_opcode base_pseudo[] = { {NULL, "RSSET", do_rsset, PSEUDO, P_RSSET, 0}, {NULL, "RS", do_rs, PSEUDO, P_RS, 0}, {NULL, "STRUCT", do_struct, PSEUDO, P_STRUCT, 0}, -// {NULL, "TEXT", do_db, PSEUDO, P_DB, 1}, // {NULL, "WORD", do_dw, PSEUDO, P_DW, 0}, {NULL, "ZP", do_section, PSEUDO, P_ZP, S_ZP}, @@ -272,8 +270,8 @@ struct t_opcode base_pseudo[] = { {NULL, ".ENDPROCGROUP", do_endp, PSEUDO, P_ENDPG, P_PGROUP}, {NULL, ".EQU", do_equ, PSEUDO, P_EQU, 0}, {NULL, ".FAIL", do_fail, PSEUDO, P_FAIL, 0}, - {NULL, ".FILL", do_ds, PSEUDO, P_DS, 0}, {NULL, ".FUNC", do_func, PSEUDO, P_FUNC, 0}, + {NULL, ".HOME", do_section, PSEUDO, P_CODE, S_HOME}, {NULL, ".IF", do_if, PSEUDO, P_IF, 0}, {NULL, ".IFDEF", do_ifdef, PSEUDO, P_IFDEF, 1}, {NULL, ".IFNDEF", do_ifdef, PSEUDO, P_IFNDEF, 0}, @@ -296,23 +294,45 @@ struct t_opcode base_pseudo[] = { {NULL, ".SET", do_equ, PSEUDO, P_EQU, 1}, {NULL, ".STRUCT", do_struct, PSEUDO, P_STRUCT, 0}, {NULL, ".ENDS", do_ends, PSEUDO, P_ENDS, 0}, - {NULL, ".TEXT", do_db, PSEUDO, P_DB, 1}, {NULL, ".WORD", do_dw, PSEUDO, P_DW, 0}, {NULL, ".ZP", do_section, PSEUDO, P_ZP, S_ZP}, {NULL, ".ZEROPAGE", do_section, PSEUDO, P_ZP, S_ZP}, + {NULL, ".3PASS", do_3pass, PSEUDO, P_3PASS, 0}, + {NULL, ".ALIAS", do_alias, PSEUDO, P_ALIAS, 0}, + {NULL, ".REF", do_ref, PSEUDO, P_REF, 0}, + {NULL, ".PHASE", do_phase, PSEUDO, P_PHASE, 0}, + {NULL, ".DEPHASE", do_phase, PSEUDO, P_PHASE, 1}, + + // pseudo-ops that support asm code generated by KickC {NULL, ".PCEAS", do_kickc, PSEUDO, P_KICKC, 0}, {NULL, ".KICKC", do_kickc, PSEUDO, P_KICKC, 1}, - {NULL, ".CPU", do_cpu, PSEUDO, P_CPU, 0}, + {NULL, ".CPU", do_ignore, PSEUDO, P_IGNORE, 0}, + {NULL, ".ENCODING", do_ignore, PSEUDO, P_IGNORE, 0}, {NULL, ".SEGMENT", do_segment, PSEUDO, P_SEGMENT, 0}, {NULL, ".CONST", do_label, PSEUDO, P_LABEL, 0}, {NULL, ".LABEL", do_label, PSEUDO, P_LABEL, 0}, {NULL, ".VAR", do_label, PSEUDO, P_LABEL, 1}, - {NULL, ".ENCODING", do_encoding, PSEUDO, P_ENCODING,0}, + {NULL, ".TEXT", do_db, PSEUDO, P_DB, 1}, + {NULL, ".FILL", do_ds, PSEUDO, P_DS, 0}, {NULL, "{", do_proc, PSEUDO, P_PROC, P_KICKC}, {NULL, "}", do_endp, PSEUDO, P_ENDP, P_KICKC}, + // pseudo-ops that support asm code generated by SDCC + + {NULL, ".MODULE", do_include, PSEUDO, P_INCLUDE, 1}, + {NULL, ".OPTSDCC", do_ignore, PSEUDO, P_IGNORE, 0}, + {NULL, ".R6502", do_kickc, PSEUDO, P_KICKC, 2}, + {NULL, ".R65C02", do_kickc, PSEUDO, P_KICKC, 2}, + {NULL, ".GLOBL", do_ignore, PSEUDO, P_IGNORE, 0}, + {NULL, ".AREA", do_segment, PSEUDO, P_SEGMENT, 1}, + {NULL, ".ASCII", do_db, PSEUDO, P_DB, 2}, + + // pseudo-ops that support asm code generated by HuCC + + {NULL, ".HUCC", do_kickc, PSEUDO, P_KICKC, 4}, + {NULL, NULL, NULL, 0, 0, 0} }; /* *INDENT-ON* */ diff --git a/src/mkit/as/macro.c b/src/mkit/as/macro.c index ad593d05..d0de488a 100644 --- a/src/mkit/as/macro.c +++ b/src/mkit/as/macro.c @@ -13,10 +13,10 @@ char marg[8][10][256]; int midx; int mcounter, mcntmax; int mcntstack[8]; -struct t_line *mstack[8]; -struct t_line *mlptr; -struct t_macro *macro_tbl[256]; -struct t_macro *mptr; +t_line *mstack[8]; +t_line *mlptr; +t_macro *macro_tbl[HASH_COUNT]; +t_macro *mptr; /* .macro pseudo */ @@ -33,7 +33,7 @@ do_macro(int *ip) return; } if (expand_macro) { - error("Can not nest macro definitions!"); + error("Cannot nest macro definitions!"); return; } if (lablptr == NULL) { @@ -59,8 +59,12 @@ do_macro(int *ip) fatal_error("Macro name cannot be a multi-label!"); return; } - if (lablptr->defcnt || lablptr->refcnt) { + if (lablptr->defthispass || lablptr->refthispass) { switch (lablptr->type) { + case ALIAS: + fatal_error("Symbol already used by an alias!"); + return; + case MACRO: fatal_error("Macro already defined!"); return; @@ -90,7 +94,7 @@ do_macro(int *ip) void do_endm(int *ip) { - error("Unexpected ENDM!"); + error("Unexpected .ENDM!"); return; } @@ -100,7 +104,7 @@ struct t_macro * macro_look(int *ip) { struct t_macro *ptr; - char name[32]; + char name[SBOLSZ]; char c; int hash; int l; @@ -118,7 +122,7 @@ macro_look(int *ip) if (isdigit(c)) return (NULL); } - if (l == 31) + if (l == (SBOLSZ-2)) return (NULL); name[l++] = c; hash += c; @@ -130,7 +134,7 @@ macro_look(int *ip) /* browse the hash table */ ptr = macro_tbl[hash]; while (ptr) { - if (!strcmp(name, ptr->name)) + if (!strcmp(name, ptr->label->name + 1)) break; ptr = ptr->next; } @@ -149,7 +153,7 @@ macro_getargs(int ip) int i, j, f, arg; int level; - /* can not nest too much macros */ + /* Cannot nest too much macros */ if (midx == 7) { error("Too many nested macro calls!"); return (0); @@ -264,6 +268,19 @@ macro_getargs(int ip) f = 0; level = 0; while (c) { + if (c == '/' && prlnbuf[ip] == '*') { + ++ip; + do { + c = prlnbuf[ip++]; + if (c == '\0') { + error("Macro argument comment cannot span multiple lines!"); + return (0); + } + } while (c != '*' && prlnbuf[ip] != '/'); + ++ip; + c = prlnbuf[ip++]; + continue; + } if (c == ',') { if (level == 0) break; @@ -292,8 +309,8 @@ macro_getargs(int ip) else { ptr[i++] = c; } - if (i == 80) { - error("Macro argument string too long, max. 80 characters!"); + if (i == 255) { + error("Macro argument string too long, max. 255 characters!"); return (0); } j++; @@ -344,7 +361,11 @@ macro_install(void) /* mark the macro name as reserved */ lablptr->type = MACRO; - lablptr->defcnt = 1; + lablptr->defthispass = 1; + + /* remember where this was defined */ + lablptr->fileinfo = input_file[infile_num].file; + lablptr->fileline = slnum; /* check macro name syntax */ /* @@ -369,7 +390,7 @@ macro_install(void) } /* initialize it */ - strcpy(mptr->name, &symbol[1]); + mptr->label = lablptr; mptr->line = NULL; mptr->next = macro_tbl[hash]; macro_tbl[hash] = mptr; @@ -440,7 +461,7 @@ macro_getargtype(char *arg) else { if ((sym->type == UNDEF) || (sym->type == IFUNDEF)) return (ARG_LABEL); - if (sym->bank == RESERVED_BANK) + if (sym->mprbank == UNDEFINED_BANK) return (ARG_ABS); else return (ARG_LABEL); diff --git a/src/mkit/as/main.c b/src/mkit/as/main.c index 05a1965d..62cd034a 100644 --- a/src/mkit/as/main.c +++ b/src/mkit/as/main.c @@ -27,8 +27,12 @@ #include #include #include -#include #include +#ifdef _MSC_VER +#include "xgetopt.h" +#else +#include +#endif #include "defs.h" #include "externs.h" #include "protos.h" @@ -51,12 +55,23 @@ char zeroes[2048]; /* CDROM sector full of zeores */ char *prg_name; /* program name */ FILE *in_fp; /* file pointers, input */ FILE *lst_fp; /* listing */ -char section_name[5][8] = { - " ZP", " BSS", "CODE", "DATA", "PROC" +char *section_name[MAX_S + 1] = { + "NULL", + "ZP", + "BSS", + "CODE", + "DATA", + "HOME", + "XDATA", + "XINIT", + "CONST", + "OSEG", + "PROC" }; int newproc_opt; int strip_opt; int kickc_opt; +int hucc_opt; int dump_seg; int overlayflag; int develo_opt; @@ -69,15 +84,58 @@ int ipl_opt; int sgx_opt; int scd_opt; int cd_opt; +int sf2_opt; int mx_opt; int mlist_opt; /* macro listing main flag */ int xlist; /* listing file main flag */ int list_level; /* output level */ -int asm_opt[9]; /* assembler options */ +int asm_opt[MAX_OPTS]; /* assembler options */ int zero_need; /* counter for trailing empty sectors on CDROM */ int rom_used; int rom_free; +/* current flags for each section */ +int section_flags[MAX_S] = { +/* S_NONE */ S_NO_DATA, +/* S_ZP */ S_IS_RAM + S_NO_DATA, +/* S_BSS */ S_IS_RAM + S_NO_DATA, +/* S_CODE */ S_IS_ROM + S_IS_CODE, +/* S_DATA */ S_IS_ROM, +/* S_HOME */ S_IS_ROM + S_IS_CODE, +/* S_XDATA */ S_IS_RAM + S_NO_DATA, +/* S_XINIT */ S_IS_ROM, +/* S_CONST */ S_IS_ROM, +/* S_OSEG */ S_IS_RAM +}; + +/* initial page for the banks for each section */ +const int section_default_page[MAX_S] = { +/* S_NONE */ 0, +/* S_ZP */ 2, +/* S_BSS */ 2, +/* S_CODE */ 7, +/* S_DATA */ 3, +/* S_HOME */ 5, +/* S_XDATA */ 0, +/* S_XINIT */ 0, +/* S_CONST */ 0, +/* S_OSEG */ 0 +}; + +/* maximum loccnt limit for each section */ +/* N.B. this isn't used, yet! */ +int section_limit[MAX_S] = { +/* S_NONE */ 0x0000, +/* S_ZP */ 0x0100, +/* S_BSS */ 0x2000, +/* S_CODE */ 0x2000, +/* S_DATA */ 0x2000, +/* S_HOME */ 0x2000, +/* S_XDATA */ 0x2000, +/* S_XINIT */ 0x2000, +/* S_CONST */ 0x2000, +/* S_OSEG */ 0x0100 +}; /* ---- * atexit callback @@ -214,36 +272,42 @@ main(int argc, char **argv) { FILE *fp; char *p; - char cmd[512]; int i, j, opt; - int file; int ram_bank; - int cd_type; - int pass_count = 0; - const char *cmd_line_options = "sSl:mhI:o:O"; - const struct option cmd_line_long_options[] = { - {"segment", 0, 0, 's'}, - {"fullsegment", 0, 0, 'S'}, - {"listing", 1, 0, 'l'}, - {"macro", 0, 0, 'm'}, - {"raw", 0, &header_opt, 0 }, - {"pad", 0, &padding_opt, 1 }, - {"trim", 0, &trim_opt, 1 }, - {"cd", 0, &cd_type, 1 }, - {"scd", 0, &cd_type, 2 }, - {"sgx", 0, &sgx_opt, 1 }, - {"ipl", 0, &ipl_opt, 1 }, - {"over", 0, &overlayflag, 1 }, - {"overlay", 0, &overlayflag, 1 }, - {"dev", 0, &develo_opt, 1 }, - {"develo", 0, &develo_opt, 1 }, - {"mx", 0, &mx_opt, 1 }, - {"srec", 0, &srec_opt, 1 }, - {"help", 0, 0, 'h'}, - {"strip", 0, &strip_opt, 1 }, - {"newproc", 0, &newproc_opt, 1 }, - {"kc", 0, &kickc_opt, 1 }, - {0, 0, 0, 0 } + static t_file *extra_source = NULL; + static t_file *final_source = NULL; + + static int cd_type; + static const char *cmd_line_options = "I:OShl:mo:s"; + static const struct option cmd_line_long_options[] = { + {"include", required_argument, 0, 'I'}, + {"pack", no_argument, 0, 'O'}, + {"fullsegment", no_argument, 0, 'S'}, + {"help", no_argument, 0, 'h'}, + {"listing", required_argument, 0, 'l'}, + {"macro", no_argument, 0, 'm'}, + {"output", required_argument, 0, 'o'}, + {"segment", no_argument, 0, 's'}, + + {"cd", no_argument, &cd_type, 1 }, + {"develo", no_argument, &develo_opt, 1 }, + {"hucc", no_argument, &hucc_opt, 1 }, + {"ipl", no_argument, &ipl_opt, 1 }, + {"kc", no_argument, &kickc_opt, 1 }, + {"mx", no_argument, &mx_opt, 1 }, + {"overlay", no_argument, &overlayflag, 1 }, + {"newproc", no_argument, &newproc_opt, 1 }, + {"pad", no_argument, &padding_opt, 1 }, + {"raw", no_argument, &header_opt, 0 }, + {"scd", no_argument, &cd_type, 2 }, + {"sdcc", no_argument, &hucc_opt, 1 }, + {"sf2", no_argument, &sf2_opt, 1 }, + {"sgx", no_argument, &sgx_opt, 1 }, + {"srec", no_argument, &srec_opt, 1 }, + {"strip", no_argument, &strip_opt, 1 }, + {"trim", no_argument, &trim_opt, 1 }, + + {0, no_argument, 0, 0 } }; /* register atexit callback */ @@ -271,7 +335,7 @@ main(int argc, char **argv) ) { machine = &pce; } - else if( + else if ( ((prg_name[0] == 'N') || (prg_name[0] == 'n')) && ((prg_name[1] == 'E') || (prg_name[1] == 'e')) && ((prg_name[2] == 'S') || (prg_name[2] == 's')) @@ -294,35 +358,60 @@ main(int argc, char **argv) run_opt = 0; ipl_opt = 0; sgx_opt = 0; + sf2_opt = 0; scd_opt = 0; cd_opt = 0; mx_opt = 0; - file = 0; cd_type = 0; strip_opt = 0; kickc_opt = 0; newproc_opt = 0; - memset(out_fname, 0, 256); - /* display assembler version message */ printf("%s\n\n", machine->asm_title); + /* process the command line options */ while ((opt = getopt_long_only (argc, argv, cmd_line_options, cmd_line_long_options, NULL)) != -1) { switch(opt) { - case 's': - dump_seg = 1; + case 'I': + /* optarg can have a leading space on linux/mac */ + while (*optarg == ' ') { ++optarg; } + + if (*optarg == '-') { + fprintf(stderr, "%s: include path missing after \"-I\"!\n", argv[0]); + return (1); + } + if (!add_path(optarg, (int)strlen(optarg)+1)) { + fprintf(stderr, "%s: could not add path to list of include directories\n", argv[0]); + return (1); + } + break; + + case 'O': + asm_opt[OPT_OPTIMIZE] = 1; break; case 'S': dump_seg = 2; break; + case 'h': + help(); + return (0); + case 'l': + /* optarg can have a leading space on linux/mac */ + while (*optarg == ' ') { ++optarg; } + + if ((isdigit(*optarg) == 0) || (optarg[1] != '\0')) { + fprintf(stderr, "%s: \"-l\" option must be followed by a single digit\n", argv[0]); + return (1); + } + /* get level */ - list_level = atol(optarg); + list_level = *optarg - '0'; /* check range */ if (list_level < 0 || list_level > 3) @@ -333,31 +422,33 @@ main(int argc, char **argv) mlist_opt = 1; break; - case 'I': - if(!add_path(optarg, strlen(optarg)+1)) - { - printf("Error while adding include path\n"); - return 0; - } - break; - case 'o': + /* optarg can have a leading space on linux/mac */ + while (*optarg == ' ') { ++optarg; } + + if (*optarg == '-') { + fprintf(stderr, "%s: output filename missing after \"-o\"\n", argv[0]); + return (1); + } + if (strlen(optarg) >= PATHSZ) { + fprintf(stderr, "%s: output filename too long, maximum %d characters\n", argv[0], PATHSZ - 1); + return (1); + } strcpy(out_fname, optarg); break; - case 'O': - asm_opt[OPT_OPTIMIZE] = 1; + case 's': + dump_seg = 1; break; - case 'h': - help(); - return 0; - + /* when a long-option has been processed */ case 0: break; + /* unknown option */ default: - return 1; + help(); + return (1); } } @@ -375,20 +466,15 @@ main(int argc, char **argv) overlayflag = 0; } - /* enable optimized procedure packing if stripping */ - asm_opt[OPT_OPTIMIZE] |= strip_opt; - - /* check for missing asm file */ - if(optind == argc) + /* HuCC option requires newproc_opt and strip_opt as well */ + if (hucc_opt) { - fprintf(stderr, "Missing input file\n"); - return 0; + newproc_opt = 1; + strip_opt = 1; } - /* get file names */ - for ( ; optind < argc; ++optind, ++file) { - strcpy(in_fname, argv[optind]); - } + /* enable optimized procedure packing if stripping */ + asm_opt[OPT_OPTIMIZE] |= (newproc_opt | strip_opt); if (machine->type == MACHINE_PCE) { /* Adjust cdrom type values ... */ @@ -408,20 +494,31 @@ main(int argc, char **argv) if ((overlayflag == 1) && ((scd_opt == 0) && (cd_opt == 0))) { - printf("Overlay option only valid for CD or SCD programs\n\n"); + fprintf(ERROUT, "Error: Overlay option only valid for CD or SCD programs.\n\n"); help(); - return (0); + return (1); } } else { /* Force ipl_opt off if not PCEAS */ ipl_opt = 0; } - if (!file) { - help(); - return (0); + /* check for input file name missing */ + if (optind == argc) + { + fprintf(ERROUT, "Error: Input file name missing!\n"); + return (1); } + /* check for input file name too long (including room to add an extension) */ + if (strlen(argv[optind]) > (PATHSZ - 5)) { + fprintf(ERROUT, "Error: Input file name too long!\n"); + return (1); + } + + /* get the input file name */ + strcpy(in_fname, argv[optind++]); + /* search file extension */ if ((p = strrchr(in_fname, '.')) != NULL) { if (!strchr(p, PATH_SEPARATOR)) @@ -458,21 +555,35 @@ main(int argc, char **argv) else strcat(in_fname, ".asm"); + /* get any additional file names */ + while (optind < argc) { + t_file *file = malloc(sizeof(t_file)); + if (file == NULL) { + fprintf(ERROUT, "Error: Not enough memory!\n"); + exit(1); + } + file->next = NULL; + file->name = argv[optind++]; + + if (extra_source == NULL) + extra_source = file; + if (final_source != NULL) + final_source->next = file; + final_source = file; + } + /* init include path */ init_path(); - /* init crc functions */ - crc_init(); - /* open the input file */ if (open_input(in_fname)) { - printf("Can not open input file '%s'!\n", in_fname); + fprintf(ERROUT, "Error: Cannot open input file \"%s\"!\n", in_fname); exit(1); } /* clear the ROM array */ - memset(rom, 0xFF, 8192 * 128); - memset(map, 0xFF, 8192 * 128); + memset(rom, 0xFF, MAX_BANKS * 8192); + memset(map, 0xFF, MAX_BANKS * 8192); /* are we creating a custom PCE CDROM IPL? */ if (ipl_opt) { @@ -482,7 +593,7 @@ main(int argc, char **argv) } /* clear symbol hash tables */ - for (i = 0; i < 256; i++) { + for (i = 0; i < HASH_COUNT; i++) { hash_tbl[i] = NULL; macro_tbl[i] = NULL; func_tbl[i] = NULL; @@ -509,7 +620,17 @@ main(int argc, char **argv) bank_base = 0x00; bank_limit = 0x7F; - if (ipl_opt) { + /* fixme: these should be exclusive! */ + /* process -sf2 first, because overlays are incompatible with the other modes */ + if (sf2_opt) { + rom_limit = ROM_BANKS * 8192; /* 8MB */ + bank_base = 0x00; + bank_limit = ROM_BANKS - 1; + section_flags[S_HOME] |= S_IS_SF2; + section_flags[S_CODE] |= S_IS_SF2; + section_flags[S_DATA] |= S_IS_SF2; + } + else if (ipl_opt) { rom_limit = 0x01800; /* 4KB */ bank_base = 0x00; bank_limit = 0x00; @@ -542,8 +663,8 @@ main(int argc, char **argv) /* assemble */ for (pass = FIRST_PASS; pass <= LAST_PASS; pass++) { + extra_file = extra_source; infile_error = -1; - page = 7; bank = 0; loccnt = 0; slnum = 0; @@ -553,14 +674,19 @@ main(int argc, char **argv) glablptr = NULL; scopeptr = NULL; branchptr = branchlst; - xvertlong = 0; + branches_changed = 0; need_another_pass = 0; skip_lines = 0; - rsbase = 0; - rsbank = RESERVED_BANK; + rs_base = 0; + rs_mprbank = UNDEFINED_BANK; + rs_overlay = 0; + proc_ptr = NULL; proc_nb = 0; kickc_mode = 0; - kickc_incl = kickc_opt; + sdcc_mode = 0; + kickc_final = 0; + hucc_final = 0; + in_final = 0; /* reset assembler options */ asm_opt[OPT_LIST] = 0; @@ -570,20 +696,26 @@ main(int argc, char **argv) asm_opt[OPT_INDPAREN] = 0; asm_opt[OPT_ZPDETECT] = 0; asm_opt[OPT_LBRANCH] = 0; + asm_opt[OPT_DATAPAGE] = 0; + asm_opt[OPT_FORWARD] = 1; /* reset bank arrays */ - for (i = 0; i < 4; i++) { - for (j = 0; j < 256; j++) { + for (i = 0; i < MAX_S; i++) { + page = newproc_opt ? section_default_page[i] : 0; + section_bank[i] = 0; + section_phase[i] = 0; + for (j = 0; j < MAX_BANKS; j++) { bank_maxloc[j] = 0; bank_loccnt[i][j] = 0; bank_glabl[i][j] = NULL; - bank_page[i][j] = 0; + bank_page[i][j] = page; } } /* reset sections */ ram_bank = machine->ram_bank; section = S_CODE; + page = 7; /* .zp */ section_bank[S_ZP] = ram_bank; @@ -600,18 +732,23 @@ main(int argc, char **argv) bank_page[S_CODE][0x00] = 0x07; bank_loccnt[S_CODE][0x00] = 0x0000; + /* .home */ + section_bank[S_HOME] = 0x00; + bank_page[S_HOME][0x00] = 0x05; + bank_loccnt[S_HOME][0x00] = 0x0000; + /* .data */ section_bank[S_DATA] = 0x00; - bank_page[S_DATA][0x00] = 0x07; + bank_page[S_DATA][0x00] = 0x03; bank_loccnt[S_DATA][0x00] = 0x0000; /* reset symbol table and include files */ if (pass != FIRST_PASS) { - /* clear the label and multi-label defcnt */ - lablresetdefcnt(); + /* reset symbol definition and reference tracking */ + lablstartpass(); /* clear the list of included files */ - forget_included_files(); + clear_included(); } /* reset max_bank */ @@ -633,8 +770,7 @@ main(int argc, char **argv) /* N.B. $2000 is a legal loccnt that says that the bank is full! */ if (loccnt > 0x2000) { if (proc_ptr) { - snprintf(cmd, sizeof(cmd), ".proc/.progroup \"%s\" is larger than 8192 bytes!\n", proc_ptr->name); - fatal_error(cmd); + fatal_error(".PROC/.PROGROUP \"%s\" is larger than 8192 bytes!\n", proc_ptr->label->name + 1); break; } @@ -646,12 +782,12 @@ main(int argc, char **argv) if (section != S_DATA || asm_opt[OPT_DATAPAGE] == 0) page = (page + 1) & 7; - if (section == S_CODE && page == 0) { - error("CODE section wrapped from MPR7 to MPR0!"); + if ((section_flags[section] & S_IS_CODE) && page == 0) { + error(".CODE or .HOME section wrapped from MPR7 to MPR0!"); } if (asm_opt[OPT_WARNING] && pass == LAST_PASS) { - printf(" (Warning. Opcode crossing page boundary $%04X, bank $%02X)\n", (page * 0x2000), bank); + warning("Opcode crossing page boundary $%04X, bank $%02X", (page * 0x2000), bank); } } while (old_bank != bank) { @@ -664,39 +800,51 @@ main(int argc, char **argv) /* sanity check */ if (max_bank > bank_limit) { - snprintf(cmd, sizeof(cmd), "Assembler bug ... max_bank (0x%02X) > bank_limit (0x%02X)!\n", max_bank, bank_limit); - fatal_error(cmd); + fatal_error("Assembler bug ... max_bank (0x%04X) > bank_limit (0x%04X)!\n", max_bank, bank_limit); } if (stop_pass) break; } - /* abort pass on errors */ + /* abort pass on errors during the pass */ if (errcnt) { - printf("# %d error(s)\n", errcnt); + fprintf(ERROUT, "# %d error(s)\n", errcnt); exit(1); } - /* set pass to FIRST_PASS to run BRANCH_PASS next */ - /* or set it to BRANCH_PASS to run LAST_PASS next */ + /* check which procedures have been referenced */ + if (pass == FIRST_PASS) { +// /* force a 3rd pass for testing */ +// need_another_pass = 1; + + /* only skip stripped procedures if we're going to + ** run a 3rd pass anyway, just hide them if not */ + allow_skipping = need_another_pass; + + /* strip unreferenced procedures */ + proc_strip(); + } + + /* set pass to FIRST_PASS to run EXTRA_PASS next */ + /* or set it to EXTRA_PASS to run LAST_PASS next */ if (pass != LAST_PASS) { /* fix out-of-range short-branches, return number fixed */ if ((branchopt() != 0) || (need_another_pass != 0)) pass = FIRST_PASS; else - pass = BRANCH_PASS; + pass = EXTRA_PASS; } /* do this just before the last pass */ - if (pass == BRANCH_PASS) { + if (pass == EXTRA_PASS) { /* open the listing file */ if (lst_fp == NULL && xlist && list_level) { if ((lst_fp = fopen(lst_fname, "w")) == NULL) { - printf("Can not open listing file '%s'!\n", lst_fname); + fprintf(ERROUT, "Error: Cannot open listing file \"%s\"!\n", lst_fname); exit(1); } - fprintf(lst_fp, "#[1] %s\n", input_file[1].name); + fprintf(lst_fp, "#[1] \"%s\"\n", input_file[1].file->name); } /* relocate procs */ @@ -712,9 +860,9 @@ main(int argc, char **argv) } } - /* abort pass on errors */ + /* abort pass on errors after the pass */ if (errcnt) { - printf("# %d error(s)\n", errcnt); + fprintf(ERROUT, "# %d error(s)\n", errcnt); exit(1); } @@ -739,7 +887,7 @@ main(int argc, char **argv) if ((cd_opt || scd_opt) && !trim_opt) { /* open output file */ if ((fp = fopen(bin_fname, "wb")) == NULL) { - printf("Can not open output file '%s'!\n", bin_fname); + fprintf(ERROUT, "Error: Cannot open output file \"%s\"!\n", bin_fname); exit(1); } @@ -841,6 +989,7 @@ main(int argc, char **argv) /* execute */ if (develo_opt) { + char cmd[PATHSZ+6]; snprintf(cmd, sizeof(cmd), "perun %s", out_fname); system(cmd); } @@ -854,8 +1003,20 @@ main(int argc, char **argv) /* binary file */ else { - /* pad rom to power-of-two? */ int num_banks = max_bank + 1; + + /* make StreetFighterII roms compatible with emulators which detect size */ + if (sf2_opt) { + /* Pad a StreetFighterII HuCARD to a minimum of the 2MB */ + if (num_banks < (64 * 4)) + num_banks = (64 * 4); + + /* Also pad it to a multiple of the 512KB mapper size */ + if (num_banks & 63) + num_banks = num_banks + 64 - (num_banks & 63); + } + + /* pad rom to power-of-two? */ if (padding_opt) { num_banks = 1; while (num_banks <= max_bank) num_banks <<= 1; @@ -863,7 +1024,7 @@ main(int argc, char **argv) /* open file */ if ((fp = fopen(bin_fname, "wb")) == NULL) { - printf("Can not open binary file '%s'!\n", bin_fname); + fprintf(ERROUT, "Error: Cannot open binary file \"%s\"!\n", bin_fname); exit(1); } @@ -923,23 +1084,21 @@ main(int argc, char **argv) /* dump the bank table */ if (dump_seg) - show_seg_usage(); + show_seg_usage(stdout); - /* check for corrupted trampolines */ - if (check_trampolines()) { + /* check for corrupted thunks */ + if (check_thunks()) { exit(1); } /* warn about 384KB hucard rom size */ if (cd_opt == 0 && scd_opt == 0 && padding_opt == 0) { if (max_bank == 0x2F) { - printf( - "\n!!!WARNING!!!\n" + warning("A 384KB ROM size may not work with emulators!\n\n" "Most emulators expect a 384KB HuCard ROM to be in a split-image layout.\n\n" "Unless you are patching an existing 384KB HuCard game image, you are\n" "almost-certainly not using that layout, and your ROM will crash.\n\n" - "To avoid problems, add or remove enough data to avoid the 384KB size.\n" - "!!!WARNING!!!\n\n"); + "To avoid problems, add or remove enough data to avoid the 384KB size.\n\n"); } } @@ -962,40 +1121,42 @@ help(void) prg_name = machine->asm_name; /* display help */ - printf("%s [-options] [-? (for help)] [-o outfile] infile\n\n", prg_name); - printf("-s/S : show segment usage\n"); - printf("-l # : listing file output level (0-3)\n"); + printf("%s [options] [-h (for help)] [-o outfile] infiles\n\n", prg_name); + printf("-s : show segment usage\n"); + printf("-S : show segment usage and contents\n"); + printf("-l <0..3> : listing file output level (0-3), default is 2\n"); printf("-m : force macro expansion in listing\n"); - printf("-raw : prevent adding a ROM header\n"); - printf("-pad : pad ROM size to power-of-two\n"); - printf("-trim : strip unused head and tail from ROM\n"); + printf("--raw : prevent adding a ROM header\n"); + printf("--pad : pad ROM size to power-of-two\n"); + printf("--trim : strip unused head and tail from ROM\n"); printf("-I : add include path\n"); if (machine->type == MACHINE_PCE) { - printf("-cd : create a CD-ROM track image\n"); - printf("-scd : create a Super CD-ROM track image\n"); - printf("-sgx : add a SuperGRAFX signature to the CD-ROM\n"); - printf("-over(lay) : create an executable 'overlay' program segment\n"); - printf("-ipl : create a custom CD-ROM IPL file\n"); - printf("-dev : assemble and run on the Develo Box\n"); - printf("-mx : create a Develo MX file\n"); + printf("--sf2 : create a StreetFighterII HuCARD\n"); + printf("--cd : create a CD-ROM track image\n"); + printf("--scd : create a Super CD-ROM track image\n"); + printf("--sgx : add a SuperGRAFX signature to the CD-ROM\n"); + printf("--overlay : create an executable 'overlay' program segment\n"); + printf("--ipl : create a custom CD-ROM IPL file\n"); + printf("--develo : assemble and run on the Develo Box\n"); + printf("--mx : create a Develo MX file\n"); printf("-O : optimize .proc packing (compared to HuC v3.21)\n"); - printf("-strip : strip unused .proc & .procgroup\n"); - printf("-newproc : run .proc code in MPR6, instead of MPR5\n"); + printf("--strip : strip unused .proc & .procgroup\n"); + printf("--newproc : run .proc code in MPR6, instead of MPR5\n"); } - printf("-kc : assemble code generated by the KickC compiler\n"); - printf("-srec : create a Motorola S-record file\n"); - printf("infile : file to be assembled\n"); + printf("--kc : assemble code generated by the KickC compiler\n"); + printf("--srec : create a Motorola S-record file\n"); + printf("infiles : one or more files to be assembled\n"); printf("\n"); } /* ---- - * show_bnk_usage() + * show_bank_usage() * ---- */ void -show_bnk_usage(int which_bank) +show_bank_usage(FILE *fp, int which_bank) { int addr, start, nb; @@ -1013,10 +1174,10 @@ show_bnk_usage(int which_bank) /* display bank infos */ if (nb) - printf("BANK %2X %-23s %4i/%4i\n", + fprintf(fp, "BANK $%-3X %-23s %4i / %4i\n", which_bank, bank_name[which_bank], nb, 8192 - nb); else { - printf("BANK %2X %-23s 0/8192\n", which_bank, bank_name[which_bank]); + fprintf(fp, "BANK $%-3X %-23s 0 / 8192\n", which_bank, bank_name[which_bank]); return; } @@ -1045,7 +1206,7 @@ show_bnk_usage(int which_bank) break; /* display section infos */ - printf(" %s $%04X-$%04X [%4i]\n", + fprintf(fp, " %5s $%04X-$%04X [%4i]\n", section_name[section], /* section name */ start + page, /* starting address */ addr + page - 1, /* end address */ @@ -1060,33 +1221,32 @@ show_bnk_usage(int which_bank) */ void -show_seg_usage(void) +show_seg_usage(FILE *fp) { int i; int start, stop; int ram_base = machine->ram_base; - printf("segment usage:\n"); - printf("\n"); + fprintf(fp, "\nSegment Usage:\n"); - printf("\t\t\t\t USED/FREE\n"); + fprintf(fp, "%37c USED / FREE\n", ' '); /* zp usage */ if (max_zp <= 1) - printf(" ZP -\n"); + fprintf(fp, " ZP -\n"); else { start = ram_base; stop = ram_base + (max_zp - 1); - printf(" ZP $%04X-$%04X [%4i] %4i/%4i\n", start, stop, stop - start + 1, stop - start + 1, 256 - (stop - start + 1)); + fprintf(fp, " ZP $%04X-$%04X [%4i] %4i / %4i\n", start, stop, stop - start + 1, stop - start + 1, 256 - (stop - start + 1)); } /* bss usage */ if (max_bss <= 0x201) - printf(" BSS -\n\n"); + fprintf(fp, " BSS -\n\n"); else { start = ram_base + 0x200; stop = ram_base + (max_bss - 1); - printf(" BSS $%04X-$%04X [%4i] %4i/%4i\n\n", start, stop, stop - start + 1, stop - start + 1, 8192 - (stop - start + 1)); + fprintf(fp, " BSS $%04X-$%04X [%4i] %4i / %4i\n\n", start, stop, stop - start + 1, stop - start + 1, 8192 - (stop - start + 1)); } /* bank usage */ @@ -1095,13 +1255,13 @@ show_seg_usage(void) /* scan banks */ for (i = 0; i <= max_bank; i++) { - show_bnk_usage(i); + show_bank_usage(fp, i); } /* total */ rom_used = (rom_used + 1023) >> 10; rom_free = (rom_free) >> 10; - printf("\t\t\t\t ---- ----\n"); - printf("\t\t\t\t %4iK%4iK\n", rom_used, rom_free); - printf("\n\t\t\tTOTAL SIZE = %4iK\n\n", (rom_used + rom_free)); + fprintf(fp, "%36c ----- -----\n", ' '); + fprintf(fp, "%36c %4iK %4iK\n", ' ', rom_used, rom_free); + fprintf(fp, "\n%24c TOTAL SIZE = %4iK\n\n", ' ', (rom_used + rom_free)); } diff --git a/src/mkit/as/map.c b/src/mkit/as/map.c index 51113ce4..9769e1d3 100644 --- a/src/mkit/as/map.c +++ b/src/mkit/as/map.c @@ -30,7 +30,7 @@ pce_load_map(char *fname, int mode) /* open the file */ if ((fp = open_file(fname, "rb")) == NULL) { - fatal_error("Can not open file!"); + fatal_error("Unable to open file!"); return (1); } @@ -44,13 +44,13 @@ pce_load_map(char *fname, int mode) if (memcmp(header, "FORM", 4) || memcmp(&header[8], "FMAP", 4)) { /* incorrect header - load it as pure binary data */ if (mode) - fatal_error("Invalid FMP format!"); + fatal_error("Invalid .FMP file format!"); fclose(fp); return (mode); } /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -77,7 +77,7 @@ pce_load_map(char *fname, int mode) /* read a block */ nb = (size > sizeof(buffer)) ? sizeof(buffer) : size; if (fread(buffer, 1, nb, fp) != nb) { - error("FMP map data missing, file is too short!"); + error(".FMP file map data missing, file is too short!"); fclose(fp); return (0); } @@ -154,7 +154,7 @@ pce_load_stm(char *fname, int mode) /* open the file */ if ((fp = open_file(fname, "rb")) == NULL) { - fatal_error("Can not open file!"); + fatal_error("Unable to open file!"); return (1); } @@ -163,13 +163,13 @@ pce_load_stm(char *fname, int mode) if (memcmp(header, "STMP", 4)) { /* incorrect header - load it as pure binary data */ if (mode) - fatal_error("Invalid STM format!"); + fatal_error("Invalid .STM file format!"); fclose(fp); return (mode); } /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -179,7 +179,7 @@ pce_load_stm(char *fname, int mode) w = (header[5] << 8) + header[4]; h = (header[7] << 8) + header[6]; if ((w > 256) || (h > 256)) { - error("STM map size too big, max. 256x256!"); + error(".STM file map size too big, max. 256x256!"); fclose(fp); return (0); } @@ -193,7 +193,7 @@ pce_load_stm(char *fname, int mode) /* read a block */ nb = (size > sizeof(buffer)) ? sizeof(buffer) : size; if (fread(buffer, 1, nb, fp) != nb) { - error("STM map data missing, file is too short!"); + error(".STM file map data missing, file is too short!"); fclose(fp); return (0); } diff --git a/src/mkit/as/msbuild/pceas.sln b/src/mkit/as/msbuild/pceas.sln new file mode 100644 index 00000000..d36cab89 --- /dev/null +++ b/src/mkit/as/msbuild/pceas.sln @@ -0,0 +1,31 @@ +īģŋ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.34601.136 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pceas", "pceas.vcxproj", "{1B00A553-793C-42DF-A1BC-EC94B0A7D620}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Debug|Win32.ActiveCfg = Debug|Win32 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Debug|Win32.Build.0 = Debug|Win32 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Debug|x64.ActiveCfg = Debug|x64 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Debug|x64.Build.0 = Debug|x64 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Release|Win32.ActiveCfg = Release|Win32 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Release|Win32.Build.0 = Release|Win32 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Release|x64.ActiveCfg = Release|x64 + {1B00A553-793C-42DF-A1BC-EC94B0A7D620}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F2A41858-D10D-4EB3-8626-4FB50CCA00A1} + EndGlobalSection +EndGlobal diff --git a/src/mkit/as/msbuild/pceas.vcxproj b/src/mkit/as/msbuild/pceas.vcxproj new file mode 100644 index 00000000..4897d8f2 --- /dev/null +++ b/src/mkit/as/msbuild/pceas.vcxproj @@ -0,0 +1,325 @@ +īģŋ + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1B00A553-793C-42DF-A1BC-EC94B0A7D620} + 10.0 + + + + Application + false + NotSet + v142 + false + + + Application + false + NotSet + v142 + false + + + Application + false + NotSet + v142 + true + + + Application + false + NotSet + v142 + true + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + ..\..\..\..\bin\ + ..\..\..\..\bin\ + ..\..\..\..\bin\ + ..\..\..\..\bin\ + .x86\$(Configuration)\ + .x86\$(Configuration)\ + .x64\$(Configuration)\ + .x64\$(Configuration)\ + false + false + false + false + + + + pceas.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\pngread;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;NO_GZCOMPRESS;Z_SOLO;NO_GZIP;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)pceas.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + true + stdcpp17 + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)pceas.pdb + Console + false + + + MachineX86 + + + true + pceas.bsc + + + + + pceas.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\pngread;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;NO_GZCOMPRESS;Z_SOLO;NO_GZIP;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)pceas.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + true + stdcpp17 + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)pceas.pdb + Console + false + + + + + true + pceas.bsc + + + + + pceas.tlb + + + + + Disabled + ..\pngread;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;NO_GZCOMPRESS;Z_SOLO;NO_GZIP;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)pceas.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + true + stdcpp17 + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + true + $(OutDir)pceas.pdb + Console + false + + + MachineX86 + + + true + pceas.bsc + + + + + pceas.tlb + + + + + Disabled + ..\pngread;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;WIN32;_CONSOLE;PC;_CRT_SECURE_NO_WARNINGS;NO_GZCOMPRESS;Z_SOLO;NO_GZIP;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)pceas.pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + true + stdcpp17 + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + true + $(OutDir)pceas.pdb + Console + false + + + + + true + pceas.bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/mkit/as/msbuild/pceas.vcxproj.filters b/src/mkit/as/msbuild/pceas.vcxproj.filters new file mode 100644 index 00000000..400a08b4 --- /dev/null +++ b/src/mkit/as/msbuild/pceas.vcxproj.filters @@ -0,0 +1,139 @@ +īģŋ + + + + + + + + + + + + + + + + + + + + + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + + + + + + + + + + + + + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + pngread + + + + + {f724e509-7f12-4614-beaf-eca641c264e0} + + + \ No newline at end of file diff --git a/src/mkit/as/nes.c b/src/mkit/as/nes.c index 13adeabb..5ee292ec 100644 --- a/src/mkit/as/nes.c +++ b/src/mkit/as/nes.c @@ -112,7 +112,7 @@ nes_pack_8x8_tile(unsigned char *buffer, void *data, int line_offset, int format default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_8x8_tile'!"); + error("Unsupported format passed to 'pack_8x8_tile'!"); break; } @@ -135,7 +135,7 @@ nes_defchr(int *ip) int i; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -177,7 +177,7 @@ nes_inesprg(int *ip) return; if ((value < 0) || (value > 64)) { - error("Prg bank value out of range!"); + error("PRG bank value out of range!"); return; } @@ -203,7 +203,7 @@ nes_ineschr(int *ip) return; if ((value < 0) || (value > 64)) { - error("Prg bank value out of range!"); + error("PRG bank value out of range!"); return; } diff --git a/src/mkit/as/nes.h b/src/mkit/as/nes.h index 590e4098..91e0a266 100644 --- a/src/mkit/as/nes.h +++ b/src/mkit/as/nes.h @@ -26,7 +26,7 @@ struct t_opcode nes_pseudo[11] = { /* *INDENT-ON* */ const char defdirs_nes[] = -#ifdef WIN32 +#ifdef _WIN32 "c:\\huc\\include\\nes" #else "/usr/local/lib/huc/include/nes;" \ @@ -55,7 +55,7 @@ struct t_machine nes = { 0x800, /* ram_limit */ 0, /* ram_base */ 0, /* ram_page */ - RESERVED_BANK, /* ram_bank */ + UNDEFINED_BANK, /* ram_bank */ m6502_inst, /* base_inst */ undoc_inst, /* plus_inst */ nes_pseudo, /* pseudo_inst */ diff --git a/src/mkit/as/output.c b/src/mkit/as/output.c index 49bc312a..ace88f6d 100644 --- a/src/mkit/as/output.c +++ b/src/mkit/as/output.c @@ -1,3 +1,4 @@ +#include #include #include #include "defs.h" @@ -22,6 +23,8 @@ println(void) return; if (!xlist || !asm_opt[OPT_LIST] || (expand_macro && !asm_opt[OPT_MACRO])) return; + if (cloaking_stripped) + return; /* undo the pre-processor's modification to the line */ if (preproc_modidx != 0) { @@ -52,15 +55,15 @@ println(void) /* ok */ cnt = 0; for (i = 0; i < nb; i++) { -// if (bank == RESERVED_BANK || bank == STRIPPED_BANK) { +// if (bank == UNDEFINED_BANK || bank == STRIPPED_BANK) { if (bank > bank_limit) { - prlnbuf[16 + (3 * cnt)] = '-'; - prlnbuf[17 + (3 * cnt)] = '-'; + prlnbuf[18 + (3 * cnt)] = '-'; + prlnbuf[19 + (3 * cnt)] = '-'; } else { hexcon(2, rom[bank][data_loccnt]); - prlnbuf[16 + (3 * cnt)] = hex[1]; - prlnbuf[17 + (3 * cnt)] = hex[2]; + prlnbuf[18 + (3 * cnt)] = hex[1]; + prlnbuf[19 + (3 * cnt)] = hex[2]; } data_loccnt++; cnt++; @@ -113,22 +116,36 @@ loadlc(int offset, int pos) int i; if (pos) - i = 16; + i = 20; else i = 7; if (pos == 0) { - if (bank == RESERVED_BANK || bank == STRIPPED_BANK) { + if (bank == UNDEFINED_BANK || bank == STRIPPED_BANK) { + prlnbuf[i++] = ' '; + prlnbuf[i++] = ' '; prlnbuf[i++] = '-'; prlnbuf[i++] = '-'; } else { - hexcon(2, bank); - prlnbuf[i++] = hex[1]; - prlnbuf[i++] = hex[2]; + if ((section_flags[section] & S_IS_SF2) && (bank > 127)) { + hexcon(1, (bank / 64) - 1); + prlnbuf[i++] = hex[1]; + prlnbuf[i++] = ':'; + hexcon(2, (bank & 63) + 64); + prlnbuf[i++] = hex[1]; + prlnbuf[i++] = hex[2]; + + } else { + prlnbuf[i++] = ' '; + prlnbuf[i++] = ' '; + hexcon(2, bank); + prlnbuf[i++] = hex[1]; + prlnbuf[i++] = hex[2]; + } } prlnbuf[i++] = ':'; - offset += page << 13; + offset = (offset + (page << 13) + phase_offset) & 0xFFFF; } hexcon(4, offset); prlnbuf[i++] = hex[1]; @@ -167,7 +184,7 @@ putbyte(int offset, int data) { int addr; - if (bank >= RESERVED_BANK) + if (((section_flags[section] & S_IS_ROM) == 0) || (bank > bank_limit)) return; addr = offset + 1 + (bank << 13); @@ -208,7 +225,7 @@ putword(int offset, int data) { int addr; - if (bank >= RESERVED_BANK) + if (((section_flags[section] & S_IS_ROM) == 0) || (bank > bank_limit)) return; addr = offset + 2 + (bank << 13); @@ -251,7 +268,7 @@ putdword(int offset, int data) { int addr; - if (bank >= RESERVED_BANK) + if (((section_flags[section] & S_IS_ROM) == 0) || (bank > bank_limit)) return; addr = offset + 4 + (bank << 13); @@ -304,15 +321,7 @@ putbuffer(void *data, int size) return; /* check if the buffer will fit in the rom */ - if (bank >= RESERVED_BANK) { - addr = loccnt + size; - - if (addr > 0x2000) { - fatal_error("PROC overflow!"); - return; - } - } - else { + if ((section_flags[section] & S_IS_ROM) && (bank <= bank_limit)) { addr = (bank << 13) + loccnt; if ((addr + size) > rom_limit) { @@ -343,6 +352,11 @@ putbuffer(void *data, int size) } } } + } else { + if ((loccnt + size) > section_limit[section]) { + fatal_error("Too large to fit in the current section!"); + return; + } } /* update the location counter */ @@ -361,7 +375,7 @@ putbuffer(void *data, int size) } /* update rom size */ - if (bank < RESERVED_BANK) { + if ((section_flags[section] & S_IS_ROM) && (bank < UNDEFINED_BANK)) { if (bank > max_bank) { if (loccnt) max_bank = bank; @@ -387,9 +401,9 @@ write_srec(char *file, char *ext, int base) /* status message */ if (!strcmp(ext, "mx")) - printf("writing mx file... "); + printf("Writing .MX file... "); else - printf("writing s-record file... "); + printf("Writing S-record file... "); /* flush output */ fflush(stdout); @@ -401,7 +415,7 @@ write_srec(char *file, char *ext, int base) /* open the file */ if ((fp = fopen(fname, "w")) == NULL) { - printf("can not open file '%s'!\n", fname); + fprintf(ERROUT, "Error: Cannot open file \"%s\"!\n", fname); return; } @@ -467,41 +481,13 @@ write_srec(char *file, char *ext, int base) /* ---- - * fatal_error() + * vmessage() * ---- - * stop compilation + * display the current source line and a message */ -void -fatal_error(char *stptr) -{ - error(stptr); - stop_pass = 1; -} - - -/* ---- - * error() - * ---- - * error printing routine - */ - -void -error(char *stptr) -{ - warning(stptr); - errcnt++; -} - - -/* ---- - * warning() - * ---- - * warning printing routine - */ - -void -warning(char *stptr) +static void +vmessage(const char *msgtype, const char *format, va_list args) { int i, temp; @@ -516,7 +502,7 @@ warning(char *stptr) /* update the current file name */ if (infile_error != infile_num) { infile_error = infile_num; - printf("#[%i] %s\n", infile_num, input_file[infile_num].name); + fprintf(ERROUT, "#[%i] \"%s\"\n", infile_num, input_file[infile_num].file->name); } /* undo the pre-processor's modification to the line */ @@ -526,8 +512,9 @@ warning(char *stptr) /* output the line and the error message */ loadlc(loccnt, 0); - printf("%s\n", prlnbuf); - printf(" %s\n", stptr); + fprintf(ERROUT, "%s\n %s", prlnbuf, msgtype); + vfprintf(ERROUT, format, args); + fprintf(ERROUT, "\n"); /* redo the pre-processor's modification to the line */ if (preproc_modidx != 0) { @@ -535,3 +522,56 @@ warning(char *stptr) } } + +/* ---- + * fatal_error() + * ---- + * stop compilation + */ + +void +fatal_error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + vmessage("Error: ", format, args); + va_end(args); + errcnt++; + stop_pass = 1; +} + + +/* ---- + * error() + * ---- + * error printing routine + */ + +void +error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + vmessage("Error: ", format, args); + va_end(args); + errcnt++; +} + + +/* ---- + * warning() + * ---- + * warning printing routine + */ + +void +warning(const char *format, ...) +{ + va_list args; + + va_start(args, format); + vmessage("Warning: ", format, args); + va_end(args); +} diff --git a/src/mkit/as/pce.c b/src/mkit/as/pce.c index d7081ef8..7e0f7f31 100644 --- a/src/mkit/as/pce.c +++ b/src/mkit/as/pce.c @@ -162,7 +162,7 @@ pce_pack_8x8_tile(unsigned char *buffer, void *data, int line_offset, int format default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_8x8_tile'!"); + error("Unsupported format passed to 'pack_8x8_tile'!"); break; } @@ -223,7 +223,7 @@ pce_pack_16x16_tile(unsigned char *buffer, void *data, int line_offset, int form default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_16x16_tile'!"); + error("Unsupported format passed to 'pack_16x16_tile'!"); break; } @@ -321,7 +321,7 @@ pce_pack_16x16_sprite(unsigned char *buffer, void *data, int line_offset, int fo default: /* other formats not supported */ - error("Internal error: unsupported format passed to 'pack_16x16_sprite'!"); + error("Unsupported format passed to 'pack_16x16_sprite'!"); break; } @@ -340,7 +340,7 @@ void pce_vram(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* check if there's a label */ if (lastlabl == NULL) { @@ -375,7 +375,7 @@ void pce_pal(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* check if there's a label */ if (lastlabl == NULL) { @@ -420,7 +420,7 @@ pce_defchr(int *ip) /* check if there's a label */ if (lablptr) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* get the VRAM address */ if (!evaluate(ip, ',', 0)) @@ -477,7 +477,7 @@ pce_defpal(int *ip) char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output infos */ data_loccnt = loccnt; @@ -542,7 +542,7 @@ pce_defspr(int *ip) /* check if there's a label */ if (lablptr) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* get the VRAM address */ if (!evaluate(ip, ',', 0)) @@ -600,7 +600,7 @@ pce_incbat(int *ip) unsigned int temp; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -668,7 +668,7 @@ pce_incpal(int *ip) int r, g, b; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -727,13 +727,13 @@ pce_incpal(int *ip) void pce_incspr(int *ip) { - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int sx, sy; + int sx, sy; int nb_sprite = 0; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -805,13 +805,13 @@ pce_incspr(int *ip) void pce_inctile(int *ip) { - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int tx, ty; + int tx, ty; int nb_tile = 0; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -888,13 +888,13 @@ pce_inctile(int *ip) void pce_incchrpal(int *ip) { - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int tx, ty; + int tx, ty; int nb_chr = 0; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -903,7 +903,7 @@ pce_incchrpal(int *ip) /* get args */ if (!pcx_get_args(ip)) return; - if (!pcx_parse_args(0, pcx_nb_args, &x, &y, &w, &h, 16)) + if (!pcx_parse_args(0, pcx_nb_args, &x, &y, &w, &h, 8)) return; /* scan tiles */ @@ -915,7 +915,6 @@ pce_incchrpal(int *ip) /* get chr palette */ buffer[0] = pce_scan_8x8_tile(tx, ty) << 4; - /* store palette number */ putbuffer(buffer, 1); nb_chr++; @@ -958,13 +957,13 @@ pce_incchrpal(int *ip) void pce_incsprpal(int *ip) { - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int tx, ty; + int tx, ty; int nb_sprite = 0; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1028,13 +1027,13 @@ pce_incsprpal(int *ip) void pce_inctilepal(int *ip) { - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int tx, ty; + int tx, ty; int nb_tile = 0; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1117,14 +1116,14 @@ pce_inctilepal(int *ip) void pce_incmap(int *ip) { - unsigned int i, j; + int i, j; int x, y, w, h; - unsigned int tx, ty; + int tx, ty; int tile; int err = 0; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1184,11 +1183,11 @@ void pce_mml(int *ip) { int offset, bufsize, size; - char mml[128]; + char mml[PATHSZ]; char c; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* output */ if (pass == LAST_PASS) @@ -1202,7 +1201,7 @@ pce_mml(int *ip) /* extract and parse mml string(s) */ for (;;) { /* get string */ - if (!getstring(ip, mml, 127)) + if (!getstring(ip, mml, PATHSZ - 1)) return; /* parse string */ diff --git a/src/mkit/as/pce.h b/src/mkit/as/pce.h index 6e0db35a..83b0a4c1 100644 --- a/src/mkit/as/pce.h +++ b/src/mkit/as/pce.h @@ -105,7 +105,7 @@ struct t_opcode pce_pseudo[29] = { /* *INDENT-ON* */ const char defdirs_pce[] = -#ifdef WIN32 +#ifdef _WIN32 "c:\\huc\\include\\huc" #else "/usr/local/lib/huc/include/huc;" \ diff --git a/src/mkit/as/pcx.c b/src/mkit/as/pcx.c index d71b5a62..0f7f471a 100644 --- a/src/mkit/as/pcx.c +++ b/src/mkit/as/pcx.c @@ -155,7 +155,13 @@ pcx_set_tile(struct t_symbol *ref, unsigned int offset) /* get infos */ nb = ref->nb - (start / ref->size); size = ref->size; - data = &rom[ref->bank - bank_base][ref->value & 0x1FFF] + start; + + if (((section_flags[ref->section] & S_IS_ROM) == 0) || (ref->rombank > bank_limit)) { +// if (((section_flags[ref->section] & S_IS_ROM) == 0) || (ref->mprbank >= UNDEFINED_BANK)) { + goto err; + } + + data = &rom[ref->rombank][ref->value & 0x1FFF] + start; /* 256 tiles max */ if (nb > 256) @@ -239,11 +245,11 @@ pcx_search_tile(unsigned char *data, int size) int pcx_get_args(int *ip) { - char name[128]; + char name[PATHSZ]; char c; /* get pcx file name */ - if (!getstring(ip, name, 127)) + if (!getstring(ip, name, PATHSZ - 1)) return (0); /* reset args counter */ @@ -390,7 +396,7 @@ pcx_load(char *name) /* open the file */ if ((f = open_file(name, "rb")) == NULL) { - error("Can not open file!"); + fatal_error("Unable to open file!"); return (0); } @@ -416,7 +422,7 @@ pcx_load(char *name) /* malloc a buffer */ pcx_buf = malloc((size_t)pcx_w * pcx_h); if (pcx_buf == NULL) { - error("Can not load file, not enough memory!"); + error("Cannot load file, not enough memory!"); return (0); } @@ -426,7 +432,7 @@ pcx_load(char *name) else if ((pcx.bpp == 1) && (pcx.np <= 4)) decode_16(f, pcx_w, pcx_h); else { - error("Unsupported or invalid PCX format!"); + error("Unsupported or invalid .PCX file format!"); return (0); } @@ -445,7 +451,7 @@ pcx_load(char *name) void decode_256(FILE *f, int w, int h) { - unsigned int i, c, x, y; + int i, c, x, y; unsigned char *ptr; ptr = pcx_buf; @@ -484,7 +490,7 @@ decode_256(FILE *f, int w, int h) break; default: - error("Unsupported PCX encoding scheme!"); + error("Unsupported .PCX file encoding scheme!"); return; } @@ -524,7 +530,7 @@ decode_16(FILE *f, int w, int h) switch (pcx.encoding) { case 0: /* raw */ - error("Unsupported PCX encoding scheme!"); + error("Unsupported .PCX file encoding scheme!"); break; case 1: @@ -592,7 +598,7 @@ decode_16(FILE *f, int w, int h) break; default: - error("Unsupported PCX encoding scheme!"); + error("Unsupported .PCX file encoding scheme!"); return; } @@ -629,7 +635,7 @@ int bmp_load(char *name) { BMPHeader_t header; - int i; + unsigned int i; FILE * pFile = NULL; /* no it's a new file - ok let's prepare loading */ if (pcx_buf) @@ -639,7 +645,7 @@ bmp_load(char *name) /* open the file */ if ((pFile = open_file(name, "rb")) == NULL) { - error("Can not open file!"); + fatal_error("Unable to open file!"); goto errorCleanup; } @@ -662,7 +668,7 @@ bmp_load(char *name) /* malloc a buffer */ pcx_buf = malloc((size_t)pcx_w * pcx_h); if (pcx_buf == NULL) { - error("Can not load file, not enough memory!"); + error("Cannot load file, not enough memory!"); goto errorCleanup; } for (i=0;ibitmapDataOffset]; fseek(pFile,header.bitmapDataOffset,SEEK_SET); - for (uint32_t y=0;y for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. */ /* @(#) $Id$ */ @@ -14,11 +12,12 @@ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + MAKECRCH can be #defined to write out crc32.h. A main() routine is also + produced, so that this one source file can be compiled to an executable. */ #ifdef MAKECRCH @@ -28,415 +27,1023 @@ # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ -#include "zutil.h" /* for STDC and FAR definitions */ +#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ -/* Definitions for doing the crc four data bytes at a time. */ -#if !defined(NOBYFOUR) && defined(Z_U4) -# define BYFOUR + /* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32.h would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. + */ + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 #endif -#ifdef BYFOUR - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, z_size_t)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, z_size_t)); -# define TBLS 8 + +/* + z_crc_t must be at least 32 bits. z_word_t must be at least as long as + z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and + that bytes are eight bits. + */ + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif #else -# define TBLS 1 -#endif /* BYFOUR */ +# ifdef MAKECRCH +# define W 8 /* required for MAKECRCH */ +# else +# if defined(__x86_64__) || defined(__aarch64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 && defined(Z_U8) + typedef Z_U8 z_word_t; +# elif defined(Z_U4) +# undef W +# define W 4 + typedef Z_U4 z_word_t; +# else +# undef W +# endif +#endif -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); +/* If available, use the ARM processor CRC32 instruction. */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 +# define ARMCRC32 +#endif +#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) +/* + Swap the bytes in a z_word_t to convert between little and big endian. Any + self-respecting compiler will optimize this to a single machine byte-swap + instruction, if one is available. This assumes that word_t is either 32 bits + or 64 bits. + */ +local z_word_t byte_swap(z_word_t word) { +# if W == 8 + return + (word & 0xff00000000000000) >> 56 | + (word & 0xff000000000000) >> 40 | + (word & 0xff0000000000) >> 24 | + (word & 0xff00000000) >> 8 | + (word & 0xff000000) << 8 | + (word & 0xff0000) << 24 | + (word & 0xff00) << 40 | + (word & 0xff) << 56; +# else /* W == 4 */ + return + (word & 0xff000000) >> 24 | + (word & 0xff0000) >> 8 | + (word & 0xff00) << 8 | + (word & 0xff) << 24; +# endif +} +#endif #ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ -local volatile int crc_table_empty = 1; -local z_crc_t FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ +local z_crc_t FAR crc_table[256]; +#ifdef W + local z_word_t FAR crc_big_table[256]; + local z_crc_t FAR crc_braid_table[W][256]; + local z_word_t FAR crc_braid_big_table[W][256]; + local void braid(z_crc_t [][256], z_word_t [][256], int, int); +#endif #ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *)); + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); #endif /* MAKECRCH */ + +/* + Define a once() function depending on the availability of atomics. If this is + compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in + multiple threads, and if atomics are not available, then get_crc_table() must + be called to initialize the tables and must return before any threads are + allowed to compute or combine CRCs. + */ + +/* Definition of once functionality. */ +typedef struct once_s once_t; + +/* Check for the availability of atomics. */ +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ + !defined(__STDC_NO_ATOMICS__) + +#include + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + atomic_flag begun; + atomic_int done; +}; +#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} + +/* + Run the provided init() function exactly once, even if multiple threads + invoke once() at the same time. The state must be a once_t initialized with + ONCE_INIT. + */ +local void once(once_t *state, void (*init)(void)) { + if (!atomic_load(&state->done)) { + if (atomic_flag_test_and_set(&state->begun)) + while (!atomic_load(&state->done)) + ; + else { + init(); + atomic_store(&state->done, 1); + } + } +} + +#else /* no atomics */ + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + volatile int begun; + volatile int done; +}; +#define ONCE_INIT {0, 0} + +/* Test and set. Alas, not atomic, but tries to minimize the period of + vulnerability. */ +local int test_and_set(int volatile *flag) { + int was; + + was = *flag; + *flag = 1; + return was; +} + +/* Run the provided init() function once. This is not thread-safe. */ +local void once(once_t *state, void (*init)(void)) { + if (!state->done) { + if (test_and_set(&state->begun)) + while (!state->done) + ; + else { + init(); + state->done = 1; + } + } +} + +#endif + +/* State for once(). */ +local once_t made = ONCE_INIT; + /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials + with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the + one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each + taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - z_crc_t c; - int n, k; - z_crc_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (z_crc_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (z_crc_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } -#endif /* BYFOUR */ + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. + */ - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; +local void make_crc_table(void) { + unsigned i, j, n; + z_crc_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; +#ifdef W + crc_big_table[i] = byte_swap(p); +#endif } + /* initialize the x^2^n mod p(x) table */ + p = (z_crc_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + +#ifdef W + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +#endif + #ifdef MAKECRCH - /* write out CRC tables to crc32.h */ { + /* + The crc32.h header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. + */ +#if !defined(W) || W != 8 +# error Need a 64-bit integer type in order to generate crc32.h. +#endif FILE *out; + int k, n; + z_crc_t ltl[8][256]; + z_word_t big[8][256]; out = fopen("crc32.h", "w"); if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const z_crc_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); + + /* write out little-endian CRC table to crc32.h */ + fprintf(out, + "/* crc32.h -- tables for rapid CRC calculation\n" + " * Generated automatically by crc32.c\n */\n" + "\n" + "local const z_crc_t FAR crc_table[] = {\n" + " "); + write_table(out, crc_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#ifdef W\n" + "\n" + "#if W == 8\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table64(out, crc_big_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table32hi(out, crc_big_table, 256); + fprintf(out, + "};\n" + "\n" + "#endif\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + fprintf(out, + "\n" + "#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#if W == 8\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table64(out, big[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table32hi(out, big[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "#endif\n" + "\n" + "#endif\n"); } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); + fprintf(out, + "\n" + "#endif\n"); + + /* write out zeros operator table to crc32.h */ + fprintf(out, + "\n" + "local const z_crc_t FAR x2n_table[] = {\n" + " "); + write_table(out, x2n_table, 32); + fprintf(out, + "};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const z_crc_t FAR *table; -{ + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { int n; - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", + (unsigned long long)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +/* Actually do the deed. */ +int main(void) { + make_crc_table(); + return 0; } + #endif /* MAKECRCH */ -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). +#ifdef W +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. */ -#include "crc32.h" +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + z_crc_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp((n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = byte_swap(q); + } + } +} +#endif + #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= - * This function can be used by asm versions of crc32() + * This function can be used by asm versions of crc32(), and to force the + * generation of the CRC tables in a threaded application. */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { #ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); + once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ return (const z_crc_t FAR *)crc_table; } -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 +/* ========================================================================= + * Use ARM machine instructions if available. This will compute the CRC about + * ten times faster than the braided calculation. This code does not check for + * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will + * only be defined if the compilation specifies an ARM processor architecture + * that has the instructions. For example, compiling with -march=armv8.1-a or + * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 + * instructions. + */ +#ifdef ARMCRC32 -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - if (buf == Z_NULL) return 0UL; +/* + Constants empirically determined to maximize speed. These values are from + measurements on a Cortex-A57. Your mileage may vary. + */ +#define Z_BATCH 3990 /* number of words in a batch */ +#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ +#define Z_BATCH_MIN 800 /* fewest words in a final batch */ + +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + z_crc_t val; + z_word_t crc1, crc2; + const z_word_t *word; + z_word_t val0, val1, val2; + z_size_t last, last2, i; + z_size_t num; + + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; #ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); + once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - z_crc_t endian; + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); + /* Compute the CRC up to a word boundary. */ + while (len && ((z_size_t)buf & 7) != 0) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; + + /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ + word = (z_word_t const *)buf; + num = len >> 3; + len &= 7; + + /* Do three interleaved CRCs to realize the throughput of one crc32x + instruction per cycle. Each CRC is calculated on Z_BATCH words. The + three CRCs are combined into a single CRC after each set of batches. */ + while (num >= 3 * Z_BATCH) { + crc1 = 0; + crc2 = 0; + for (i = 0; i < Z_BATCH; i++) { + val0 = word[i]; + val1 = word[i + Z_BATCH]; + val2 = word[i + 2 * Z_BATCH]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * Z_BATCH; + num -= 3 * Z_BATCH; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - return crc32_z(crc, buf, len); + /* Do one last smaller batch with the remaining words, if there are enough + to pay for the combination of CRCs. */ + last = num / 3; + if (last >= Z_BATCH_MIN) { + last2 = last << 1; + crc1 = 0; + crc2 = 0; + for (i = 0; i < last; i++) { + val0 = word[i]; + val1 = word[i + last]; + val2 = word[i + last2]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * last; + num -= 3 * last; + val = x2nmodp(last, 6); + crc = multmodp(val, crc) ^ crc1; + crc = multmodp(val, crc) ^ crc2; + } + + /* Compute the CRC on any remaining words. */ + for (i = 0; i < num; i++) { + val0 = word[i]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + } + word += num; + + /* Complete the CRC on any remaining bytes. */ + buf = (const unsigned char FAR *)word; + while (len) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; } -#ifdef BYFOUR +#else + +#ifdef W /* - This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit - integer pointer type. This violates the strict aliasing rule, where a - compiler can assume, for optimization purposes, that two pointers to - fundamentally different types won't ever point to the same memory. This can - manifest as a problem only if one of the pointers is written to. This code - only reads from those pointers. So long as this code remains isolated in - this compilation unit, there won't be a problem. For this reason, this code - should not be copied and pasted into a compilation unit in which other code - writes to the buffer that is passed to these routines. + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. */ +local z_crc_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (z_crc_t)data; +} -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 +local z_word_t crc_word_big(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} + +#endif /* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; -/* ========================================================================= */ -#define DOBIG4 c ^= *buf4++; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 +#ifdef W -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + z_size_t blks; + z_word_t const *words; + unsigned endian; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((z_size_t)buf & (W - 1)) != 0) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + /* Do endian check at execution time instead of compile time, since ARM + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the + check and the unused branch. */ + endian = 1; + if (*(unsigned char *)&endian) { + /* Little endian. */ + + z_crc_t crc0; + z_word_t word0; +#if N > 1 + z_crc_t crc1; + z_word_t word1; +#if N > 2 + z_crc_t crc2; + z_word_t word2; +#if N > 3 + z_crc_t crc3; + z_word_t word3; +#if N > 4 + z_crc_t crc4; + z_word_t word4; +#if N > 5 + z_crc_t crc5; + z_word_t word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = crc; +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + crc = crc_word(crc0 ^ words[0]); +#if N > 1 + crc = crc_word(crc1 ^ words[1] ^ crc); +#if N > 2 + crc = crc_word(crc2 ^ words[2] ^ crc); +#if N > 3 + crc = crc_word(crc3 ^ words[3] ^ crc); +#if N > 4 + crc = crc_word(crc4 ^ words[4] ^ crc); +#if N > 5 + crc = crc_word(crc5 ^ words[5] ^ crc); +#endif +#endif +#endif +#endif +#endif + words += N; + } + else { + /* Big endian. */ + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = byte_swap(crc); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_big_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_big_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_big_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_big_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_big_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_big_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + comb = crc_word_big(crc0 ^ words[0]); +#if N > 1 + comb = crc_word_big(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word_big(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word_big(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word_big(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word_big(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + crc = byte_swap(comb); + } + + /* + Update the pointer to the remaining bytes to process. + */ + buf = (unsigned char const *)words; } - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOBIG32; - len -= 32; +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; } - while (len >= 4) { - DOBIG4; - len -= 4; + while (len) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; } - buf = (const unsigned char FAR *)buf4; - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(ZSWAP32(c)); + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; } -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ +#endif /* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { + return crc32_z(crc, buf, len); } /* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); } /* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { + return crc32_combine64(crc1, crc2, (z_off64_t)len2); +} - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return x2nmodp(len2, 3); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { + return crc32_combine_gen64((z_off64_t)len2); } -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { + return multmodp(op, crc1) ^ (crc2 & 0xffffffff); } diff --git a/src/mkit/as/pngread/crc32.h b/src/mkit/as/pngread/crc32.h index 9e0c7781..137df68d 100644 --- a/src/mkit/as/pngread/crc32.h +++ b/src/mkit/as/pngread/crc32.h @@ -2,440 +2,9445 @@ * Generated automatically by crc32.c */ -local const z_crc_t FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL +local const z_crc_t FAR crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +local const z_word_t FAR crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +local const z_word_t FAR crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#if N == 1 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif + +#endif + +#if N == 2 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + #endif - } -}; + +#endif + +#if N == 3 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif + +#endif + +#if N == 4 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif + +#endif + +#if N == 5 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif + +#endif + +#if N == 6 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif + +#endif + +#endif + +local const z_crc_t FAR x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; diff --git a/src/mkit/as/pngread/inffast.c b/src/mkit/as/pngread/inffast.c index 0dbd1dbc..9354676e 100644 --- a/src/mkit/as/pngread/inffast.c +++ b/src/mkit/as/pngread/inffast.c @@ -47,10 +47,7 @@ requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { struct inflate_state FAR *state; z_const unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *last; /* have enough input while in < last */ @@ -70,7 +67,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ + code const *here; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ @@ -107,20 +104,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold += (unsigned long)(*in++) << bits; bits += 8; } - here = lcode[hold & lmask]; + here = lcode + (hold & lmask); dolen: - op = (unsigned)(here.bits); + op = (unsigned)(here->bits); hold >>= op; bits -= op; - op = (unsigned)(here.op); + op = (unsigned)(here->op); if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - *out++ = (unsigned char)(here.val); + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); } else if (op & 16) { /* length base */ - len = (unsigned)(here.val); + len = (unsigned)(here->val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { @@ -138,14 +135,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ hold += (unsigned long)(*in++) << bits; bits += 8; } - here = dcode[hold & dmask]; + here = dcode + (hold & dmask); dodist: - op = (unsigned)(here.bits); + op = (unsigned)(here->bits); hold >>= op; bits -= op; - op = (unsigned)(here.op); + op = (unsigned)(here->op); if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); + dist = (unsigned)(here->val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(*in++) << bits; @@ -264,7 +261,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; + here = dcode + here->val + (hold & ((1U << op) - 1)); goto dodist; } else { @@ -274,7 +271,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; + here = lcode + here->val + (hold & ((1U << op) - 1)); goto dolen; } else if (op & 32) { /* end-of-block */ diff --git a/src/mkit/as/pngread/inffast.h b/src/mkit/as/pngread/inffast.h index e5c1aa4c..49c6d156 100644 --- a/src/mkit/as/pngread/inffast.h +++ b/src/mkit/as/pngread/inffast.h @@ -8,4 +8,4 @@ subject to change. Applications should only use zlib.h. */ -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/src/mkit/as/pngread/inflate.c b/src/mkit/as/pngread/inflate.c index ac333e8c..94ecff01 100644 --- a/src/mkit/as/pngread/inflate.c +++ b/src/mkit/as/pngread/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2016 Mark Adler + * Copyright (C) 1995-2022 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -91,20 +91,7 @@ # endif #endif -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ +local int inflateStateCheck(z_streamp strm) { struct inflate_state FAR *state; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -116,9 +103,7 @@ z_streamp strm; return 0; } -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ +int ZEXPORT inflateResetKeep(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -130,6 +115,7 @@ z_streamp strm; state->mode = HEAD; state->last = 0; state->havedict = 0; + state->flags = -1; state->dmax = 32768U; state->head = Z_NULL; state->hold = 0; @@ -141,9 +127,7 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ +int ZEXPORT inflateReset(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -154,10 +138,7 @@ z_streamp strm; return inflateResetKeep(strm); } -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { int wrap; struct inflate_state FAR *state; @@ -167,6 +148,8 @@ int windowBits; /* extract wrap request from windowBits parameter */ if (windowBits < 0) { + if (windowBits < -15) + return Z_STREAM_ERROR; wrap = 0; windowBits = -windowBits; } @@ -192,12 +175,8 @@ int windowBits; return inflateReset(strm); } -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { int ret; struct inflate_state FAR *state; @@ -236,22 +215,17 @@ int stream_size; return ret; } -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; @@ -275,9 +249,7 @@ int value; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -339,7 +311,7 @@ struct inflate_state FAR *state; a.out > inffixed.h */ -void makefixed() +void makefixed(void) { unsigned low, size; struct inflate_state state; @@ -393,11 +365,7 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { struct inflate_state FAR *state; unsigned dist; @@ -447,10 +415,10 @@ unsigned copy; /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP -# define UPDATE(check, buf, len) \ +# define UPDATE_CHECK(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else -# define UPDATE(check, buf, len) adler32(check, buf, len) +# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ @@ -619,10 +587,7 @@ unsigned copy; will return Z_BUF_ERROR if it has not reached the end of the stream. */ -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ +int ZEXPORT inflate(z_streamp strm, int flush) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -670,7 +635,6 @@ int flush; state->mode = FLAGS; break; } - state->flags = 0; /* expect zlib header */ if (state->head != Z_NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ @@ -697,6 +661,7 @@ int flush; break; } state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; @@ -722,6 +687,7 @@ int flush; CRC2(state->check, hold); INITBITS(); state->mode = TIME; + /* fallthrough */ case TIME: NEEDBITS(32); if (state->head != Z_NULL) @@ -730,6 +696,7 @@ int flush; CRC4(state->check, hold); INITBITS(); state->mode = OS; + /* fallthrough */ case OS: NEEDBITS(16); if (state->head != Z_NULL) { @@ -740,6 +707,7 @@ int flush; CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; + /* fallthrough */ case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); @@ -753,14 +721,16 @@ int flush; else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; + /* fallthrough */ case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; + state->head->extra != Z_NULL && + (len = state->head->extra_len - state->length) < + state->head->extra_max) { zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); @@ -775,6 +745,7 @@ int flush; } state->length = 0; state->mode = NAME; + /* fallthrough */ case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; @@ -796,6 +767,7 @@ int flush; state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; + /* fallthrough */ case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; @@ -816,6 +788,7 @@ int flush; else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; + /* fallthrough */ case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); @@ -839,6 +812,7 @@ int flush; strm->adler = state->check = ZSWAP32(hold); INITBITS(); state->mode = DICT; + /* fallthrough */ case DICT: if (state->havedict == 0) { RESTORE(); @@ -846,8 +820,10 @@ int flush; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; + /* fallthrough */ case TYPE: if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + /* fallthrough */ case TYPEDO: if (state->last) { BYTEBITS(); @@ -898,8 +874,10 @@ int flush; INITBITS(); state->mode = COPY_; if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ case COPY_: state->mode = COPY; + /* fallthrough */ case COPY: copy = state->length; if (copy) { @@ -935,6 +913,7 @@ int flush; Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; + /* fallthrough */ case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); @@ -956,6 +935,7 @@ int flush; Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; + /* fallthrough */ case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { @@ -1039,8 +1019,10 @@ int flush; Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN_; if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ case LEN_: state->mode = LEN; + /* fallthrough */ case LEN: if (have >= 6 && left >= 258) { RESTORE(); @@ -1090,6 +1072,7 @@ int flush; } state->extra = (unsigned)(here.op) & 15; state->mode = LENEXT; + /* fallthrough */ case LENEXT: if (state->extra) { NEEDBITS(state->extra); @@ -1100,6 +1083,7 @@ int flush; Tracevv((stderr, "inflate: length %u\n", state->length)); state->was = state->length; state->mode = DIST; + /* fallthrough */ case DIST: for (;;) { here = state->distcode[BITS(state->distbits)]; @@ -1127,6 +1111,7 @@ int flush; state->offset = (unsigned)here.val; state->extra = (unsigned)(here.op) & 15; state->mode = DISTEXT; + /* fallthrough */ case DISTEXT: if (state->extra) { NEEDBITS(state->extra); @@ -1143,6 +1128,7 @@ int flush; #endif Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; + /* fallthrough */ case MATCH: if (left == 0) goto inf_leave; copy = out - left; @@ -1202,7 +1188,7 @@ int flush; state->total += out; if ((state->wrap & 4) && out) strm->adler = state->check = - UPDATE(state->check, put - out, out); + UPDATE_CHECK(state->check, put - out, out); out = left; if ((state->wrap & 4) && ( #ifdef GUNZIP @@ -1218,10 +1204,11 @@ int flush; } #ifdef GUNZIP state->mode = LENGTH; + /* fallthrough */ case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; @@ -1231,6 +1218,7 @@ int flush; } #endif state->mode = DONE; + /* fallthrough */ case DONE: ret = Z_STREAM_END; goto inf_leave; @@ -1240,6 +1228,7 @@ int flush; case MEM: return Z_MEM_ERROR; case SYNC: + /* fallthrough */ default: return Z_STREAM_ERROR; } @@ -1265,7 +1254,7 @@ int flush; state->total += out; if ((state->wrap & 4) && out) strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); + UPDATE_CHECK(state->check, strm->next_out - out, out); strm->data_type = (int)state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); @@ -1274,9 +1263,7 @@ int flush; return ret; } -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateEnd(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1288,11 +1275,8 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { struct inflate_state FAR *state; /* check state */ @@ -1311,11 +1295,8 @@ uInt *dictLength; return Z_OK; } -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { struct inflate_state FAR *state; unsigned long dictid; int ret; @@ -1346,10 +1327,7 @@ uInt dictLength; return Z_OK; } -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { struct inflate_state FAR *state; /* check state */ @@ -1374,11 +1352,8 @@ gz_headerp head; called again with more data and the *have state. *have is initialized to zero for the first call. */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { unsigned got; unsigned next; @@ -1397,10 +1372,9 @@ unsigned len; return next; } -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ +int ZEXPORT inflateSync(z_streamp strm) { unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; @@ -1413,7 +1387,7 @@ z_streamp strm; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { @@ -1433,9 +1407,15 @@ z_streamp strm; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; + state->flags = flags; state->mode = TYPE; return Z_OK; } @@ -1448,9 +1428,7 @@ z_streamp strm; block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ +int ZEXPORT inflateSyncPoint(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1458,10 +1436,7 @@ z_streamp strm; return state->mode == STORED && state->bits == 0; } -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; @@ -1505,10 +1480,7 @@ z_streamp source; return Z_OK; } -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1523,24 +1495,19 @@ int subvert; #endif } -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ +int ZEXPORT inflateValidate(z_streamp strm, int check) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; - if (check) + if (check && state->wrap) state->wrap |= 4; else state->wrap &= ~4; return Z_OK; } -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ +long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) @@ -1551,9 +1518,7 @@ z_streamp strm; (state->mode == MATCH ? state->was - state->length : 0)); } -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return (unsigned long)-1; state = (struct inflate_state FAR *)strm->state; diff --git a/src/mkit/as/pngread/inflate.h b/src/mkit/as/pngread/inflate.h index a46cce6b..f127b6b1 100644 --- a/src/mkit/as/pngread/inflate.h +++ b/src/mkit/as/pngread/inflate.h @@ -1,5 +1,5 @@ /* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2016 Mark Adler + * Copyright (C) 1995-2019 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -86,7 +86,8 @@ struct inflate_state { int wrap; /* bit 0 true for zlib, bit 1 true for gzip, bit 2 true to validate check value */ int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ diff --git a/src/mkit/as/pngread/inftrees.c b/src/mkit/as/pngread/inftrees.c index 2ea08fc1..98cfe164 100644 --- a/src/mkit/as/pngread/inftrees.c +++ b/src/mkit/as/pngread/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2017 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -29,14 +29,9 @@ const char inflate_copyright[] = table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ @@ -62,7 +57,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/src/mkit/as/pngread/inftrees.h b/src/mkit/as/pngread/inftrees.h index baa53a0b..396f74b5 100644 --- a/src/mkit/as/pngread/inftrees.h +++ b/src/mkit/as/pngread/inftrees.h @@ -38,11 +38,11 @@ typedef struct { /* Maximum size of the dynamic table. The maximum number of code structures is 1444, which is the sum of 852 for literal/length codes and 592 for distance codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that + examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ @@ -57,6 +57,6 @@ typedef enum { DISTS } codetype; -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/src/mkit/as/pngread/png.c b/src/mkit/as/pngread/png.c index 757c755f..9ed31570 100644 --- a/src/mkit/as/pngread/png.c +++ b/src/mkit/as/pngread/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -14,27 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37; - -#ifdef __GNUC__ -/* The version tests may need to be added to, but the problem warning has - * consistently been fixed in GCC versions which obtain wide-spread release. - * The problem is that many versions of GCC rearrange comparison expressions in - * the optimizer in such a way that the results of the comparison will change - * if signed integer overflow occurs. Such comparisons are not permitted in - * ANSI C90, however GCC isn't clever enough to work out that that do not occur - * below in png_ascii_from_fp and png_muldiv, so it produces a warning with - * -Wextra. Unfortunately this is highly dependent on the optimizer and the - * machine architecture so the warning comes and goes unpredictably and is - * impossible to "fix", even were that a good idea. - */ -#if __GNUC__ == 7 && __GNUC_MINOR__ == 1 -#define GCC_STRICT_OVERFLOW 1 -#endif /* GNU 7.1.x */ -#endif /* GNU */ -#ifndef GCC_STRICT_OVERFLOW -#define GCC_STRICT_OVERFLOW 0 -#endif +typedef png_libpng_version_1_6_43 Your_png_h_is_not_version_1_6_43; /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -73,21 +53,21 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes) int PNGAPI png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) { - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; if (num_to_check > 8) num_to_check = 8; else if (num_to_check < 1) - return (-1); + return -1; if (start > 7) - return (-1); + return -1; if (start + num_to_check > 8) num_to_check = 8 - start; - return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); + return memcmp(&sig[start], &png_signature[start], num_to_check); } #endif /* READ */ @@ -447,7 +427,6 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), memset(info_ptr, 0, (sizeof *info_ptr)); } -/* The following API is not called internally */ void PNGAPI png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, int freer, png_uint_32 mask) @@ -686,9 +665,9 @@ png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; - return (png_ptr->io_ptr); + return png_ptr->io_ptr; } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) @@ -720,7 +699,7 @@ png_init_io(png_structrp png_ptr, png_FILE_p fp) * * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the * negative integral value is added the result will be an unsigned value - * correspnding to the 2's complement representation. + * corresponding to the 2's complement representation. */ void PNGAPI png_save_int_32(png_bytep buf, png_int_32 i) @@ -752,7 +731,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) { size_t pos = 0; - char number_buf[5]; /* enough for a four-digit year */ + char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */ # define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) # define APPEND_NUMBER(format, value)\ @@ -815,8 +794,8 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.37" PNG_STRING_NEWLINE \ - "Copyright (c) 2018-2019 Cosmin Truta" PNG_STRING_NEWLINE \ + "libpng version 1.6.43" PNG_STRING_NEWLINE \ + "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ @@ -977,7 +956,7 @@ png_reset_zstream(png_structrp png_ptr) return Z_STREAM_ERROR; /* WARNING: this resets the window bits to the maximum! */ - return (inflateReset(&png_ptr->zstream)); + return inflateReset(&png_ptr->zstream); } #endif /* READ */ @@ -986,7 +965,7 @@ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ - return((png_uint_32)PNG_LIBPNG_VER); + return (png_uint_32)PNG_LIBPNG_VER; } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) @@ -1842,14 +1821,14 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, } # ifdef PNG_WARNINGS_SUPPORTED else - { - char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ + { + char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ - pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); - pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ - } + pos = png_safecat(message, (sizeof message), pos, + png_format_number(number, number+(sizeof number), + PNG_NUMBER_FORMAT_x, value)); + pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ + } # endif /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ pos = png_safecat(message, (sizeof message), pos, reason); @@ -2532,17 +2511,6 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) #endif /* COLORSPACE */ -#ifdef __GNUC__ -/* This exists solely to work round a warning from GNU C. */ -static int /* PRIVATE */ -png_gt(size_t a, size_t b) -{ - return a > b; -} -#else -# define png_gt(a,b) ((a) > (b)) -#endif - void /* PRIVATE */ png_check_IHDR(png_const_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, @@ -2564,8 +2532,16 @@ png_check_IHDR(png_const_structrp png_ptr, error = 1; } - if (png_gt(((width + 7) & (~7U)), - ((PNG_SIZE_MAX + /* The bit mask on the first line below must be at least as big as a + * png_uint_32. "~7U" is not adequate on 16-bit systems because it will + * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the + * type of the result at least as bit (in bits) as the RHS of the > operator + * which also avoids a common warning on 64-bit systems that the comparison + * of (png_uint_32) against the constant value on the RHS will always be + * false. + */ + if (((width + 7) & ~(png_alloc_size_t)7) > + (((PNG_SIZE_MAX - 48 /* big_row_buf hack */ - 1) /* filter byte */ / 8) /* 8-byte RGBA pixels */ @@ -2710,7 +2686,7 @@ png_check_IHDR(png_const_structrp png_ptr, int /* PRIVATE */ png_check_fp_number(png_const_charp string, size_t size, int *statep, - png_size_tp whereami) + size_t *whereami) { int state = *statep; size_t i = *whereami; @@ -2891,14 +2867,6 @@ png_pow10(int power) /* Function to format a floating point value in ASCII with a given * precision. */ -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic push -/* The problem arises below with exp_b10, which can never overflow because it - * comes, originally, from frexp and is therefore limited to a range which is - * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)). - */ -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ void /* PRIVATE */ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, double fp, unsigned int precision) @@ -3220,10 +3188,6 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, /* Here on buffer too small. */ png_error(png_ptr, "ASCII conversion buffer too small"); } -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ - # endif /* FLOATING_POINT */ # ifdef PNG_FIXED_POINT_SUPPORTED @@ -3251,7 +3215,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, if (num <= 0x80000000) /* else overflowed */ { unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; + char digits[10] = {0}; while (num) { @@ -3336,15 +3300,6 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) * the nearest .00001). Overflow and divide by zero are signalled in * the result, a boolean - true on success, false on overflow. */ -#if GCC_STRICT_OVERFLOW /* from above */ -/* It is not obvious which comparison below gets optimized in such a way that - * signed overflow would change the result; looking through the code does not - * reveal any tests which have the form GCC complains about, so presumably the - * optimizer is moving an add or subtract into the 'if' somewhere. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ int png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, png_int_32 divisor) @@ -3459,9 +3414,6 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, return 0; } -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ #endif /* READ_GAMMA || INCH_CONVERSIONS */ #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) diff --git a/src/mkit/as/pngread/png.h b/src/mkit/as/pngread/png.h index 139eb0dc..83d39031 100644 --- a/src/mkit/as/pngread/png.h +++ b/src/mkit/as/pngread/png.h @@ -1,9 +1,9 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.37 - April 14, 2019 + * libpng version 1.6.43 * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -15,7 +15,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.37, April 2019: + * libpng versions 1.6.36, December 2018, through 1.6.43, February 2024: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -27,8 +27,8 @@ * PNG Reference Library License version 2 * --------------------------------------- * - * * Copyright (c) 1995-2019 The PNG Reference Library Authors. - * * Copyright (c) 2018-2019 Cosmin Truta. + * * Copyright (c) 1995-2024 The PNG Reference Library Authors. + * * Copyright (c) 2018-2024 Cosmin Truta. * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. * * Copyright (c) 1996-1997 Andreas Dilger. * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -239,7 +239,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.37 16 10637 16.so.16.37[.0] + * 1.6.43 16 10643 16.so.16.43[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -255,9 +255,6 @@ * to the info_ptr or png_ptr members through png.h, and the compiled * application is loaded with a different version of the library. * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). - * * See libpng.txt or libpng.3 for more information. The PNG specification * is available as a W3C Recommendation and as an ISO/IEC Standard; see * @@ -278,19 +275,21 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.37" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.37 - April 14, 2019\n" +#define PNG_LIBPNG_VER_STRING "1.6.43" +#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" -#define PNG_LIBPNG_VER_SONUM 16 -#define PNG_LIBPNG_VER_DLLNUM 16 +/* The versions of shared library builds should stay in sync, going forward */ +#define PNG_LIBPNG_VER_SHAREDLIB 16 +#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ +#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 37 +#define PNG_LIBPNG_VER_RELEASE 43 /* This should be zero for a public release, or non-zero for a - * development version. [Deprecated] + * development version. */ #define PNG_LIBPNG_VER_BUILD 0 @@ -318,7 +317,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10637 /* 1.6.37 */ +#define PNG_LIBPNG_VER 10643 /* 1.6.43 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -428,7 +427,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_37; +typedef char* png_libpng_version_1_6_43; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -849,7 +848,7 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); #define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ /* Added to libpng-1.5.4 */ #define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#if INT_MAX >= 0x8000 /* else this might break */ +#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */ #define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ #endif @@ -908,15 +907,15 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a * PNG file. Returns zero if the supplied bytes match the 8-byte PNG * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (ie return non-zero). + * start > 7 will always fail (i.e. return non-zero). */ PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, size_t num_to_check)); /* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0). */ -#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) +#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */ /* Allocate and initialize png_ptr struct for reading, and any other memory. */ PNG_EXPORTA(4, png_structp, png_create_read_struct, @@ -1446,7 +1445,7 @@ PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, * mainly useful for testing, as the defaults should work with most users. * Those users who are tight on memory or want faster performance at the * expense of compression can modify them. See the compression library - * header file (zlib.h) for an explination of the compression functions. + * header file (zlib.h) for an explanation of the compression functions. */ /* Set the filtering method(s) used by libpng. Currently, the only valid @@ -1501,7 +1500,7 @@ PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 * (0 - no compression, 9 - "maximal" compression). Note that tests have * shown that zlib compression levels 3-6 usually perform as well as level 9 - * for PNG images, and do considerably fewer caclulations. In the future, + * for PNG images, and do considerably fewer calculations. In the future, * these values may not correspond directly to the zlib compression levels. */ #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED @@ -1730,12 +1729,9 @@ PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 free_me, int num)); -/* Reassign responsibility for freeing existing data, whether allocated +/* Reassign the responsibility for freeing existing data, whether allocated * by libpng or by the application; this works on the png_info structure passed - * in, it does not change the state for other png_info structures. - * - * It is unlikely that this function works correctly as of 1.6.0 and using it - * may result either in memory leaks or double free of allocated data. + * in, without changing the state for other png_info structures. */ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, png_inforp info_ptr, int freer, png_uint_32 mask)); @@ -3207,11 +3203,18 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, #ifdef PNG_MIPS_MSA_API_SUPPORTED # define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ #endif -#define PNG_IGNORE_ADLER32 8 +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED +# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */ +#endif #ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */ +# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions + * supported */ #endif -#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */ +#ifdef PNG_MIPS_MMI_API_SUPPORTED +# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */ +#endif + +#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */ /* Return values: NOTE: there are four values and 'off' is *not* zero */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ diff --git a/src/mkit/as/pngread/pngconf.h b/src/mkit/as/pngread/pngconf.h index 927a769d..000d7b1a 100644 --- a/src/mkit/as/pngread/pngconf.h +++ b/src/mkit/as/pngread/pngconf.h @@ -1,9 +1,9 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.37 + * libpng version 1.6.43 * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -180,8 +180,8 @@ * compiler-specific macros to the values required to change the calling * conventions of the various functions. */ -#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ - defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \ + defined(__CYGWIN__) /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or * MinGW on any architecture currently supported by Windows. Also includes * Watcom builds but these need special treatment because they are not diff --git a/src/mkit/as/pngread/pngerror.c b/src/mkit/as/pngread/pngerror.c index ec3a709b..29ebda79 100644 --- a/src/mkit/as/pngread/pngerror.c +++ b/src/mkit/as/pngread/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -255,7 +255,7 @@ void png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, png_alloc_size_t value) { - char buffer[PNG_NUMBER_BUFFER_SIZE]; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); } @@ -265,7 +265,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format, { png_alloc_size_t u; png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE]; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; /* Avoid overflow by doing the negate in a png_alloc_size_t: */ u = (png_alloc_size_t)value; @@ -858,7 +858,7 @@ png_get_error_ptr(png_const_structrp png_ptr) if (png_ptr == NULL) return NULL; - return ((png_voidp)png_ptr->error_ptr); + return (png_voidp)png_ptr->error_ptr; } @@ -933,31 +933,25 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) #endif int /* PRIVATE */ -png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) +png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg) { - volatile png_imagep image = image_in; - volatile int result; - volatile png_voidp saved_error_buf; + png_voidp saved_error_buf = image->opaque->error_buf; jmp_buf safe_jmpbuf; + int result; - /* Safely execute function(arg) with png_error returning to this function. */ - saved_error_buf = image->opaque->error_buf; - result = setjmp(safe_jmpbuf) == 0; - - if (result != 0) + /* Safely execute function(arg), with png_error returning back here. */ + if (setjmp(safe_jmpbuf) == 0) { - image->opaque->error_buf = safe_jmpbuf; result = function(arg); + image->opaque->error_buf = saved_error_buf; + return result; } + /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */ image->opaque->error_buf = saved_error_buf; - - /* And do the cleanup prior to any failure return. */ - if (result == 0) - png_image_free(image); - - return result; + png_image_free(image); + return 0; } #endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ #endif /* READ || WRITE */ diff --git a/src/mkit/as/pngread/pngget.c b/src/mkit/as/pngread/pngget.c index 5abf1efd..1084b268 100644 --- a/src/mkit/as/pngread/pngget.c +++ b/src/mkit/as/pngread/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -21,18 +21,29 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->valid & flag); + { +#ifdef PNG_READ_tRNS_SUPPORTED + /* png_handle_PLTE() may have canceled a valid tRNS chunk but left the + * 'valid' flag for the detection of duplicate chunks. Do not report a + * valid tRNS chunk in this case. + */ + if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0) + return 0; +#endif - return(0); + return info_ptr->valid & flag; + } + + return 0; } size_t PNGAPI png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->rowbytes); + return info_ptr->rowbytes; - return(0); + return 0; } #ifdef PNG_INFO_IMAGE_SUPPORTED @@ -40,9 +51,9 @@ png_bytepp PNGAPI png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); + return info_ptr->row_pointers; - return(0); + return 0; } #endif @@ -54,7 +65,7 @@ png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->width; - return (0); + return 0; } png_uint_32 PNGAPI @@ -63,7 +74,7 @@ png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->height; - return (0); + return 0; } png_byte PNGAPI @@ -72,7 +83,7 @@ png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->bit_depth; - return (0); + return 0; } png_byte PNGAPI @@ -81,7 +92,7 @@ png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->color_type; - return (0); + return 0; } png_byte PNGAPI @@ -90,7 +101,7 @@ png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->filter_type; - return (0); + return 0; } png_byte PNGAPI @@ -99,7 +110,7 @@ png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->interlace_type; - return (0); + return 0; } png_byte PNGAPI @@ -108,7 +119,7 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->compression_type; - return (0); + return 0; } png_uint_32 PNGAPI @@ -116,21 +127,20 @@ png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_x_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } + { + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return info_ptr->x_pixels_per_unit; + } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_uint_32 PNGAPI @@ -138,42 +148,41 @@ png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_y_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); + return info_ptr->y_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_uint_32 PNGAPI png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); + return info_ptr->x_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } #ifdef PNG_FLOATING_POINT_SUPPORTED @@ -182,21 +191,21 @@ png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - if (info_ptr->x_pixels_per_unit != 0) - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); + return (float)info_ptr->y_pixels_per_unit + / (float)info_ptr->x_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return ((float)0.0); + return (float)0.0; } #endif @@ -206,6 +215,8 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio_fixed"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0 && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && @@ -214,8 +225,6 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, { png_fixed_point res; - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); - /* The following casts work because a PNG 4 byte integer only has a valid * range of 0..2^31-1; otherwise the cast might overflow. */ @@ -236,80 +245,80 @@ png_int_32 PNGAPI png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_microns"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); + return info_ptr->x_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_microns"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); + return info_ptr->y_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_pixels"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); + return info_ptr->x_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_pixels"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); + return info_ptr->y_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } #ifdef PNG_INCH_CONVERSIONS_SUPPORTED @@ -423,11 +432,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, { png_uint_32 retval = 0; + png_debug1(1, "in %s retrieval function", "pHYs"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "pHYs"); - if (res_x != NULL) { *res_x = info_ptr->x_pixels_per_unit; @@ -453,7 +462,7 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, } } - return (retval); + return retval; } #endif /* pHYs */ #endif /* INCH_CONVERSIONS */ @@ -467,9 +476,9 @@ png_byte PNGAPI png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->channels); + return info_ptr->channels; - return (0); + return 0; } #ifdef PNG_READ_SUPPORTED @@ -477,9 +486,9 @@ png_const_bytep PNGAPI png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); + return info_ptr->signature; - return (NULL); + return NULL; } #endif @@ -488,17 +497,17 @@ png_uint_32 PNGAPI png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, png_color_16p *background) { + png_debug1(1, "in %s retrieval function", "bKGD"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0 && background != NULL) { - png_debug1(1, "in %s retrieval function", "bKGD"); - *background = &(info_ptr->background); - return (PNG_INFO_bKGD); + return PNG_INFO_bKGD; } - return (0); + return 0; } #endif @@ -513,6 +522,8 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, double *red_y, double *green_x, double *green_y, double *blue_x, double *blue_y) { + png_debug1(1, "in %s retrieval function", "cHRM"); + /* Quiet API change: this code used to only return the end points if a cHRM * chunk was present, but the end points can also come from iCCP or sRGB * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and @@ -522,8 +533,6 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM"); - if (white_x != NULL) *white_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); @@ -548,10 +557,10 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (blue_y != NULL) *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, "cHRM blue Y"); - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } png_uint_32 PNGAPI @@ -560,11 +569,11 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, double *green_Y, double *green_Z, double *blue_X, double *blue_Y, double *blue_Z) { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); - if (red_X != NULL) *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, "cHRM red X"); @@ -592,10 +601,10 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, if (blue_Z != NULL) *blue_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } # endif @@ -608,11 +617,11 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, png_fixed_point *int_blue_Z) { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - if (int_red_X != NULL) *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; if (int_red_Y != NULL) @@ -631,10 +640,10 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; if (int_blue_Z != NULL) *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } png_uint_32 PNGAPI @@ -664,10 +673,10 @@ png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *blue_x = info_ptr->colorspace.end_points_xy.bluex; if (blue_y != NULL) *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } # endif #endif @@ -685,10 +694,10 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, file_gamma != NULL) { *file_gamma = info_ptr->colorspace.gamma; - return (PNG_INFO_gAMA); + return PNG_INFO_gAMA; } - return (0); + return 0; } # endif @@ -705,10 +714,10 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, { *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, "png_get_gAMA"); - return (PNG_INFO_gAMA); + return PNG_INFO_gAMA; } - return (0); + return 0; } # endif #endif @@ -724,10 +733,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) { *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return (PNG_INFO_sRGB); + return PNG_INFO_sRGB; } - return (0); + return 0; } #endif @@ -751,10 +760,10 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, */ if (compression_type != NULL) *compression_type = PNG_COMPRESSION_TYPE_BASE; - return (PNG_INFO_iCCP); + return PNG_INFO_iCCP; } - return (0); + return 0; } #endif @@ -764,13 +773,15 @@ int PNGAPI png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, png_sPLT_tpp spalettes) { + png_debug1(1, "in %s retrieval function", "sPLT"); + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) { *spalettes = info_ptr->splt_palettes; return info_ptr->splt_palettes_num; } - return (0); + return 0; } #endif @@ -796,10 +807,10 @@ png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, { *num_exif = info_ptr->num_exif; *exif = info_ptr->exif; - return (PNG_INFO_eXIf); + return PNG_INFO_eXIf; } - return (0); + return 0; } #endif @@ -814,10 +825,10 @@ png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) { *hist = info_ptr->hist; - return (PNG_INFO_hIST); + return PNG_INFO_hIST; } - return (0); + return 0; } #endif @@ -830,7 +841,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, png_debug1(1, "in %s retrieval function", "IHDR"); if (png_ptr == NULL || info_ptr == NULL) - return (0); + return 0; if (width != NULL) *width = info_ptr->width; @@ -862,7 +873,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, info_ptr->compression_type, info_ptr->filter_type); - return (1); + return 1; } #ifdef PNG_oFFs_SUPPORTED @@ -879,10 +890,10 @@ png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, *offset_x = info_ptr->x_offset; *offset_y = info_ptr->y_offset; *unit_type = (int)info_ptr->offset_unit_type; - return (PNG_INFO_oFFs); + return PNG_INFO_oFFs; } - return (0); + return 0; } #endif @@ -906,10 +917,10 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, *nparams = (int)info_ptr->pcal_nparams; *units = info_ptr->pcal_units; *params = info_ptr->pcal_params; - return (PNG_INFO_pCAL); + return PNG_INFO_pCAL; } - return (0); + return 0; } #endif @@ -921,6 +932,8 @@ png_uint_32 PNGAPI png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_fixed_point *width, png_fixed_point *height) { + png_debug1(1, "in %s retrieval function", "sCAL"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { @@ -932,10 +945,10 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), "sCAL height"); - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } # endif /* FLOATING_ARITHMETIC */ # endif /* FIXED_POINT */ @@ -944,32 +957,36 @@ png_uint_32 PNGAPI png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, double *width, double *height) { + png_debug1(1, "in %s retrieval function", "sCAL(float)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { *unit = info_ptr->scal_unit; *width = atof(info_ptr->scal_s_width); *height = atof(info_ptr->scal_s_height); - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } # endif /* FLOATING POINT */ png_uint_32 PNGAPI png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_charpp width, png_charpp height) { + png_debug1(1, "in %s retrieval function", "sCAL(str)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_s_width; *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } #endif /* sCAL */ @@ -1004,7 +1021,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, } } - return (retval); + return retval; } #endif /* pHYs */ @@ -1020,10 +1037,10 @@ png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, *palette = info_ptr->palette; *num_palette = info_ptr->num_palette; png_debug1(3, "num_palette = %d", *num_palette); - return (PNG_INFO_PLTE); + return PNG_INFO_PLTE; } - return (0); + return 0; } #ifdef PNG_sBIT_SUPPORTED @@ -1037,10 +1054,10 @@ png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) { *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); + return PNG_INFO_sBIT; } - return (0); + return 0; } #endif @@ -1051,7 +1068,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { - png_debug1(1, "in 0x%lx retrieval function", + png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx", (unsigned long)png_ptr->chunk_name); if (text_ptr != NULL) @@ -1066,7 +1083,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, if (num_text != NULL) *num_text = 0; - return(0); + return 0; } #endif @@ -1081,10 +1098,10 @@ png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) { *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); + return PNG_INFO_tIME; } - return (0); + return 0; } #endif @@ -1094,11 +1111,12 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) { png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "tRNS"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) { - png_debug1(1, "in %s retrieval function", "tRNS"); - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (trans_alpha != NULL) @@ -1130,7 +1148,7 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, } } - return (retval); + return retval; } #endif @@ -1145,13 +1163,13 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, return info_ptr->unknown_chunks_num; } - return (0); + return 0; } #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED png_byte PNGAPI -png_get_rgb_to_gray_status (png_const_structrp png_ptr) +png_get_rgb_to_gray_status(png_const_structrp png_ptr) { return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); } @@ -1192,27 +1210,27 @@ png_get_compression_buffer_size(png_const_structrp png_ptr) /* These functions were added to libpng 1.2.6 and were enabled * by default in libpng-1.4.0 */ png_uint_32 PNGAPI -png_get_user_width_max (png_const_structrp png_ptr) +png_get_user_width_max(png_const_structrp png_ptr) { return (png_ptr ? png_ptr->user_width_max : 0); } png_uint_32 PNGAPI -png_get_user_height_max (png_const_structrp png_ptr) +png_get_user_height_max(png_const_structrp png_ptr) { return (png_ptr ? png_ptr->user_height_max : 0); } /* This function was added to libpng 1.4.0 */ png_uint_32 PNGAPI -png_get_chunk_cache_max (png_const_structrp png_ptr) +png_get_chunk_cache_max(png_const_structrp png_ptr) { return (png_ptr ? png_ptr->user_chunk_cache_max : 0); } /* This function was added to libpng 1.4.1 */ png_alloc_size_t PNGAPI -png_get_chunk_malloc_max (png_const_structrp png_ptr) +png_get_chunk_malloc_max(png_const_structrp png_ptr) { return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); } @@ -1221,13 +1239,13 @@ png_get_chunk_malloc_max (png_const_structrp png_ptr) /* These functions were added to libpng 1.4.0 */ #ifdef PNG_IO_STATE_SUPPORTED png_uint_32 PNGAPI -png_get_io_state (png_const_structrp png_ptr) +png_get_io_state(png_const_structrp png_ptr) { return png_ptr->io_state; } png_uint_32 PNGAPI -png_get_io_chunk_type (png_const_structrp png_ptr) +png_get_io_chunk_type(png_const_structrp png_ptr) { return png_ptr->chunk_name; } @@ -1241,7 +1259,7 @@ png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) if (png_ptr != NULL && info_ptr != NULL) return png_ptr->num_palette_max; - return (-1); + return -1; } # endif #endif diff --git a/src/mkit/as/pngread/pnglibconf.h b/src/mkit/as/pngread/pnglibconf.h index e32500e3..dd790bd7 100644 --- a/src/mkit/as/pngread/pnglibconf.h +++ b/src/mkit/as/pngread/pnglibconf.h @@ -1,8 +1,8 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.37 */ +/* libpng version 1.6.43 */ -/* Copyright (c) 2018-2019 Cosmin Truta */ +/* Copyright (c) 2018-2024 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ @@ -27,6 +27,7 @@ /*#undef PNG_COLORSPACE_SUPPORTED*/ /*#undef PNG_CONSOLE_IO_SUPPORTED*/ /*#undef PNG_CONVERT_tIME_SUPPORTED*/ +/*#undef PNG_DISABLE_ADLER32_CHECK_SUPPORTED*/ /*#undef PNG_EASY_ACCESS_SUPPORTED*/ /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ /*#undef PNG_ERROR_TEXT_SUPPORTED*/ @@ -41,6 +42,10 @@ /*#undef PNG_INCH_CONVERSIONS_SUPPORTED*/ /*#undef PNG_INFO_IMAGE_SUPPORTED*/ /*#undef PNG_IO_STATE_SUPPORTED*/ +/*#undef PNG_MIPS_MMI_API_SUPPORTED*/ +/*#undef PNG_MIPS_MMI_CHECK_SUPPORTED*/ +/*#undef PNG_MIPS_MSA_API_SUPPORTED*/ +/*#undef PNG_MIPS_MSA_CHECK_SUPPORTED*/ /*#undef PNG_MNG_FEATURES_SUPPORTED*/ /*#undef PNG_POINTER_INDEXING_SUPPORTED*/ /*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ @@ -210,7 +215,7 @@ #define PNG_USER_HEIGHT_MAX 1000000 #define PNG_USER_WIDTH_MAX 1000000 #define PNG_ZBUF_SIZE 8192 -#define PNG_ZLIB_VERNUM 0x12b0 +#define PNG_ZLIB_VERNUM 0x1310 #define PNG_Z_DEFAULT_COMPRESSION (-1) #define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 #define PNG_Z_DEFAULT_STRATEGY 1 diff --git a/src/mkit/as/pngread/pngpriv.h b/src/mkit/as/pngread/pngpriv.h index 583c26f9..9bfdb713 100644 --- a/src/mkit/as/pngread/pngpriv.h +++ b/src/mkit/as/pngread/pngpriv.h @@ -1,7 +1,7 @@ /* pngpriv.h - private declarations for use inside libpng * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -36,7 +36,7 @@ * still required (as of 2011-05-02.) */ #ifndef _POSIX_SOURCE -# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ +# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ #endif #ifndef PNG_VERSION_INFO_ONLY @@ -174,7 +174,7 @@ # else /* !defined __ARM_NEON__ */ /* The 'intrinsics' code simply won't compile without this -mfpu=neon: */ -# if !defined(__aarch64__) +# if !defined(__aarch64__) && !defined(_M_ARM64) /* The assembler code currently does not work on ARM64 */ # define PNG_ARM_NEON_IMPLEMENTATION 2 # endif /* __aarch64__ */ @@ -185,16 +185,32 @@ /* Use the intrinsics code by default. */ # define PNG_ARM_NEON_IMPLEMENTATION 1 # endif +#else /* PNG_ARM_NEON_OPT == 0 */ +# define PNG_ARM_NEON_IMPLEMENTATION 0 #endif /* PNG_ARM_NEON_OPT > 0 */ #ifndef PNG_MIPS_MSA_OPT -# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) # define PNG_MIPS_MSA_OPT 2 # else # define PNG_MIPS_MSA_OPT 0 # endif #endif +#ifndef PNG_MIPS_MMI_OPT +# ifdef PNG_MIPS_MMI +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_MIPS_MMI_OPT 1 +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +#endif + #ifndef PNG_POWERPC_VSX_OPT # if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) # define PNG_POWERPC_VSX_OPT 2 @@ -203,13 +219,21 @@ # endif #endif +#ifndef PNG_LOONGARCH_LSX_OPT +# if defined(__loongarch_sx) +# define PNG_LOONGARCH_LSX_OPT 1 +# else +# define PNG_LOONGARCH_LSX_OPT 0 +# endif +#endif + #ifndef PNG_INTEL_SSE_OPT # ifdef PNG_INTEL_SSE /* Only check for SSE if the build configuration has been modified to * enable SSE optimizations. This means that these optimizations will * be off by default. See contrib/intel for more details. */ -# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ +# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ (defined(_M_IX86_FP) && _M_IX86_FP >= 2) # define PNG_INTEL_SSE_OPT 1 @@ -246,7 +270,6 @@ #endif #if PNG_MIPS_MSA_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa # ifndef PNG_MIPS_MSA_IMPLEMENTATION # if defined(__mips_msa) # if defined(__clang__) @@ -262,14 +285,41 @@ # ifndef PNG_MIPS_MSA_IMPLEMENTATION # define PNG_MIPS_MSA_IMPLEMENTATION 1 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips # endif +#else +# define PNG_MIPS_MSA_IMPLEMENTATION 0 #endif /* PNG_MIPS_MSA_OPT > 0 */ +#if PNG_MIPS_MMI_OPT > 0 +# ifndef PNG_MIPS_MMI_IMPLEMENTATION +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) +# define PNG_MIPS_MMI_IMPLEMENTATION 2 +# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */ +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */ +# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */ + +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips +# endif +#else +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +#endif /* PNG_MIPS_MMI_OPT > 0 */ + #if PNG_POWERPC_VSX_OPT > 0 # define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx # define PNG_POWERPC_VSX_IMPLEMENTATION 1 +#else +# define PNG_POWERPC_VSX_IMPLEMENTATION 0 #endif +#if PNG_LOONGARCH_LSX_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1 +#else +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 +#endif /* Is this a build of a DLL where compilation of the object modules requires * different preprocessor settings to those required for a simple library? If @@ -492,16 +542,7 @@ static_cast(static_cast(value)) #else # define png_voidcast(type, value) (value) -# ifdef _WIN64 -# ifdef __GNUC__ - typedef unsigned long long png_ptruint; -# else - typedef unsigned __int64 png_ptruint; -# endif -# else - typedef unsigned long png_ptruint; -# endif -# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value)) +# define png_constcast(type, value) ((type)(void*)(const void*)(value)) # define png_aligncast(type, value) ((void*)(value)) # define png_aligncastconst(type, value) ((const void*)(value)) #endif /* __cplusplus */ @@ -517,18 +558,8 @@ */ # include -# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) - /* We need to check that hasn't already been included earlier - * as it seems it doesn't agree with , yet we should really use - * if possible. - */ -# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) -# include -# endif -# else -# include -# endif +# include + # if defined(_AMIGA) && defined(__SASC) && defined(_M68881) /* Amiga SAS/C: We must include builtin FPU functions when compiling using * MATH=68881 @@ -543,9 +574,8 @@ # include #endif -#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ - defined(_WIN32) || defined(__WIN32__) -# include /* defines _WINDOWS_ macro */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +# include #endif #endif /* PNG_VERSION_INFO_ONLY */ @@ -554,24 +584,20 @@ * functions that are passed far data must be model-independent. */ -/* Memory model/platform independent fns */ +/* Platform-independent functions */ #ifndef PNG_ABORT -# ifdef _WINDOWS_ -# define PNG_ABORT() ExitProcess(0) -# else -# define PNG_ABORT() abort() -# endif +# define PNG_ABORT() abort() #endif /* These macros may need to be architecture dependent. */ -#define PNG_ALIGN_NONE 0 /* do not use data alignment */ -#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ +#define PNG_ALIGN_NONE 0 /* do not use data alignment */ +#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ #ifdef offsetof -# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ +# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ #else # define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ #endif -#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ +#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ #ifndef PNG_ALIGN_TYPE /* Default to using aligned access optimizations and requiring alignment to a @@ -585,26 +611,25 @@ /* This is used because in some compiler implementations non-aligned * structure members are supported, so the offsetof approach below fails. * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access - * is good for performance. Do not do this unless you have tested the result - * and understand it. + * is good for performance. Do not do this unless you have tested the + * result and understand it. */ -# define png_alignof(type) (sizeof (type)) +# define png_alignof(type) (sizeof(type)) #else # if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET -# define png_alignof(type) offsetof(struct{char c; type t;}, t) +# define png_alignof(type) offsetof(struct{char c; type t;}, t) # else -# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS -# define png_alignof(type) (1) -# endif - /* Else leave png_alignof undefined to prevent use thereof */ +# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS +# define png_alignof(type) 1 +# endif + /* Else leave png_alignof undefined to prevent use thereof */ # endif #endif -/* This implicitly assumes alignment is always to a power of 2. */ +/* This implicitly assumes alignment is always a multiple of 2. */ #ifdef png_alignof -# define png_isaligned(ptr, type)\ - (((type)((const char*)ptr-(const char*)0) & \ - (type)(png_alignof(type)-1)) == 0) +# define png_isaligned(ptr, type) \ + (((type)(size_t)((const void*)(ptr)) & (type)(png_alignof(type)-1)) == 0) #else # define png_isaligned(ptr, type) 0 #endif @@ -635,7 +660,7 @@ #define PNG_BACKGROUND_IS_GRAY 0x800U #define PNG_HAVE_PNG_SIGNATURE 0x1000U #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */ - /* 0x4000U (unused) */ +#define PNG_WROTE_eXIf 0x4000U #define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */ /* Flags for the transformations the PNG library does on the image data */ @@ -1315,7 +1340,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif -#if PNG_MIPS_MSA_OPT > 0 +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop @@ -1332,6 +1357,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + #if PNG_POWERPC_VSX_OPT > 0 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); @@ -1364,6 +1406,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + /* Choose the best filter to use and filter the row data */ PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); @@ -1919,7 +1978,7 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, */ #define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ -/* Result codes for the parser (boolean - true meants ok, false means +/* Result codes for the parser (boolean - true means ok, false means * not ok yet.) */ #define PNG_FP_MAYBE 0 /* The number may be valid in the future */ @@ -1955,7 +2014,7 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, * the problem character.) This has not been tested within libpng. */ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, - size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); + size_t size, int *statep, size_t *whereami),PNG_EMPTY); /* This is the same but it checks a complete string and returns true * only if it just contains a floating point number. As of 1.5.4 this @@ -2103,17 +2162,27 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif -#if PNG_MIPS_MSA_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa, +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +# endif + # if PNG_INTEL_SSE_IMPLEMENTATION > 0 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); # endif #endif +#if PNG_LOONGARCH_LSX_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, png_const_charp key, png_bytep new_key), PNG_EMPTY); diff --git a/src/mkit/as/pngread/pngread.c b/src/mkit/as/pngread/pngread.c index 8fa7d9f1..07a39df6 100644 --- a/src/mkit/as/pngread/pngread.c +++ b/src/mkit/as/pngread/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -568,7 +568,11 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) + if (png_ptr->transformations +# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + || png_ptr->num_palette_max >= 0 +# endif + ) png_do_read_transformations(png_ptr, &row_info); #endif @@ -785,7 +789,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED /* Report invalid palette index; added at libng-1.5.10 */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max > png_ptr->num_palette) + png_ptr->num_palette_max >= png_ptr->num_palette) png_benign_error(png_ptr, "Read palette index exceeding num_palette"); #endif @@ -1049,6 +1053,8 @@ void PNGAPI png_read_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params) { + png_debug(1, "in png_read_png"); + if (png_ptr == NULL || info_ptr == NULL) return; @@ -3452,7 +3458,6 @@ png_image_read_background(png_voidp argument) for (pass = 0; pass < passes; ++pass) { - png_bytep row = png_voidcast(png_bytep, display->first_row); unsigned int startx, stepx, stepy; png_uint_32 y; @@ -3557,8 +3562,6 @@ png_image_read_background(png_voidp argument) inrow += 2; /* gray and alpha channel */ } - - row += display->row_bytes; } } } @@ -3765,13 +3768,13 @@ png_image_read_direct(png_voidp argument) mode = PNG_ALPHA_PNG; output_gamma = PNG_DEFAULT_sRGB; } - + if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { mode = PNG_ALPHA_OPTIMIZED; change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; } - + /* If 'do_local_background' is set check for the presence of gamma * correction; this is part of the work-round for the libpng bug * described above. diff --git a/src/mkit/as/pngread/pngrtran.c b/src/mkit/as/pngread/pngrtran.c index 9a8fad9f..1526123e 100644 --- a/src/mkit/as/pngread/pngrtran.c +++ b/src/mkit/as/pngread/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -21,7 +21,7 @@ #ifdef PNG_ARM_NEON_IMPLEMENTATION # if PNG_ARM_NEON_IMPLEMENTATION == 1 # define PNG_ARM_NEON_INTRINSICS_AVAILABLE -# if defined(_MSC_VER) && defined(_M_ARM64) +# if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) # include # else # include @@ -290,21 +290,20 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, int compose = 0; png_fixed_point file_gamma; - png_debug(1, "in png_set_alpha_mode"); + png_debug(1, "in png_set_alpha_mode_fixed"); if (png_rtran_ok(png_ptr, 0) == 0) return; output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - /* Validate the value to ensure it is in a reasonable range. The value + /* Validate the value to ensure it is in a reasonable range. The value * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out users of this API - * who use the inverse of the gamma value accidentally! Since some of these - * values are reasonable this may have to be changed: + * viewing correction values. The intent is to weed out the API users + * who might use the inverse of the gamma value accidentally! * - * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit - * gamma of 36, and its reciprocal.) + * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate + * the optimal 16-bit gamma of 36 and its reciprocal. */ if (output_gamma < 1000 || output_gamma > 10000000) png_error(png_ptr, "output gamma out of expected range"); @@ -441,7 +440,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -458,7 +457,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -592,11 +591,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -761,12 +758,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, size_t num_entries = ((size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); + (png_alloc_size_t)(num_entries)); - distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries * - (sizeof (png_byte)))); + distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries); - memset(distance, 0xff, num_entries * (sizeof (png_byte))); + memset(distance, 0xff, num_entries); for (i = 0; i < num_palette; i++) { @@ -970,7 +966,7 @@ void PNGFAPI png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { - png_debug(1, "in png_set_rgb_to_gray"); + png_debug(1, "in png_set_rgb_to_gray_fixed"); /* Need the IHDR here because of the check on color_type below. */ /* TODO: fix this */ diff --git a/src/mkit/as/pngread/pngrutil.c b/src/mkit/as/pngread/pngrutil.c index d5fa08c3..d31dc21d 100644 --- a/src/mkit/as/pngread/pngrutil.c +++ b/src/mkit/as/pngread/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -26,7 +26,7 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) if (uval > PNG_UINT_31_MAX) png_error(png_ptr, "PNG unsigned integer out of range"); - return (uval); + return uval; } #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) @@ -140,7 +140,7 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr) if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) { if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) png_error(png_ptr, "Not a PNG file"); else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); @@ -171,7 +171,7 @@ png_read_chunk_header(png_structrp png_ptr) /* Put the chunk name into png_ptr->chunk_name. */ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - png_debug2(0, "Reading %lx chunk, length = %lu", + png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu", (unsigned long)png_ptr->chunk_name, (unsigned long)length); /* Reset the crc and run it over the chunk name. */ @@ -238,10 +238,10 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip) else png_chunk_error(png_ptr, "CRC error"); - return (1); + return 1; } - return (0); + return 0; } /* Compare the CRC stored in the PNG file with that calculated by libpng from @@ -277,11 +277,11 @@ png_crc_error(png_structrp png_ptr) if (need_crc != 0) { crc = png_get_uint_32(crc_bytes); - return ((int)(crc != png_ptr->crc)); + return crc != png_ptr->crc; } else - return (0); + return 0; } #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ @@ -301,7 +301,6 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) if (buffer != NULL && new_size > png_ptr->read_buffer_size) { - png_ptr->read_buffer = NULL; png_ptr->read_buffer = NULL; png_ptr->read_buffer_size = 0; png_free(png_ptr, buffer); @@ -422,8 +421,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; } -#if ZLIB_VERNUM >= 0x1290 && \ - defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) /* Turn off validation of the ADLER32 checksum in IDAT chunks */ ret = inflateValidate(&png_ptr->zstream, 0); @@ -2076,21 +2074,22 @@ png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_byte buf[1]; png_crc_read(png_ptr, buf, 1); info_ptr->eXIf_buf[i] = buf[0]; - if (i == 1 && buf[0] != 'M' && buf[0] != 'I' - && info_ptr->eXIf_buf[0] != buf[0]) + if (i == 1) { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - return; + if ((buf[0] != 'M' && buf[0] != 'I') || + (info_ptr->eXIf_buf[0] != buf[0])) + { + png_crc_finish(png_ptr, length - 2); + png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); + png_free(png_ptr, info_ptr->eXIf_buf); + info_ptr->eXIf_buf = NULL; + return; + } } } - if (png_crc_finish(png_ptr, 0) != 0) - return; - - png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); + if (png_crc_finish(png_ptr, 0) == 0) + png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); png_free(png_ptr, info_ptr->eXIf_buf); info_ptr->eXIf_buf = NULL; @@ -2126,8 +2125,9 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) num = length / 2 ; - if (num != (unsigned int) png_ptr->num_palette || - num > (unsigned int) PNG_MAX_PALETTE_LENGTH) + if (length != num * 2 || + num != (unsigned int)png_ptr->num_palette || + num > (unsigned int)PNG_MAX_PALETTE_LENGTH) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); @@ -3185,7 +3185,7 @@ png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) { png_debug2(0," length = %lu, limit = %lu", (unsigned long)length,(unsigned long)limit); - png_chunk_error(png_ptr, "chunk data is too large"); + png_benign_error(png_ptr, "chunk data is too large"); } } @@ -4621,14 +4621,13 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) */ { png_bytep temp = png_ptr->big_row_buf + 32; - int extra = (int)((temp - (png_bytep)0) & 0x0f); + size_t extra = (size_t)temp & 0x0f; png_ptr->row_buf = temp - extra - 1/*filter byte*/; temp = png_ptr->big_prev_row + 32; - extra = (int)((temp - (png_bytep)0) & 0x0f); + extra = (size_t)temp & 0x0f; png_ptr->prev_row = temp - extra - 1/*filter byte*/; } - #else /* Use 31 bytes of padding before and 17 bytes after row_buf. */ png_ptr->row_buf = png_ptr->big_row_buf + 31; diff --git a/src/mkit/as/pngread/pngset.c b/src/mkit/as/pngread/pngset.c index ec75dbe3..eb1c8c7a 100644 --- a/src/mkit/as/pngread/pngset.c +++ b/src/mkit/as/pngread/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -137,46 +137,40 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, #ifdef PNG_eXIf_SUPPORTED void PNGAPI png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep eXIf_buf) + png_bytep exif) { png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); PNG_UNUSED(info_ptr) - PNG_UNUSED(eXIf_buf) + PNG_UNUSED(exif) } void PNGAPI png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 num_exif, png_bytep eXIf_buf) + png_uint_32 num_exif, png_bytep exif) { - int i; + png_bytep new_exif; png_debug1(1, "in %s storage function", "eXIf"); - if (png_ptr == NULL || info_ptr == NULL) + if (png_ptr == NULL || info_ptr == NULL || + (png_ptr->mode & PNG_WROTE_eXIf) != 0) return; - if (info_ptr->exif) - { - png_free(png_ptr, info_ptr->exif); - info_ptr->exif = NULL; - } - - info_ptr->num_exif = num_exif; - - info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, - info_ptr->num_exif)); + new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif)); - if (info_ptr->exif == NULL) + if (new_exif == NULL) { png_warning(png_ptr, "Insufficient memory for eXIf chunk data"); return; } - info_ptr->free_me |= PNG_FREE_EXIF; + memcpy(new_exif, exif, (size_t)num_exif); - for (i = 0; i < (int) info_ptr->num_exif; i++) - info_ptr->exif[i] = eXIf_buf[i]; + png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0); + info_ptr->num_exif = num_exif; + info_ptr->exif = new_exif; + info_ptr->free_me |= PNG_FREE_EXIF; info_ptr->valid |= PNG_INFO_eXIf; } #endif /* eXIf */ @@ -237,15 +231,13 @@ png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->hist == NULL) { png_warning(png_ptr, "Insufficient memory for hIST chunk data"); - return; } - info_ptr->free_me |= PNG_FREE_HIST; - for (i = 0; i < info_ptr->num_palette; i++) info_ptr->hist[i] = hist[i]; + info_ptr->free_me |= PNG_FREE_HIST; info_ptr->valid |= PNG_INFO_hIST; } #endif @@ -367,6 +359,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, memcpy(info_ptr->pcal_purpose, purpose, length); + info_ptr->free_me |= PNG_FREE_PCAL; + png_debug(3, "storing X0, X1, type, and nparams in info"); info_ptr->pcal_X0 = X0; info_ptr->pcal_X1 = X1; @@ -383,7 +377,6 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->pcal_units == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL units"); - return; } @@ -395,7 +388,6 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->pcal_params == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL params"); - return; } @@ -413,7 +405,6 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->pcal_params[i] == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL parameter"); - return; } @@ -421,7 +412,6 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, } info_ptr->valid |= PNG_INFO_pCAL; - info_ptr->free_me |= PNG_FREE_PCAL; } #endif @@ -478,18 +468,17 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->scal_s_height == NULL) { - png_free (png_ptr, info_ptr->scal_s_width); + png_free(png_ptr, info_ptr->scal_s_width); info_ptr->scal_s_width = NULL; png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - return; } memcpy(info_ptr->scal_s_height, sheight, lengthh); - info_ptr->valid |= PNG_INFO_sCAL; info_ptr->free_me |= PNG_FREE_SCAL; + info_ptr->valid |= PNG_INFO_sCAL; } # ifdef PNG_FLOATING_POINT_SUPPORTED @@ -625,11 +614,10 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, if (num_palette > 0) memcpy(png_ptr->palette, palette, (unsigned int)num_palette * (sizeof (png_color))); + info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; - info_ptr->free_me |= PNG_FREE_PLTE; - info_ptr->valid |= PNG_INFO_PLTE; } @@ -775,11 +763,11 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, { int i; - png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U : - (unsigned long)png_ptr->chunk_name); + png_debug1(1, "in text storage function, chunk typeid = 0x%lx", + png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name); if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return(0); + return 0; /* Make sure we have enough space in the "text" array in info_struct * to hold all of the incoming text_ptr objects. This compare can't overflow @@ -959,7 +947,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "transferred text chunk %d", info_ptr->num_text); } - return(0); + return 0; } #endif @@ -1019,6 +1007,9 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, info_ptr->trans_alpha = png_voidcast(png_bytep, png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans); + + info_ptr->free_me |= PNG_FREE_TRNS; + info_ptr->valid |= PNG_INFO_tRNS; } png_ptr->trans_alpha = info_ptr->trans_alpha; } @@ -1051,8 +1042,8 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, if (num_trans != 0) { - info_ptr->valid |= PNG_INFO_tRNS; info_ptr->free_me |= PNG_FREE_TRNS; + info_ptr->valid |= PNG_INFO_tRNS; } } #endif @@ -1072,6 +1063,8 @@ png_set_sPLT(png_const_structrp png_ptr, { png_sPLT_tp np; + png_debug1(1, "in %s storage function", "sPLT"); + if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) return; @@ -1086,11 +1079,11 @@ png_set_sPLT(png_const_structrp png_ptr, { /* Out of memory or too many chunks */ png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); - return; } png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = np; info_ptr->free_me |= PNG_FREE_SPLT; @@ -1244,11 +1237,11 @@ png_set_unknown_chunks(png_const_structrp png_ptr, { png_chunk_report(png_ptr, "too many unknown chunks", PNG_CHUNK_WRITE_ERROR); - return; } png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = np; /* safe because it is initialized */ info_ptr->free_me |= PNG_FREE_UNKN; @@ -1326,7 +1319,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, #ifdef PNG_MNG_FEATURES_SUPPORTED png_uint_32 PNGAPI -png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) +png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features) { png_debug(1, "in png_permit_mng_features"); @@ -1546,7 +1539,7 @@ void PNGAPI png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, png_bytepp row_pointers) { - png_debug1(1, "in %s storage function", "rows"); + png_debug(1, "in png_set_rows"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -1565,6 +1558,8 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, void PNGAPI png_set_compression_buffer_size(png_structrp png_ptr, size_t size) { + png_debug(1, "in png_set_compression_buffer_size"); + if (png_ptr == NULL) return; @@ -1633,9 +1628,11 @@ png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) #ifdef PNG_SET_USER_LIMITS_SUPPORTED /* This function was added to libpng 1.2.6 */ void PNGAPI -png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, +png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max) { + png_debug(1, "in png_set_user_limits"); + /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream * regardless of dimensions, set both limits to 0x7fffffff. @@ -1649,17 +1646,21 @@ png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, /* This function was added to libpng 1.4.0 */ void PNGAPI -png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) +png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max) { + png_debug(1, "in png_set_chunk_cache_max"); + if (png_ptr != NULL) png_ptr->user_chunk_cache_max = user_chunk_cache_max; } /* This function was added to libpng 1.4.1 */ void PNGAPI -png_set_chunk_malloc_max (png_structrp png_ptr, +png_set_chunk_malloc_max(png_structrp png_ptr, png_alloc_size_t user_chunk_malloc_max) { + png_debug(1, "in png_set_chunk_malloc_max"); + if (png_ptr != NULL) png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; } diff --git a/src/mkit/as/pngread/pngstruct.h b/src/mkit/as/pngread/pngstruct.h index 8bdc7ce4..e591d94d 100644 --- a/src/mkit/as/pngread/pngstruct.h +++ b/src/mkit/as/pngread/pngstruct.h @@ -1,7 +1,7 @@ /* pngstruct.h - header file for PNG reference library * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2022 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -334,18 +334,8 @@ struct png_struct_def size_t current_buffer_size; /* amount of data now in current_buffer */ int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ - #endif /* PROGRESSIVE_READ */ -#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) -/* For the Borland special 64K segment handler */ - png_bytepp offset_table_ptr; - png_bytep offset_table; - png_uint_16 offset_table_number; - png_uint_16 offset_table_count; - png_uint_16 offset_table_count_free; -#endif - #ifdef PNG_READ_QUANTIZE_SUPPORTED png_bytep palette_lookup; /* lookup table for quantizing */ png_bytep quantize_index; /* index translation for palette files */ diff --git a/src/mkit/as/pngread/pngtrans.c b/src/mkit/as/pngread/pngtrans.c index 1100f46e..62cb21ed 100644 --- a/src/mkit/as/pngread/pngtrans.c +++ b/src/mkit/as/pngread/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -103,10 +103,10 @@ png_set_interlace_handling(png_structrp png_ptr) if (png_ptr != 0 && png_ptr->interlaced != 0) { png_ptr->transformations |= PNG_INTERLACE; - return (7); + return 7; } - return (1); + return 1; } #endif @@ -498,6 +498,8 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) png_bytep dp = row; /* destination pointer */ png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ + png_debug(1, "in png_do_strip_channel"); + /* At the start sp will point to the first byte to copy and dp to where * it is copied to. ep always points just beyond the end of the row, so * the loop simply copies (channels-1) channels until sp reaches ep. @@ -698,6 +700,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) { + png_debug(1, "in png_do_check_palette_indexes"); + if (png_ptr->num_palette < (1 << row_info->bit_depth) && png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ { @@ -708,7 +712,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) * forms produced on either GCC or MSVC. */ int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); - png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; switch (row_info->bit_depth) { @@ -833,7 +837,7 @@ png_voidp PNGAPI png_get_user_transform_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; return png_ptr->user_transform_ptr; } diff --git a/src/mkit/as/pngread/readme.txt b/src/mkit/as/pngread/readme.txt index ff960ca3..1649b651 100644 --- a/src/mkit/as/pngread/readme.txt +++ b/src/mkit/as/pngread/readme.txt @@ -1,8 +1,8 @@ ***************************************************************************** ELMER'S NOTES FOR CONFIGURING LIBPNG & ZLIB ***************************************************************************** -2019-04-14 LIBPNG version 1.6.37 -2017-01-15 ZLIB version 1.2.11 +2024-02-23 LIBPNG version 1.6.43 +2024-01-22 ZLIB version 1.3.1 ***************************************************************************** diff --git a/src/mkit/as/pngread/zconf.h b/src/mkit/as/pngread/zconf.h index 5e1d68a0..62adc8d8 100644 --- a/src/mkit/as/pngread/zconf.h +++ b/src/mkit/as/pngread/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -38,6 +38,9 @@ # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op # define crc32_z z_crc32_z # define deflate z_deflate # define deflateBound z_deflateBound @@ -238,7 +241,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -293,14 +300,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -349,6 +348,9 @@ # ifdef FAR # undef FAR # endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ @@ -467,11 +469,18 @@ typedef uLong FAR uLongf; # undef _LARGEFILE64_SOURCE #endif -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif #endif #ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# if defined(Z_HAVE_UNISTD_H) # include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include /* for off_t */ @@ -507,7 +516,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/src/mkit/as/pngread/zlib.h b/src/mkit/as/pngread/zlib.h index f09cdaf1..8d4b932e 100644 --- a/src/mkit/as/pngread/zlib.h +++ b/src/mkit/as/pngread/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.11, January 15th, 2017 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.11" -#define ZLIB_VERNUM 0x12b0 +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 11 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -78,8 +78,8 @@ extern "C" { even in the case of corrupted input. */ -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); struct internal_state; @@ -217,7 +217,7 @@ typedef gz_header FAR *gz_headerp; /* basic functions */ -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +ZEXTERN const char * ZEXPORT zlibVersion(void); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check @@ -225,12 +225,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); */ /* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. + allocation functions. total_in, total_out, adler, and msg are initialized. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all @@ -247,7 +247,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); */ -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce @@ -276,7 +276,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput + which can be used if desired to determine whether or not there is more output in that case. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to @@ -320,8 +320,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was @@ -360,7 +360,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending @@ -375,7 +375,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by @@ -383,7 +383,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); read or consumed. The allocation of a sliding window will be deferred to the first call of inflate (if the decompression does not complete on the first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -397,7 +398,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); */ -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce @@ -517,7 +518,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending @@ -535,16 +536,15 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); */ /* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. + fields zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. @@ -608,9 +608,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this @@ -652,16 +652,16 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by deflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If deflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. + Similarly, if dictLength is Z_NULL, then it is not set. deflateGetDictionary() may return a length less than the window size, even when more than the window size in input has been provided. It may return up @@ -674,8 +674,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -692,31 +692,32 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate the internal compression state. The stream will leave the compression level and any other attributes that may have been - set unchanged. + set unchanged. total_in, total_out, adler, and msg are initialized. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2(). This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression approach (which is a function of the level) or the - strategy is changed, and if any input has been consumed in a previous - deflate() call, then the input available so far is compressed with the old - level and strategy using deflate(strm, Z_BLOCK). There are three approaches - for the compression levels 0, 1..3, and 4..9 respectively. The new level - and strategy will take effect at the next call of deflate(). + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does not have enough output space to complete, then the parameter change will not @@ -729,7 +730,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, Then no more input data should be provided before the deflateParams() call. If this is done, the old level and strategy will be applied to the data compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). + applied to the data compressed after deflateParams(). deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if @@ -740,11 +741,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, retried with more output space. */ -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for @@ -757,8 +758,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or @@ -772,9 +773,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, than Z_FINISH or Z_NO_FLUSH are used. */ -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not @@ -787,9 +788,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits @@ -804,8 +805,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, source stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called @@ -821,16 +822,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized @@ -865,9 +867,11 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will not automatically decode concatenated gzip streams. - inflate() will return Z_STREAM_END at the end of the gzip stream. The state - would need to be reset to continue decoding a subsequent gzip stream. + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -881,9 +885,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, deferred until inflate() is called. */ -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, @@ -904,22 +908,22 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If inflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. + Similarly, if dictLength is Z_NULL, then it is not set. inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent. */ -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); /* Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all @@ -932,14 +936,14 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -954,18 +958,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted @@ -978,9 +983,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, the windowBits parameter is invalid. */ -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the @@ -999,7 +1004,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the @@ -1027,8 +1032,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); source stream state was inconsistent. */ -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after @@ -1068,8 +1073,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, */ /* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized @@ -1089,13 +1094,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than @@ -1163,7 +1168,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, cannot return Z_OK. */ -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); /* All memory allocated by inflateBackInit() is freed. @@ -1171,7 +1176,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); state was inconsistent. */ -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: @@ -1224,8 +1229,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); you need special options. */ -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1239,9 +1244,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -1255,15 +1260,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, Z_STREAM_ERROR if the level parameter is invalid. */ -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1280,8 +1285,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of @@ -1300,16 +1305,16 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since @@ -1337,11 +1342,11 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); file could not be opened. */ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); /* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor @@ -1360,15 +1365,15 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); will not detect if fd is invalid (unless fd is -1). */ -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); /* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). @@ -1376,20 +1381,20 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); too late. */ -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); /* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not opened for writing, Z_ERRNO if there is an error writing the flushed data, or Z_MEM_ERROR if there is a memory allocation error. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); /* - Reads the given number of uncompressed bytes from the compressed file. If + Read and decompress up to len uncompressed bytes from file into buf. If the input file is not in gzip format, gzread copies the given number of bytes into the buffer directly from the file. @@ -1417,14 +1422,14 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); Z_STREAM_ERROR. */ -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); /* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. gzfread() returns the number of full items read of size size, or zero if the end of the file was reached and a full item could not be read, or if @@ -1435,26 +1440,24 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, In the event that the end of file is reached and only a partial item is available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf + multiple of size, then the final partial item is nevertheless read into buf and the end-of-file flag is set. The length of the partial item read is not provided, but could be inferred from the result of gztell(). This behavior is the same as the behavior of fread() implementations in common libraries, but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. + file, resetting and retrying on end-of-file, when size is not 1. */ -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); /* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. */ -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); /* - gzfwrite() writes nitems items of size size from buf to file, duplicating + Compress and write nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If the library defines size_t, then z_size_t is identical to size_t. If not, then z_size_t is an unsigned integer type that can contain a pointer. @@ -1465,61 +1468,62 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, is returned, and the error state is set to Z_STREAM_ERROR. */ -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); /* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or a negative zlib error code in case of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() + zlib was compiled with the insecure functions sprintf() or vsprintf(), because the secure snprintf() or vsnprintf() functions were not available. This can be determined using zlibCompileFlags(). */ -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); /* - Writes the given null-terminated string to the compressed file, excluding + Compress and write the given null-terminated string s to file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); /* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. gzgets returns buf which is a null-terminated string, or it returns NULL for end-of-file or in case of error. If there was an error, the contents at buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); /* - Writes c, converted to an unsigned char, into the compressed file. gzputc + Compress and write c, converted to an unsigned char, into file. gzputc returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc(gzFile file); /* - Reads one byte from the compressed file. gzgetc returns this byte or -1 + Read and decompress one byte from file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. As such, it does not do all of the checking the other functions do. I.e. it does not check to see if file is NULL, nor whether the structure file points to has been clobbered or not. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); /* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if c is -1, and may fail if a character has been pushed but not read yet. If gzungetc is used immediately after gzopen or gzdopen, at least the @@ -1528,11 +1532,11 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); /* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new @@ -1544,11 +1548,11 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); */ /* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. @@ -1563,52 +1567,52 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, would be before the current position. */ -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +ZEXTERN int ZEXPORT gzrewind(gzFile file); /* - Rewinds the given file. This function is supported only for reading. + Rewind file. This function is supported only for reading. - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). */ /* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ /* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. */ -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +ZEXTERN int ZEXPORT gzeof(gzFile file); /* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. If gzeof() returns true, then the read functions will return no more data, unless the end-of-file indicator is reset by gzclearerr() and the input file has grown since the previous end of file was detected. */ -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +ZEXTERN int ZEXPORT gzdirect(gzFile file); /* - Returns true (1) if file is being copied directly while reading, or false + Return true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. If the input file is empty, gzdirect() will return true, since the input @@ -1627,10 +1631,10 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); gzip file reading and decompression, which may not be desired.) */ -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose(gzFile file); /* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. gzclose must not be called more than once on the same file, just as free must not be called more than once on the same allocation. @@ -1640,8 +1644,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); last read ended in the middle of a gzip stream, or Z_OK on success. */ -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to @@ -1652,12 +1656,12 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); zlib library. */ -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); /* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is @@ -1668,9 +1672,9 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); functions above that do not distinguish those cases in their return values. */ -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +ZEXTERN void ZEXPORT gzclearerr(gzFile file); /* - Clears the error and end-of-file flags for file. This is analogous to the + Clear the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ @@ -1685,11 +1689,12 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); library. */ -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster. @@ -1704,15 +1709,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); /* Same as adler32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for @@ -1722,12 +1727,13 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, negative, the result has no meaning or utility. */ -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. Usage example: @@ -1739,20 +1745,34 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ -ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); /* Same as crc32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). len2 must be non-negative. +*/ + +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. */ @@ -1761,20 +1781,20 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); #ifdef Z_PREFIX_SET # define z_deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) @@ -1819,7 +1839,7 @@ struct gzFile_s { unsigned char *next; z_off64_t pos; }; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ @@ -1836,12 +1856,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ * without large file support, _LFS64_LARGEFILE must also be true */ #ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) @@ -1852,6 +1873,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define z_gzoffset z_gzoffset64 # define z_adler32_combine z_adler32_combine64 # define z_crc32_combine z_crc32_combine64 +# define z_crc32_combine_gen z_crc32_combine_gen64 # else # define gzopen gzopen64 # define gzseek gzseek64 @@ -1859,49 +1881,53 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define gzoffset gzoffset64 # define adler32_combine adler32_combine64 # define crc32_combine crc32_combine64 +# define crc32_combine_gen crc32_combine_gen64 # endif # ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); # endif #else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif #else /* Z_SOLO */ - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif /* !Z_SOLO */ /* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); # endif #endif diff --git a/src/mkit/as/pngread/zutil.c b/src/mkit/as/pngread/zutil.c index a76c6b0c..b1c5d2d3 100644 --- a/src/mkit/as/pngread/zutil.c +++ b/src/mkit/as/pngread/zutil.c @@ -24,13 +24,11 @@ z_const char * const z_errmsg[10] = { }; -const char * ZEXPORT zlibVersion() -{ +const char * ZEXPORT zlibVersion(void) { return ZLIB_VERSION; } -uLong ZEXPORT zlibCompileFlags() -{ +uLong ZEXPORT zlibCompileFlags(void) { uLong flags; flags = 0; @@ -61,9 +59,11 @@ uLong ZEXPORT zlibCompileFlags() #ifdef ZLIB_DEBUG flags += 1 << 8; #endif + /* #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif + */ #ifdef ZLIB_WINAPI flags += 1 << 10; #endif @@ -119,9 +119,7 @@ uLong ZEXPORT zlibCompileFlags() # endif int ZLIB_INTERNAL z_verbose = verbose; -void ZLIB_INTERNAL z_error (m) - char *m; -{ +void ZLIB_INTERNAL z_error(char *m) { fprintf(stderr, "%s\n", m); exit(1); } @@ -130,14 +128,12 @@ void ZLIB_INTERNAL z_error (m) /* exported to allow conversion of error code to string for compress() and * uncompress() */ -const char * ZEXPORT zError(err) - int err; -{ +const char * ZEXPORT zError(int err) { return ERR_MSG(err); } -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have +#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 + /* The older Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. */ @@ -146,22 +142,14 @@ const char * ZEXPORT zError(err) #ifndef HAVE_MEMCPY -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { uInt j; for (j = 0; j < len; j++) { @@ -170,10 +158,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len) return 0; } -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ @@ -214,8 +199,7 @@ local ptr_table table[MAX_PTR]; * a protected system like OS/2. Use Microsoft C instead. */ -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { voidpf buf; ulg bsize = (ulg)items*size; @@ -240,8 +224,7 @@ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) return buf; } -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; (void)opaque; @@ -277,14 +260,12 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return _halloc((long)items, size); } -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; _hfree(ptr); } @@ -297,25 +278,18 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); #endif -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; free(ptr); } diff --git a/src/mkit/as/pngread/zutil.h b/src/mkit/as/pngread/zutil.h index b079ea6a..48dd7feb 100644 --- a/src/mkit/as/pngread/zutil.h +++ b/src/mkit/as/pngread/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -29,10 +29,6 @@ # include #endif -#ifdef Z_SOLO - typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ -#endif - #ifndef local # define local static #endif @@ -46,10 +42,21 @@ typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; +#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) +# include +# if (ULONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long +# elif (ULLONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long long +# elif (UINT_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned +# endif +#endif + extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -130,17 +137,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -163,22 +161,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 @@ -188,8 +170,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* provide prototypes for these when building zlib without LFS */ #if !defined(_WIN32) && \ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); #endif /* common defaults */ @@ -228,16 +211,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemzero(dest, len) memset(dest, 0, len) # endif #else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); #endif /* Diagnostic functions */ #ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); + extern void ZLIB_INTERNAL z_error(char *m); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} @@ -254,9 +237,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif #ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); #endif #define ZALLOC(strm, items, size) \ diff --git a/src/mkit/as/proc.c b/src/mkit/as/proc.c index 8fad46f0..e56be7c6 100644 --- a/src/mkit/as/proc.c +++ b/src/mkit/as/proc.c @@ -6,15 +6,31 @@ #include "externs.h" #include "protos.h" -struct t_proc *proc_tbl[256]; -struct t_proc *proc_ptr; -struct t_proc *proc_first; -struct t_proc *proc_last; +t_proc *proc_tbl[HASH_COUNT]; +t_proc *proc_ptr; +t_proc *proc_first; +t_proc *proc_last; int proc_nb; int call_1st; int call_ptr; int call_bank; +/* this is set when suppressing the listing output of stripped procedures */ +/* n.b. fully compatible with 2-pass assembly because code is still built */ +int cloaking_stripped; + +/* this is set when not assembling the code within the stripped procedure */ +/* n.b. not compatible with 2-pass assembly because symbol addresses will */ +/* change because both multi-label and branch tracking counts will change */ +int skipping_stripped; + +/* this is set to say that skipping is an acceptable alternative to */ +/* cloaking, which means that we've decided to do a 3-pass assembly */ +int allow_skipping; + +/* set this to spew procedure stripping information to the tty */ +#define DEBUG_STRIPPING 0 + extern int dump_seg; /* protos */ @@ -24,6 +40,83 @@ void poke(int addr, int data); void proc_sortlist(void); +/* ---- + * add_thunk() + * ---- + * add a procedure thunk + */ + +void +add_thunk(struct t_proc *proc) +{ + if (!proc->call) { + /* init */ + if (call_bank > max_bank) { + /* don't increase ROM size until we need a thunk */ + if (call_bank > bank_limit) { + fatal_error("There is no target memory left to allocate a bank for .PROC thunks!"); + if (asm_opt[OPT_OPTIMIZE] == 0) { + fprintf(ERROUT, "Optimized procedure packing is currently disabled, use \"-O\" to enable.\n\n"); + } + return; + } + max_bank = call_bank; + } + + /* new call */ + if (newproc_opt == 0) { + /* check that the new thunk won't overrun the bank */ + if (((call_ptr + 17) & 0xE000) != (call_1st & 0xE000)) { + error("The .PROC thunk bank is full, there are too many procedures!"); + return; + } + + /* install HuC thunks at start of MPR4, map code into MPR5 */ + proc->call = call_ptr; + + poke(call_ptr++, 0xA8); // tay + poke(call_ptr++, 0x43); // tma #5 + poke(call_ptr++, 0x20); + poke(call_ptr++, 0x48); // pha + poke(call_ptr++, 0xA9); // lda #... + poke(call_ptr++, proc->label->mprbank); + poke(call_ptr++, 0x53); // tam #5 + poke(call_ptr++, 0x20); + poke(call_ptr++, 0x98); // tya + poke(call_ptr++, 0x20); // jsr ... + poke(call_ptr++, (proc->org + 0xA000) & 255); + poke(call_ptr++, (proc->org + 0xA000) >> 8); + poke(call_ptr++, 0xA8); // tay + poke(call_ptr++, 0x68); // pla + poke(call_ptr++, 0x53); // tam #5 + poke(call_ptr++, 0x20); + poke(call_ptr++, 0x98); // tya + poke(call_ptr++, 0x60); // rts + } else { + /* check that the new thunk won't overrun the bank */ + if (((call_ptr - 9) & 0xE000) != (call_1st & 0xE000)) { + error("The .PROC thunk bank is full, there are too many procedures!"); + return; + } + + /* install new thunks at end of MPR7, map code into MPR6 */ + poke(call_ptr--, (proc->org + 0xC000) >> 8); + poke(call_ptr--, (proc->org + 0xC000) & 255); + poke(call_ptr--, 0x4C); // jmp ... + poke(call_ptr--, 0x40); + poke(call_ptr--, 0x53); // tam #6 + poke(call_ptr--, proc->label->mprbank); + poke(call_ptr--, 0xA9); // lda #... + poke(call_ptr--, 0x48); // pha + poke(call_ptr--, 0x40); + poke(call_ptr--, 0x43); // tma #6 + + proc->call = call_ptr + 1; + } + } +} + + /* ---- * do_call() * ---- @@ -37,7 +130,7 @@ do_call(int *ip) /* define label, unless already defined in classC() instruction flow */ if (opflg == PSEUDO) - labldef(0, 0, LOCATION); + labldef(LOCATION); /* update location counter */ data_loccnt = loccnt; @@ -59,78 +152,9 @@ do_call(int *ip) value = proc->org + 0xA000; } else { /* different bank */ - if (proc->call) { - value = proc->call; - } else { - /* init */ - if (call_bank > max_bank) { - /* don't increase ROM size until we need a trampoline */ - if (call_bank > bank_limit) { - fatal_error("Not enough ROM space for proc trampolines!"); - if (asm_opt[OPT_OPTIMIZE] == 0) { - printf("Procedure optimization is currently disabled, use \"-O\" to enable.\n\n"); - } - return; - } - max_bank = call_bank; - } - - /* new call */ - if (newproc_opt == 0) { - /* check that the new trampoline won't overrun the bank */ - if (((call_ptr + 17) & 0xE000) != (call_1st & 0xE000)) { - error("No more space in bank for .proc trampoline!"); - if (asm_opt[OPT_OPTIMIZE] == 0) { - printf("Procedure optimization is currently disabled, use \"-O\" to enable.\n\n"); - } - return; - } - - /* install HuC trampolines at start of MPR4, map code into MPR5 */ - value = call_ptr; - - poke(call_ptr++, 0xA8); // tay - poke(call_ptr++, 0x43); // tma #5 - poke(call_ptr++, 0x20); - poke(call_ptr++, 0x48); // pha - poke(call_ptr++, 0xA9); // lda #... - poke(call_ptr++, proc->bank + bank_base); - poke(call_ptr++, 0x53); // tam #5 - poke(call_ptr++, 0x20); - poke(call_ptr++, 0x98); // tya - poke(call_ptr++, 0x20); // jsr ... - poke(call_ptr++, (proc->org + 0xA000) & 255); - poke(call_ptr++, (proc->org + 0xA000) >> 8); - poke(call_ptr++, 0xA8); // tay - poke(call_ptr++, 0x68); // pla - poke(call_ptr++, 0x53); // tam #5 - poke(call_ptr++, 0x20); - poke(call_ptr++, 0x98); // tya - poke(call_ptr++, 0x60); // rts - } else { - /* check that the new trampoline won't overrun the bank */ - if (((call_ptr - 9) & 0xE000) != (call_1st & 0xE000)) { - error("No more space in bank for .proc trampoline!"); - return; - } - - /* install new trampolines at end of MPR7, map code into MPR6 */ - poke(call_ptr--, (proc->org + 0xC000) >> 8); - poke(call_ptr--, (proc->org + 0xC000) & 255); - poke(call_ptr--, 0x4C); // jmp ... - poke(call_ptr--, 0x40); - poke(call_ptr--, 0x53); // tam #6 - poke(call_ptr--, proc->bank + bank_base); - poke(call_ptr--, 0xA9); // lda #... - poke(call_ptr--, 0x48); // pha - poke(call_ptr--, 0x40); - poke(call_ptr--, 0x43); // tma #6 - - value = call_ptr + 1; - } - - proc->call = value; - } + if (!proc->call) + add_thunk(proc); + value = proc->call; /* special handling for a jmp between procedures */ if ((newproc_opt != 0) && (optype == 1)) { @@ -176,7 +200,7 @@ void do_leave(int *ip) { /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* check end of line */ if (!check_eol(ip)) @@ -218,7 +242,7 @@ do_proc(int *ip) if (optype == P_KICKC) { /* reserve "{}" syntax for KickC code */ if (kickc_mode == 0) { - fatal_error("Cannot use \"{}\" syntax in .pceas mode!"); + fatal_error("Cannot use \"{}\" syntax in .PCEAS mode!"); return; } @@ -229,16 +253,22 @@ do_proc(int *ip) } } + /* not allowed while .phase is active */ + if (phase_offset) { + fatal_error("Cannot declare a .PROC/.PROCGROUP a .PHASE'd chunk of code!"); + return; + } + /* do not mix different types of label-scope */ if (scopeptr) { - fatal_error("Cannot declare a .proc/.procgroup inside a .struct!"); + fatal_error("Cannot declare a .PROC/.PROCGROUP inside a .STRUCT!"); return; } /* check if nesting procs/groups */ if (proc_ptr) { if (optype == P_PGROUP) { - fatal_error("Cannot declare a .procgroup inside a .proc/.procgroup!"); + fatal_error("Cannot declare a .PROCGROUP inside a .PROC/.PROCGROUP!"); return; } else { @@ -261,16 +291,19 @@ do_proc(int *ip) /* extract name */ if (!colsym(ip, 0)) { + /* was there a bad symbol */ if (symbol[0]) return; + + /* or just no symbol at all */ if (optype == P_PROC) { - fatal_error(".proc name is missing!"); + fatal_error(".PROC name is missing!"); return; } /* default name */ - sprintf(&symbol[1], "__group_%i__", proc_nb + 1); - symbol[0] = strlen(&symbol[1]); + sprintf(&symbol[1], "__group_%d_%d__", input_file[infile_num].file->number, slnum); + symbol[0] = (char)strlen(&symbol[1]); } /* lookup symbol table */ @@ -280,11 +313,11 @@ do_proc(int *ip) /* check symbol */ if (symbol[1] == '.' || symbol[1] == '@') { - fatal_error(".proc/.procgroup name cannot be a local label!"); + fatal_error(".PROC/.PROCGROUP name cannot be a local label!"); return; } if (symbol[1] == '!') { - fatal_error(".proc/.procgroup name cannot be a multi-label!"); + fatal_error(".PROC/.PROCGROUP name cannot be a multi-label!"); return; } @@ -293,19 +326,51 @@ do_proc(int *ip) return; /* search (or create new) proc */ - if((ptr = proc_look())) + if ((ptr = proc_look())) proc_ptr = ptr; else { if (!proc_install()) return; } if (pass == FIRST_PASS && proc_ptr->defined) { - fatal_error(".proc/.procgroup multiply defined!"); + fatal_error(".PROC/.PROCGROUP multiply defined!"); + return; + } + + /* reset location and size in case it changed due to skipping */ + if (pass != LAST_PASS) { + proc_ptr->org = proc_ptr->base = proc_ptr->group ? loccnt : 0; + proc_ptr->label->data_size = proc_ptr->size = 0; + } + + /* can we just not assemble a stripped .proc/.procgroup */ + /* at all instead of assembling it to the STRIPPED_BANK */ + if (proc_ptr->bank == STRIPPED_BANK && allow_skipping && proc_ptr->is_skippable) { + #if DEBUG_STRIPPING + printf("Skipping %s \"%s\" with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr = proc_ptr->group; + skipping_stripped = optype; + if (pass == LAST_PASS) { + println(); + } return; } + #if DEBUG_STRIPPING + printf("Assembling %s \"%s\" to bank %d with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", + proc_ptr->label->name + 1, + proc_ptr->bank, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + /* increment proc ref counter */ proc_ptr->defined = 1; + proc_ptr->is_skippable = if_level; /* backup current bank infos */ bank_glabl[section][bank] = proc_ptr->old_glablptr = glablptr; @@ -324,7 +389,7 @@ do_proc(int *ip) discontiguous = 1; /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* a KickC procedure also opens a label-scope */ if (optype == P_KICKC) { @@ -334,8 +399,13 @@ do_proc(int *ip) /* output */ if (pass == LAST_PASS) { - loadlc(loccnt, 0); - println(); + if (proc_ptr->bank == STRIPPED_BANK) { + println(); + ++cloaking_stripped; + } else { + loadlc(loccnt, 0); + println(); + } } } @@ -353,17 +423,23 @@ do_endp(int *ip) if (optype == P_KICKC) { /* reserve "{}" syntax for KickC code */ if (kickc_mode == 0) { - fatal_error("Cannot use \"{}\" syntax in .pceas mode!"); + fatal_error("Cannot use \"{}\" syntax in .PCEAS mode!"); return; } } + /* not allowed while .phase is active */ + if (phase_offset) { + fatal_error("Cannot .ENDP/.ENDPROCGROUP within a .PHASE'd chunk of code!"); + return; + } + if (proc_ptr == NULL) { - fatal_error("Unexpected .endp/.endprocgroup!"); + fatal_error("Unexpected .ENDP/.ENDPROCGROUP!"); return; } if (optype != proc_ptr->type) { - fatal_error("Unexpected .endp/.endprocgroup!"); + fatal_error("Unexpected .ENDP/.ENDPROCGROUP!"); return; } @@ -371,33 +447,21 @@ do_endp(int *ip) if (!check_eol(ip)) return; - /* restore procedure's initial section */ - if (section != proc_ptr->label->section) { - /* backup current section data */ - section_bank[section] = bank; - bank_glabl[section][bank] = glablptr; - bank_loccnt[section][bank] = loccnt; - bank_page[section][bank] = page; - - /* change section */ - section = proc_ptr->label->section; - - /* switch to the new section */ - bank = section_bank[section]; - page = bank_page[section][bank]; - loccnt = bank_loccnt[section][bank]; - glablptr = bank_glabl[section][bank]; - - /* signal discontiguous change in loccnt */ - discontiguous = 1; + /* disable skipping if the procedure starts and ends at different .if nesting */ + if (!(proc_ptr->is_skippable = (proc_ptr->is_skippable == if_level))) { + if (asm_opt[OPT_WARNING]) + warning(".PROC/.PROCGROUP has mismatched .IF nesting!\n"); } + /* restore procedure's initial section */ + set_section(proc_ptr->label->section); + /* define label */ - labldef(0, 0, LOCATION); + labldef(LOCATION); /* sanity check */ if (bank != proc_ptr->bank) { - fatal_error(".endp/.endprocgroup is in a different bank to .proc/,procgroup!"); + fatal_error(".ENDP/.ENDPROCGROUP is in a different bank to .PROC/.PROCGROUP!"); return; } @@ -420,6 +484,13 @@ do_endp(int *ip) discontiguous = 1; } + #if DEBUG_STRIPPING + printf("Ending %s \"%s\" with parent \"%s\".\n", + optype == P_PROC ? ".PROC" : ".PROCGROUP", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr = proc_ptr->group; /* a KickC procedure also closes the label-scope */ @@ -433,8 +504,86 @@ do_endp(int *ip) } /* output */ - if (pass == LAST_PASS) + if (pass == LAST_PASS) { + if (cloaking_stripped) + --cloaking_stripped; println(); + } +} + + +/* ---- + * proc_strip() + * ---- + * + */ + +void +proc_strip(void) +{ + int num_stripped = 0; + + if (proc_nb == 0) + return; + + if (strip_opt == 0) + return; + + /* calculate the refthispass for each group */ + proc_ptr = proc_first; + + while (proc_ptr) { + /* proc within a group */ + if (proc_ptr->group != NULL) { + proc_ptr->group->label->refthispass += proc_ptr->label->refthispass; + } + proc_ptr = proc_ptr->link; + } + + /* strip out the groups and procs with zero references */ + proc_ptr = proc_first; + + while (proc_ptr) { + + /* group or standalone proc */ + if (proc_ptr->group == NULL) { + /* strip this .proc or .procgroup? */ + if (proc_ptr->label->refthispass < 1) { + /* strip this unused code from the ROM */ + #if DEBUG_STRIPPING + printf("Stripping %s \"%s\" with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr->bank = STRIPPED_BANK; + --proc_nb; + ++num_stripped; + } + } + + /* proc within a group */ + else { + /* strip this .proc? */ + if ((proc_ptr->group->bank == STRIPPED_BANK) || + (proc_ptr->label->refthispass < 1 && allow_skipping && proc_ptr->is_skippable)) { + /* strip this unused code from the ROM */ + #if DEBUG_STRIPPING + printf("Stripping %s \"%s\" with parent \"%s\".\n", + proc_ptr->type == P_PROC ? ".PROC" : ".PROCGROUP", + proc_ptr->label->name + 1, + proc_ptr->group == NULL ? "none" : proc_ptr->group->label->name + 1); + #endif + proc_ptr->bank = STRIPPED_BANK; + --proc_nb; + ++num_stripped; + } + } + + /* next */ + proc_ptr->defined = 0; + proc_ptr = proc_ptr->link; + } } @@ -477,40 +626,30 @@ proc_reloc(void) new_bank = max_bank + 1; } + /* alloc memory */ proc_ptr = proc_first; - /* sum up each group's refcnt */ - while (proc_ptr) { - /* proc within a group */ - if (proc_ptr->group != NULL) { - proc_ptr->group->label->refcnt += proc_ptr->label->refcnt; - } - proc_ptr = proc_ptr->link; - } - - proc_ptr = proc_first; - - /* alloc memory */ while (proc_ptr) { /* group or standalone proc */ if (proc_ptr->group == NULL) { - /* relocate or strip? */ - if ((strip_opt != 0) && (proc_ptr->label->refcnt < 1)) { - /* strip this unused code from the ROM */ - proc_ptr->bank = STRIPPED_BANK; - } else { + /* relocate if not stripped */ + if (proc_ptr->bank != STRIPPED_BANK) { /* relocate code to any unused bank in ROM */ int reloc_bank = -1; int check_bank = 0; + int check_last = 0; int smallest = 0x2000; while (reloc_bank == -1) { check_bank = (asm_opt[OPT_OPTIMIZE]) ? 0 : max_bank; - for (; check_bank <= max_bank; check_bank++) + /* limit procs to the first 64 banks if using the SF2 mapper */ + check_last = (section_flags[S_DATA] & S_IS_SF2) ? 63 : max_bank; + + for (; check_bank <= check_last; check_bank++) { /* don't use a full bank, even if proc_ptr->size==0 */ if ((bank_free[check_bank] != 0) && (bank_free[check_bank] >= proc_ptr->size)) @@ -525,46 +664,46 @@ proc_reloc(void) if (reloc_bank == -1) { - /* need new bank */ - if (++max_bank > bank_limit) { + /* new bank needed, is there space below 1MB? */ + if ((max_bank >= 127) || (max_bank >= bank_limit)) { int total = 0, totfree = 0; struct t_proc *current = NULL; current = proc_ptr; - fatal_error("\nThere is not enough free memory for all the procedures!\n"); + fatal_error("There is not enough free target memory for all the procedures!\n"); if (asm_opt[OPT_OPTIMIZE] == 0) { - printf("Procedure optimization is currently disabled, use \"-O\" to enable.\n\n"); + fprintf(ERROUT, "Optimized procedure packing is currently disabled, use \"-O\" to enable.\n\n"); } - for (i = new_bank; i < max_bank; i++) { - printf("BANK %02X: %d bytes free\n", i, bank_free[i]); + for (i = new_bank; i <= max_bank; i++) { + fprintf(ERROUT, "BANK %3X: %d bytes free\n", i, bank_free[i]); totfree += bank_free[i]; } - printf("\nTotal free space in all banks %d.\n\n", totfree); + fprintf(ERROUT, "\nTotal free space in all banks %d.\n\n", totfree); total = 0; proc_ptr = proc_first; while (proc_ptr) { if (proc_ptr->bank == PROC_BANK) { - printf("Proc: %s Bank: 0x%02X Size: %4d %s\n", - proc_ptr->name, proc_ptr->bank == PROC_BANK ? 0 : proc_ptr->bank, proc_ptr->size, + fprintf(ERROUT, "Proc: %s Bank: 0x%02X Size: %4d %s\n", + proc_ptr->label->name + 1, proc_ptr->bank == PROC_BANK ? 0 : proc_ptr->bank, proc_ptr->size, proc_ptr->bank == PROC_BANK && proc_ptr == current ? " ** too big **" : proc_ptr->bank == PROC_BANK ? "** unassigned **" : ""); total += proc_ptr->size; } proc_ptr = proc_ptr->link; } - printf("\nTotal bytes that didn't fit in ROM: %d\n\n", total); + fprintf(ERROUT, "\nTotal bytes that didn't fit in ROM: %d\n\n", total); if (totfree > total && current) - printf("Try splitting the \"%s\" procedure into smaller chunks.\n\n", current->name); + fprintf(ERROUT, "Try splitting the \"%s\" procedure into smaller chunks.\n\n", current->label->name + 1); else - printf("There are %d bytes that won't fit into the currently available BANK space\n\n", total - totfree); + fprintf(ERROUT, "There are %d bytes that won't fit into the currently available BANK space\n\n", total - totfree); errcnt++; return; } - reloc_bank = max_bank; + reloc_bank = ++max_bank; } } @@ -581,7 +720,8 @@ proc_reloc(void) else { /* reloc proc */ group = proc_ptr->group; - proc_ptr->bank = group->bank; + if (proc_ptr->bank != STRIPPED_BANK) + proc_ptr->bank = group->bank; proc_ptr->org += (group->org - group->base); } @@ -594,7 +734,7 @@ proc_reloc(void) bank_free = NULL; /* remap proc symbols */ - for (i = 0; i < 256; i++) { + for (i = 0; i < HASH_COUNT; i++) { sym = hash_tbl[i]; while (sym) { @@ -602,19 +742,19 @@ proc_reloc(void) /* remap addr */ if (sym->proc) { - if (proc_ptr->bank == STRIPPED_BANK) - sym->bank = STRIPPED_BANK; - else - sym->bank = proc_ptr->bank + bank_base; - - sym->value = (sym->value & 0x007FFFFF); - sym->value += (proc_ptr->org - proc_ptr->base); - - /* KickC can't call bank(), so put it in the label */ - if (proc_ptr->kickc) { - sym->value += sym->bank << 23; + if (proc_ptr->bank == STRIPPED_BANK) { + sym->rombank = + sym->mprbank = STRIPPED_BANK; + sym->overlay = 0; + } else { + sym->rombank = proc_ptr->bank; + sym->mprbank = bank2mprbank(sym->rombank, sym->section); + sym->overlay = bank2overlay(sym->rombank, sym->section); } + if (sym->phase == 0) + sym->value += (proc_ptr->org - proc_ptr->base); + /* local symbols */ if (sym->local) { local = sym->local; @@ -624,18 +764,18 @@ proc_reloc(void) /* remap addr */ if (local->proc) { - if (proc_ptr->bank == STRIPPED_BANK) - local->bank = STRIPPED_BANK; - else - local->bank = proc_ptr->bank + bank_base; - - local->value = (local->value & 0x007FFFFF); - local->value += (proc_ptr->org - proc_ptr->base); - - /* KickC can't call bank(), so put it in the label */ - if (proc_ptr->kickc) { - local->value += local->bank << 23; + if (proc_ptr->bank == STRIPPED_BANK) { + local->rombank = + local->mprbank = STRIPPED_BANK; + local->overlay = 0; + } else { + local->rombank = proc_ptr->bank; + local->mprbank = bank2mprbank(local->rombank, local->section); + local->overlay = bank2overlay(local->rombank, local->section); } + + if (local->phase == 0) + local->value += (proc_ptr->org - proc_ptr->base); } /* next */ @@ -651,9 +791,8 @@ proc_reloc(void) /* reset */ proc_ptr = NULL; - proc_nb = 0; - /* initialize trampoline bank/addr after relocation */ + /* initialize thunk bank/addr after relocation */ if (newproc_opt) { call_bank = 0; call_ptr = 0xFFF5; @@ -676,12 +815,15 @@ proc_reloc(void) /* install code for leaving .proc */ /* fix do_proc() if this changes! */ poke(call_ptr--, 0x60); // rts - poke(call_ptr--, 0x98); // tya + if (hucc_opt) + poke(call_ptr--, 0x8A); // txa + else + poke(call_ptr--, 0x98); // tya poke(call_ptr--, 0x40); poke(call_ptr--, 0x53); // tam #6 poke(call_ptr--, 0x68); // pla - lablset("leave_proc", call_ptr + 1 + (call_bank << 23)); + lablset("leave_proc", call_ptr + 1); } } @@ -702,7 +844,7 @@ proc_look(void) hash = symhash(); ptr = proc_tbl[hash]; while (ptr) { - if (!strcmp(&symbol[1], ptr->name)) + if (!strcmp(symbol, ptr->label->name)) break; ptr = ptr->next; } @@ -732,7 +874,6 @@ proc_install(void) } /* initialize it */ - strcpy(ptr->name, &symbol[1]); hash = symhash(); ptr->bank = (optype == P_PGROUP) ? GROUP_BANK : PROC_BANK; ptr->base = proc_ptr ? loccnt : 0; @@ -741,6 +882,7 @@ proc_install(void) ptr->call = 0; ptr->kickc = kickc_mode; ptr->defined = 0; + ptr->is_skippable = 0; ptr->link = NULL; ptr->next = proc_tbl[hash]; ptr->group = proc_ptr; @@ -773,7 +915,7 @@ proc_install(void) void poke(int addr, int data) { - /* do not overwrite existing data! check_trampolines() will report */ + /* do not overwrite existing data! check_thunks() will report */ /* this error later on and show a segment dump to provide help */ if ((map[call_bank][(addr & 0x1FFF)] & 0x0F) == 0x0F) { rom[call_bank][(addr & 0x1FFF)] = data; @@ -812,9 +954,9 @@ proc_sortlist(void) struct t_proc *previous = NULL; while(!inserted && list) { - if(list->size < proc_ptr->size) + if (list->size < proc_ptr->size) { - if(!previous) + if (!previous) sorted_list = proc_ptr; else previous->link = proc_ptr; @@ -828,7 +970,7 @@ proc_sortlist(void) } } - if(!inserted) + if (!inserted) previous->link = proc_ptr; } } @@ -850,9 +992,9 @@ list_procs(void) if ((lst_fp != NULL) && (proc_ptr != NULL) && (fprintf(lst_fp, "\nPROCEDURE LIST (in order of size):\n\n") > 0)) { while (proc_ptr) { - if ((proc_ptr->group == NULL) && (proc_ptr->bank < RESERVED_BANK)) { - if (fprintf( lst_fp, "Size: $%04X, Addr: $%02X:%04X, %s %s\n", proc_ptr->size, proc_ptr->bank, proc_ptr->label->value, - (proc_ptr->type == P_PGROUP) ? ".procgroup" : " .proc" , proc_ptr->name) < 0) + if ((proc_ptr->group == NULL) && (proc_ptr->bank < UNDEFINED_BANK)) { + if (fprintf(lst_fp, "Size: $%04X, Addr: $%02X:%04X, %s %s\n", proc_ptr->size, proc_ptr->bank, proc_ptr->label->value, + (proc_ptr->type == P_PGROUP) ? ".procgroup" : " .proc" , proc_ptr->label->name + 1) < 0) break; } proc_ptr = proc_ptr->link; @@ -862,13 +1004,13 @@ list_procs(void) /* ---- - * check_trampolines() + * check_thunks() * ---- * were they overwritten by other code/data? */ int -check_trampolines(void) +check_thunks(void) { int first_bad = -1; int final_bad = -1; @@ -892,11 +1034,11 @@ check_trampolines(void) } if (first_bad >= 0) { - printf("Error: .proc trampolines between $%04X-$%04X are overwritten by code or data!\n\nTrampoline Bank ...\n", + fatal_error(".PROC thunks between $%04X-$%04X are overwritten by code or data!\n\nThunk Bank ...\n", first_bad, final_bad); dump_seg = 2; - show_bnk_usage(call_bank); - printf("\n"); + show_bank_usage(ERROUT, call_bank); + fprintf(ERROUT, "\n"); return (1); } return (0); diff --git a/src/mkit/as/protos.h b/src/mkit/as/protos.h index 85fe5d7b..88c20306 100644 --- a/src/mkit/as/protos.h +++ b/src/mkit/as/protos.h @@ -47,7 +47,6 @@ void do_org(int *ip); void do_bank(int *ip); void do_incbin(int *ip); void do_mx(char *fname); -void forget_included_files(void); void do_include(int *ip); void do_rsset(int *ip); void do_rs(int *ip); @@ -57,25 +56,30 @@ void do_section(int *ip); void do_incchr(int *ip); void do_opt(int *ip); void do_align(int *ip); +void do_3pass(int *ip); void do_kickc(int *ip); -void do_cpu(int *ip); +void do_ignore(int *ip); void do_segment(int *ip); void do_star(int *ip); void do_label(int *ip); -void do_encoding(int *ip); void do_struct(int *ip); void do_ends(int *ip); +void do_alias(int *ip); +void do_ref(int *ip); +void do_phase(int *ip); int htoi(char *str, int nb); +void set_section(int new_section); /* CRC.C */ -void crc_init(void); -unsigned int crc_calc(unsigned char *data, int len); +unsigned int crc_calc(const unsigned char *data, int len); +unsigned int filename_crc(const char *name); /* EXPR.C */ int evaluate(int *ip, char flag, char allow_bank); int push_val(int type); int getsym(struct t_symbol * curscope); -int check_keyword(void); +int check_keyword(char * name); +int check_prefix(char * name); int push_op(int op); int do_op(void); int check_func_args(char *func_name); @@ -92,9 +96,12 @@ int add_path(char*, int); void cleanup_path(void); int init_path(void); int readline(void); -int open_input(char *name); +const char *remember_string(const char * string, size_t length); +t_file *remember_file(int hash); +void clear_included(void); +int open_input(const char *name); int close_input(void); -FILE *open_file(char *fname, char *mode); +FILE *open_file(const char *fname, const char *mode); /* MACRO.C */ void do_macro(int *ip); @@ -106,10 +113,9 @@ int macro_getargtype(char *arg); /* MAIN.C */ int main(int argc, char **argv); -int calc_bank_base(void); void help(void); -void show_bnk_usage(int which_bank); -void show_seg_usage(void); +void show_bank_usage(FILE *fp, int which_bank); +void show_seg_usage(FILE *fp); /* MAP.C */ int pce_load_map(char *fname, int mode); @@ -125,9 +131,9 @@ void putword(int offset, int data); void putdword(int offset, int data); void putbuffer(void *data, int size); void write_srec(char *fname, char *ext, int base); -void error(char *stptr); -void warning(char *stptr); -void fatal_error(char *stptr); +void error(const char *format, ...); +void warning(const char *format, ...); +void fatal_error(const char *format, ...); /* PCX.C */ int pcx_pack_8x8_tile(unsigned char *buffer, int x, int y); @@ -144,13 +150,15 @@ int png_load(char *name); int bmp_load(char *name); /* PROC.C */ +void add_thunk(struct t_proc *proc); void do_call(int *ip); void do_leave(int *ip); void do_proc(int *ip); void do_endp(int *ip); +void proc_strip(void); void proc_reloc(void); void list_procs(void); -int check_trampolines(void); +int check_thunks(void); /* SYMBOL.C */ int symhash(void); @@ -158,9 +166,12 @@ int addscope(struct t_symbol * curscope, int i); int colsym(int *ip, int flag); struct t_symbol *stlook(int flag); struct t_symbol *stinstall(int hash, int type); -int labldef(int lval, int lbnk, int lsrc); +int labldef(int reason); void lablset(char *name, int val); int lablexists(char *name); void lablremap(void); void labldump(FILE *fp); -void lablresetdefcnt(void); +void lablstartpass(void); +int bank2mprbank (int what_bank, int what_section); +int bank2overlay (int what_bank, int what_section); +int mprbank2bank (int what_bank, int what_overlay); diff --git a/src/mkit/as/symbol.c b/src/mkit/as/symbol.c index 0dd1671b..7463983e 100644 --- a/src/mkit/as/symbol.c +++ b/src/mkit/as/symbol.c @@ -40,7 +40,7 @@ symhash(void) int addscope(struct t_symbol * curscope, int i) { - char * string; + const char * string; /* stop at the end of scope chain */ if (curscope == NULL) { @@ -80,13 +80,27 @@ colsym(int *ip, int flag) int j; char c; + /* convert an SDCC local-symbol into a PCEAS local-symbol */ + if (sdcc_mode && (prlnbuf[(*ip)+5] == '$') && + isdigit((symbol[2] = prlnbuf[(*ip)+0])) && + isdigit((symbol[3] = prlnbuf[(*ip)+1])) && + isdigit((symbol[4] = prlnbuf[(*ip)+2])) && + isdigit((symbol[5] = prlnbuf[(*ip)+3])) && + isdigit((symbol[6] = prlnbuf[(*ip)+4]))) { + symbol[0] = 6; + symbol[1] = '@'; + symbol[7] = '\0'; + (*ip) += 6; + return (6); + } + /* prepend the current scope? */ c = prlnbuf[*ip]; if ((flag != 0) && (scopeptr != NULL) && (c != '.') && (c != '@') && (c != '!')) { i = addscope(scopeptr, i); } - /* remember where the symbol itself starts */ + /* remember where the symbol itself starts after the scope */ j = i; /* get the symbol */ @@ -105,15 +119,19 @@ colsym(int *ip, int flag) if (i == j) { i = 0; } symbol[0] = i; - symbol[i + 1] = '\0'; - if (i >= SBOLSZ - 1) { - char errorstr[512]; - snprintf(errorstr, 512, "Symbol name too long ('%s' is %d chars long, max is %d)", symbol + 1, i, SBOLSZ - 2); - fatal_error(errorstr); + if (i == SBOLSZ - 1) { + symbol[SBOLSZ - 1] = '\0'; + fatal_error("Symbol name too long, maximum is %d characters.", SBOLSZ - 2); return (0); } + symbol[i + 1] = '\0'; + + /* skip passed the first ':' if there are two in SDCC code */ + if (sdcc_mode && (prlnbuf[*ip] == ':') && (prlnbuf[(*ip)+1] == ':')) + (*ip)++; + /* check if it's a reserved symbol */ if (i == 1) { switch (toupper(symbol[1])) { @@ -124,14 +142,12 @@ colsym(int *ip, int flag) break; } } - if (check_keyword()) + if (check_keyword(symbol)) err = 1; /* error */ if (err) { fatal_error("Reserved symbol!"); -// symbol[0] = 0; -// symbol[1] = '\0'; return (0); } @@ -195,9 +211,15 @@ stlook(int type) } } + /* resolve symbol alias */ + unaliased = sym; + while ((sym != NULL) && (sym->type == ALIAS)) { + sym = sym->local; + } + /* increment symbol reference counter */ - if ((sym != NULL) && (type == SYM_REF)) { - sym->refcnt++; + if ((sym != NULL) && (type == SYM_REF) && (if_expr == 0)) { + sym->refthispass++; } /* ok */ @@ -223,24 +245,30 @@ stinstall(int hash, int type) } /* init the symbol struct */ - sym->type = if_expr ? IFUNDEF : UNDEF; - sym->value = 0; sym->local = NULL; sym->scope = NULL; sym->proc = NULL; - sym->section = -1; - sym->bank = RESERVED_BANK; + sym->reason = -1; + sym->type = if_expr ? IFUNDEF : UNDEF; + sym->value = 0; + sym->phase = 0; + sym->section = S_NONE; + sym->overlay = 0; + sym->mprbank = UNDEFINED_BANK; + sym->rombank = UNDEFINED_BANK; + sym->page = -1; sym->nb = 0; sym->size = 0; - sym->page = -1; sym->vram = -1; sym->pal = -1; - sym->defcnt = 0; - sym->refcnt = 0; sym->reserved = 0; sym->data_type = -1; sym->data_size = 0; - strcpy(sym->name, symbol); + sym->deflastpass = 0; + sym->reflastpass = 1; /* so that .ifref triggers in 1st pass */ + sym->defthispass = 0; + sym->refthispass = 0; + sym->name = remember_string(symbol, (size_t)symbol[0] + 2); /* add the symbol to the hash table */ if (type) { @@ -267,16 +295,41 @@ stinstall(int hash, int type) */ int -labldef(int lval, int lbnk, int lsrc) +labldef(int reason) { char c; + int labl_value, labl_rombank, labl_mprbank, labl_overlay, labl_section; /* check for NULL ptr */ if (lablptr == NULL) return (0); - /* adjust symbol address */ - if (lsrc == LOCATION) { + /* is the symbol already used for somthing else */ + if (lablptr->type == ALIAS) { + error("Symbol already used by an alias!"); + return (-1); + } + if (lablptr->type == MACRO) { + error("Symbol already used by a macro!"); + return (-1); + } + if (lablptr->type == FUNC) { + error("Symbol already used by a function!"); + return (-1); + } + + if (lablptr->reserved) { + fatal_error("Reserved symbol!"); + return (-1); + } + + /* remember where this was defined */ + lablptr->fileinfo = input_file[infile_num].file; + lablptr->fileline = slnum; + + if (reason == LOCATION) { + /* label is set from the current LOCATION */ + /* is this a multi-label? */ if (lablptr->name[1] == '!') { char tail [10]; @@ -289,9 +342,9 @@ labldef(int lval, int lbnk, int lsrc) /* define the next multi-label instance */ strcpy(symbol, lablptr->name); - sprintf(tail, "!%d", 0x7FFFF & ++(lablptr->defcnt)); + sprintf(tail, "!%d", 0x7FFFF & ++(lablptr->defthispass)); strncat(symbol, tail, SBOLSZ - 1 - strlen(symbol)); - symbol[0] = strlen(&symbol[1]); + symbol[0] = (char)strlen(&symbol[1]); if ((lablptr = stlook(SYM_DEF)) == NULL) { fatal_error("Out of memory!"); return (-1); @@ -306,101 +359,84 @@ labldef(int lval, int lbnk, int lsrc) page = (page + 1) & 7; } - lval = loccnt + (page << 13); - - if (bank >= RESERVED_BANK) - lbnk = bank; - else - lbnk = bank_base + bank; - - /* KickC can't call bank(), so put it in the label */ - if (kickc_mode) - lval += lbnk << 23; + labl_value = (loccnt + (page << 13) + phase_offset) & 0xFFFF; + labl_rombank = bank; + labl_mprbank = bank2mprbank(bank, section); + labl_overlay = bank2overlay(bank, section); + labl_section = section; } else { + /* label is a CONSTANT or VARIABLE set from the current expression */ + /* is this a multi-label? */ if (lablptr->name[1] == '!') { /* sanity check */ fatal_error("A multi-label can only be a location!"); return (-1); } - } - - /* record definition */ - lablptr->defcnt = 1; - - /* first pass or still undefined */ - if ((pass == FIRST_PASS) || (lablptr->type == UNDEF)) { - if (pass != FIRST_PASS) { - /* needed for KickC forward-references */ - need_another_pass = 1; - } - - switch (lablptr->type) { - /* undefined */ - case UNDEF: - case IFUNDEF: - lablptr->type = DEFABS; - lablptr->bank = lbnk; - lablptr->value = lval; - break; - /* already defined - error */ - case MACRO: - error("Symbol already used by a macro!"); - return (-1); + labl_value = value; + labl_mprbank = expr_mprbank; + labl_overlay = expr_overlay; + labl_rombank = mprbank2bank(expr_mprbank, expr_overlay); + labl_section = (labl_rombank < UNDEFINED_BANK) ? S_DATA : S_NONE; + } - case FUNC: - error("Symbol already used by a function!"); - return (-1); +// /* needed for forward-references (in KickC and elsewhere) */ +// if ((pass != FIRST_PASS) && (lablptr->type == UNDEF)) { +// if (pass_count < 3) +// need_another_pass = 1; +// } - default: - /* reserved label */ - if (lablptr->reserved) { - fatal_error("Reserved symbol!"); - return (-1); - } + /* allow ".set" to change a label's value at any time */ + if ((reason == VARIABLE) && (lablptr->reason == VARIABLE)) + lablptr->type = UNDEF; - /* compare the values */ - if (lablptr->value == lval) - break; - - /* normal label */ - lablptr->type = MDEF; - lablptr->value = 0; - error("Label multiply defined!"); - return (-1); - } + /* is the symbol currently undefined? */ + if ((lablptr->type == UNDEF) || (lablptr->type == IFUNDEF)) { + /* allow the definition */ } - - /* branch pass */ - else if (pass != LAST_PASS) { - if (lablptr->type == DEFABS) { - if ((lablptr->value != lval) || - ((lsrc == LOCATION) && (bank < bank_limit) && (lablptr->bank != bank_base + bank))) { - /* needed for KickC forward-references */ - need_another_pass = 1; - } - lablptr->bank = lbnk; - lablptr->value = lval; - } + /* don't allow the reason, or the value, to change during a single pass */ + else if ((lablptr->reason != reason) || + (lablptr->defthispass && lablptr->value != labl_value)) { + /* normal label */ + lablptr->type = MDEF; + lablptr->value = 0; + error("Label was already defined differently!"); + return (-1); } - - /* last pass */ - else { - if ((lablptr->value != lval) || - ((lsrc == LOCATION) && (bank < bank_limit) && (lablptr->bank != bank_base + bank))) { - fatal_error("Symbol's bank or address changed in final pass!"); + /* make sure that nothing changes at all in the last pass */ + else if (pass == LAST_PASS) { + if ((lablptr->value != labl_value) || (lablptr->overlay != labl_overlay) || + ((reason == LOCATION) && (labl_mprbank < UNDEFINED_BANK) && (lablptr->mprbank != labl_mprbank))) { + error("Symbol's bank or address changed in final pass!"); + #if 0 + fprintf(ERROUT, "lablptr->value = $%04x, labl_value = $%04x\n", lablptr->value, labl_value); + fprintf(ERROUT, "lablptr->mprbank = $%02x, labl_mprbank = $%02x\n", lablptr->mprbank, labl_mprbank); + fprintf(ERROUT, "lablptr->rombank = $%02x, labl_rombank = $%02x\n", lablptr->rombank, labl_rombank); + #endif return (-1); } } - /* update symbol data */ - if (lsrc == LOCATION) { - lablptr->section = section; + /* record definition */ + lablptr->defthispass = 1; - if (section == S_CODE) + /* update symbol data */ + lablptr->reason = reason; + lablptr->type = DEFABS; + lablptr->value = labl_value; +// if (labl_rombank < UNDEFINED_BANK) /* Don't overwrite with undefined */ + lablptr->rombank = labl_rombank; +// if (labl_mprbank < UNDEFINED_BANK) /* Don't overwrite with undefined */ + lablptr->mprbank = labl_mprbank; + lablptr->overlay = labl_overlay; + lablptr->section = labl_section; + + if (reason == LOCATION) { + if (section_flags[section] & S_IS_CODE) lablptr->proc = proc_ptr; + lablptr->phase = phase_offset; lablptr->page = page; /* check if it's a local or global symbol */ @@ -432,7 +468,7 @@ lablset(char *name, int val) { int len; - len = strlen(name); + len = (int)strlen(name); lablptr = NULL; if (len) { @@ -443,7 +479,7 @@ lablset(char *name, int val) if (lablptr) { lablptr->type = DEFABS; lablptr->value = val; - lablptr->defcnt = 1; + lablptr->defthispass = 1; lablptr->reserved = 1; } } @@ -464,7 +500,7 @@ lablexists(char *name) { int len; - len = strlen(name); + len = (int)strlen(name); lablptr = NULL; if (len) { @@ -495,7 +531,7 @@ lablremap(void) int i; /* browse the symbol table */ - for (i = 0; i < 256; i++) { + for (i = 0; i < HASH_COUNT; i++) { sym = hash_tbl[i]; while (sym) { /* remap the bank */ @@ -540,15 +576,24 @@ labldump(FILE *fp) fprintf(fp, "----\t----\t-----\n"); /* browse the symbol table */ - for (i = 0; i < 256; i++) { + for (i = 0; i < HASH_COUNT; i++) { for (sym = hash_tbl[i]; sym != NULL; sym = sym->next) { /* skip undefined symbols and stripped symbols */ - if ((sym->type != DEFABS) || (sym->bank == STRIPPED_BANK) || (sym->name[1] == '!')) + if ((sym->type != DEFABS) || (sym->mprbank == STRIPPED_BANK) || (sym->name[1] == '!')) continue; /* dump the label */ - fprintf(fp, "%2.2x\t%4.4x\t", sym->bank, sym->value & 0xFFFF); + if (sym->mprbank >= UNDEFINED_BANK) + fprintf(fp, " -"); + else if (sym->overlay == 0) + fprintf(fp, " %2.2x", sym->mprbank); + else + fprintf(fp, "%1.1x:%2.2x", sym->overlay, sym->mprbank); + + fprintf(fp, "\t%4.4x\t", sym->value & 0xFFFF); + fprintf(fp, "%s\t", &(sym->name[1])); + if (strlen(&(sym->name[1])) < 8) fprintf(fp, "\t"); if (strlen(&(sym->name[1])) < 16) @@ -562,8 +607,16 @@ labldump(FILE *fp) local = sym->local; while (local) { - fprintf(fp, "%2.2x\t%4.4x\t", local->bank, local->value & 0xFFFF); + if (local->mprbank >= UNDEFINED_BANK) + fprintf(fp, " -"); + else if (sym->overlay == 0) + fprintf(fp, " %2.2x", local->mprbank); + else + fprintf(fp, "%1.1x:%2.2x", local->overlay, local->mprbank); + + fprintf(fp, "\t%4.4x\t", local->value & 0xFFFF); fprintf(fp, "\t%s\t", &(local->name[1])); + if (strlen(&(local->name[1])) < 8) fprintf(fp, "\t"); if (strlen(&(local->name[1])) < 16) @@ -580,29 +633,35 @@ labldump(FILE *fp) /* ---- - * lablresetdefcnt + * lablstartpass * ---- - * clear the defcnt on all the multi-labels + * reset symbol definition and reference tracking */ void -lablresetdefcnt(void) +lablstartpass(void) { struct t_symbol *sym; int i; /* browse the symbol table */ - for (i = 0; i < 256; i++) { + for (i = 0; i < HASH_COUNT; i++) { sym = hash_tbl[i]; while (sym) { - sym->defcnt = 0; + sym->deflastpass = sym->defthispass; + sym->defthispass = 0; + sym->reflastpass = sym->refthispass; + sym->refthispass = 0; /* local symbols */ if (sym->local) { struct t_symbol * local = sym->local; while (local) { - local->defcnt = 0; + local->deflastpass = local->defthispass; + local->defthispass = 0; + local->reflastpass = local->refthispass; + local->refthispass = 0; /* next */ local = local->next; @@ -614,3 +673,66 @@ lablresetdefcnt(void) } } } + + +/* ---- + * bank2mprbank + * ---- + * convert a bank number into a value to put into an MPR register + */ + +int bank2mprbank (int what_bank, int what_section) +{ + if ((section_flags[what_section] & S_IS_ROM) && (what_bank < UNDEFINED_BANK)) { + if ((section_flags[what_section] & S_IS_SF2) && (what_bank > 0x7F)) { + /* for StreetFighterII banks in ROM */ + what_bank = 0x40 + (what_bank & 0x3F); + } else { + /* for all non-SF2, CD, SCD code and data banks */ + what_bank = what_bank + bank_base; + } + } + return (what_bank); +} + + +/* ---- + * bank2overlay + * ---- + * convert a bank number into an overlay number + */ + +int bank2overlay (int what_bank, int what_section) +{ + if ((section_flags[what_section] & S_IS_ROM) && (what_bank < UNDEFINED_BANK)) { + if ((section_flags[what_section] & S_IS_SF2) && (what_bank > 0x7F)) { + /* for StreetFighterII banks in ROM */ + return (what_bank / 0x40) - 1; + } + } + return (0); +} + + +/* ---- + * mprbank2bank + * ---- + * convert an overlay and MPR register value into a bank number + */ + +int mprbank2bank (int what_bank, int what_overlay) +{ + if (what_overlay != 0) { + if ((section_flags[S_DATA] & S_IS_SF2) == 0) { + error("You can only use overlays with the StreetFighterII mapper!"); + return (UNDEFINED_BANK); + } + if ((what_bank < 0x40) || (what_bank > 0x7F)) { + error("Invalid bank and overlay for the StreetFighterII mapper!"); + return (UNDEFINED_BANK); + } + return (what_bank + what_overlay * 0x40); + } + what_bank = what_bank - bank_base; + return (what_bank <= bank_limit) ? what_bank : UNDEFINED_BANK; +} diff --git a/src/mkit/as/vars.h b/src/mkit/as/vars.h index 6b9a96c3..98d213ad 100644 --- a/src/mkit/as/vars.h +++ b/src/mkit/as/vars.h @@ -1,91 +1,88 @@ -unsigned char rom[128][8192]; -unsigned char map[128][8192]; -char bank_name[128][64]; -int bank_loccnt[4][256]; -int bank_page[4][256]; -int bank_maxloc[256]; /* record max location in bank */ -int discontiguous; /* NZ signals a warp in loccnt */ -int max_zp; /* higher used address in zero page */ -int max_bss; /* higher used address in ram */ -int max_bank; /* last bank used */ -int data_loccnt; /* data location counter */ -int data_size; /* size of binary output (in bytes) */ -int data_level; /* data output level, must be <= listlevel to be outputed */ -int loccnt; /* location counter */ -int bank; /* current bank */ -int bank_base; /* bank base index */ -int rom_limit; /* bank limit */ -int bank_limit; /* rom max. size in bytes */ -int page; /* page */ -int rsbase; /* .rs counter */ -int rsbank; /* .rs counter */ -int section; /* current section: S_ZP, S_BSS, S_CODE or S_DATA */ -int section_bank[4]; /* current bank for each section */ -int stop_pass; /* stop the program; set by fatal_error() */ -int errcnt; /* error counter */ -int kickc_mode; /* NZ if assembling KickC code */ -int kickc_incl; /* auto-include "kickc-final.asm" */ -int preproc_inblock; /* C-style comment: within block comment */ -int preproc_sfield; /* C-style comment: SFIELD as a variable */ -int preproc_modidx; /* C-style comment: offset to modified char */ -struct t_machine *machine; -struct t_opcode *inst_tbl[256]; /* instructions hash table */ -struct t_symbol *hash_tbl[256]; /* label hash table */ -struct t_symbol *lablptr; /* label pointer into symbol table */ -struct t_symbol *glablptr; /* pointer to the latest defined global label */ -struct t_symbol *scopeptr; /* pointer to the latest defined scope label */ -struct t_symbol *lastlabl; /* last label we have seen */ -struct t_symbol *bank_glabl[4][256]; /* latest global symbol for each bank */ -struct t_branch *branchlst; /* first branch instruction assembled */ -struct t_branch *branchptr; /* last branch instruction assembled */ -int xvertlong; /* count of branches fixed in pass */ -char need_another_pass; /* NZ if another pass if required */ -char hex[5]; /* hexadecimal character buffer */ -void (*opproc)(int *); /* instruction gen proc */ -int opflg; /* instruction flags */ -int opval; /* instruction value */ -int optype; /* instruction type */ -char opext; /* instruction extension (.l or .h) */ -int pass; /* pass counter */ -char prlnbuf[LAST_CH_POS + 4]; /* input line buffer */ -char tmplnbuf[LAST_CH_POS + 4]; /* temporary line buffer */ -int slnum; /* source line number counter */ -char symbol[SBOLSZ + 1]; /* temporary symbol storage */ -int undef; /* undefined symbol in expression flg */ -int notyetdef; /* undefined-in-current-pass symbol in expr */ -unsigned int value; /* operand field value */ +unsigned char rom[MAX_BANKS][8192]; +unsigned char map[MAX_BANKS][8192]; +char bank_name[MAX_BANKS][64]; +int bank_loccnt[MAX_S][MAX_BANKS]; +int bank_page[MAX_S][MAX_BANKS]; +int bank_maxloc[MAX_BANKS]; /* record max location in bank */ + +int discontiguous; /* NZ signals a warp in loccnt */ +int max_zp; /* higher used address in zero page */ +int max_bss; /* higher used address in ram */ +int max_bank; /* last bank used */ +int data_loccnt; /* data location counter */ +int data_size; /* size of binary output (in bytes) */ +int data_level; /* data output level, must be <= listlevel to be outputed */ +int phase_offset; /* location counter offset for .phase */ +int loccnt; /* location counter */ +int bank; /* current bank */ +int bank_base; /* bank base index */ +int rom_limit; /* bank limit */ +int bank_limit; /* rom max. size in bytes */ +int page; /* page */ +int rs_base; /* .rs counter */ +int rs_mprbank; /* .rs counter */ +int rs_overlay; /* .rs counter */ +int section; /* current section: S_ZP, S_BSS, S_CODE or S_DATA */ +int section_bank[MAX_S]; /* current bank for each section */ +int section_phase[MAX_S]; /* current phase offset for each section */ +int stop_pass; /* stop the program; set by fatal_error() */ +int errcnt; /* error counter */ +int kickc_mode; /* NZ if assembling KickC code */ +int sdcc_mode; /* NZ if assembling SDCC code */ +int hucc_mode; /* NZ if assembling HuCC code */ +int kickc_final; /* auto-include "kickc-final.asm" */ +int hucc_final; /* auto-include "hucc-final.asm" */ +int in_final; /* set when in xxxx-final.asm include */ +int preproc_inblock; /* C-style comment: within block comment */ +int preproc_sfield; /* C-style comment: SFIELD as a variable */ +int preproc_modidx; /* C-style comment: offset to modified char */ + +t_machine *machine; +t_opcode *inst_tbl[HASH_COUNT]; /* instructions hash table */ +t_symbol *hash_tbl[HASH_COUNT]; /* label hash table */ +t_symbol *lablptr; /* label pointer into symbol table */ +t_symbol *glablptr; /* pointer to the latest defined global label */ +t_symbol *scopeptr; /* pointer to the latest defined scope label */ +t_symbol *lastlabl; /* last label we have seen */ +t_symbol *bank_glabl[MAX_S][MAX_BANKS]; /* latest global symbol for each bank */ +t_symbol *unaliased; /* unaliased version of last symbol lookup */ +t_branch *branchlst; /* first branch instruction assembled */ +t_branch *branchptr; /* last branch instruction assembled */ + +int branches_changed; /* count of branches changed in pass */ +char need_another_pass; /* NZ if another pass if required */ +char hex[5]; /* hexadecimal character buffer */ +void (*opproc)(int *); /* instruction gen proc */ +int opflg; /* instruction flags */ +int opval; /* instruction value */ +int optype; /* instruction type */ +char opext; /* instruction extension (.l or .h) */ +int pass; /* pass type (FIRST_PASS, EXTRA_PASS, LAST_PASS */ +int pass_count; /* pass counter */ +char prlnbuf[LAST_CH_POS + 4]; /* input line buffer */ +char tmplnbuf[LAST_CH_POS + 4]; /* temporary line buffer */ +int slnum; /* source line number counter */ +char symbol[SBOLSZ]; /* temporary symbol storage */ +int undef; /* undefined symbol in expression flg */ +int notyetdef; /* undefined-in-current-pass symbol in expr */ +unsigned int value; /* operand field value */ + int opvaltab[6][16] = { - {0x08, 0x08, 0x04, 0x14, 0x14, 0x11, 0x00, 0x10, // ADC AND CMP EOR LDA ORA SBC STA - 0x0C, 0x1C, 0x18, 0x2C, 0x3C, 0x00, 0x00, 0x00}, + {0x08, 0x08, 0x04, 0x14, 0x14, 0x11, 0x00, 0x10, // ADC AND CMP EOR LDA ORA SBC STA + 0x0C, 0x1C, 0x18, 0x2C, 0x3C, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x04, 0x14, 0x14, 0x00, 0x00, 0x10, // CPX CPY LDX LDY LAX ST0 ST1 ST2 - 0x0C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x04, 0x14, 0x14, 0x00, 0x00, 0x10, // CPX CPY LDX LDY LAX ST0 ST1 ST2 + 0x0C, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x89, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00, // BIT - 0x2C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x89, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00, // BIT + 0x2C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x3A, 0x00, 0xC6, 0xD6, 0x00, 0x00, 0x00, 0x00, // DEC - 0xCE, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x3A, 0x00, 0xC6, 0xD6, 0x00, 0x00, 0x00, 0x00, // DEC + 0xCE, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x1A, 0x00, 0xE6, 0xF6, 0x00, 0x00, 0x00, 0x00, // INC - 0xEE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x1A, 0x00, 0xE6, 0xF6, 0x00, 0x00, 0x00, 0x00, // INC + 0xEE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x64, 0x74, 0x00, 0x00, 0x00, 0x00, // STZ - 0x9C, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + {0x00, 0x00, 0x64, 0x74, 0x00, 0x00, 0x00, 0x00, // STZ + 0x9C, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; - -/* -define ACC 0x0000001 0 -define IMM 0x0000002 1 -define ZP 0x0000004 2 -define ZP_X 0x0000008 3 -define ZP_Y 0x0000010 4 -define ZP_IND 0x0000020 5 -define ZP_IND_X 0x0000040 6 -define ZP_IND_Y 0x0000080 7 -define ABS 0x0000100 8 -define ABS_X 0x0000200 9 -define ABS_Y 0x0000400 A -define ABS_IND 0x0000800 B -define ABS_IND_X 0x0001000 C -*/ diff --git a/src/mkit/as/xgetopt.c b/src/mkit/as/xgetopt.c new file mode 100644 index 00000000..7c181698 --- /dev/null +++ b/src/mkit/as/xgetopt.c @@ -0,0 +1,505 @@ +/******************************************************************************* + * Copyright (c) 2016 hklo.tw@gmail.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + ******************************************************************************** + * Original source repository ... https://github.com/matthklo/xgetopt + * + * All original xopt* and xget* labels have changed to opt* and get* so that this + * is a drop-in replacement for the GNU/BSD functions on Windows. + * + * Error messages have been changed to make them more consistent with MSYS2. + * + * In getopt_long_only(), ambiguous single letter options now try short options. + ********************************************************************************/ + +#ifdef _MSC_VER +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#endif + +#include +#include +#include +#include "xgetopt.h" + +// Instance of extern global variables +int optind; +int optopt; +int opterr = 1; +int optreset; +char *optarg; + +// A local-scope variable. +// Used for tracking parsing point within the same argument element. +static char *optcur; + +static int getopt_impl(int argc, char * const argv[], + const char *optstring, const struct option *longopts, + int *longindex, char only); + +// Permute an argv array. So that all non-option element will be +// moved to the end of argv with respect to their original presenting order. +static void getopt_permute(int argc, char * const argv[], + const char *optstring, const struct option *longopts, + char only) +{ + // Tweak the optstring: + // 1. Remove any heading GNU flags ('+','-') at front of it (if any). + // 2. Insert a single '+' at the front. + char *pstr = 0; + if (optstring == 0) + { +#ifdef _MSC_VER + pstr = _strdup("+"); +#else + pstr = strdup("+"); +#endif + } + else + { + int len = (int)strlen(optstring); + pstr = (char*)malloc(len+2); + memset(pstr, 0, len+2); + while (((*optstring) == '+') || ((*optstring) == '-')) + optstring++; + pstr[0] = '+'; + strcpy(&pstr[1], optstring); + } + + // Clone longopts and tweak on flag and val. + struct option *x = 0; + if (longopts) + { + int cnt; + for (cnt=0; (longopts[cnt].name != 0) || (longopts[cnt].flag != 0) || (longopts[cnt].has_arg != 0) || (longopts[cnt].val != 0); ++cnt); + x = (struct option*) malloc(sizeof(struct option) * (cnt+1)); + memset(x, 0, sizeof(struct option) * (cnt+1)); + for (int i=0; i= argc) || (0 == argv)) + { + optind = argc; + if (permute) + getopt_permute(argc, argv, optstring, longopts, only); + return -1; + } + + // Check whether optind has been changed since the last valid getopt_impl call. + // Reset optcur to NULL if does. + if (optcur) + { + char inrange = 0; + for (char * p = argv[optind]; *p != '\0'; ++p) + { + if (p != optcur) continue; + inrange = 1; + break; + } + + if (!inrange) + optcur = 0; + } + + // Check the content of argv[optind], to see if it is: + // 1. Non-option argument (not start with '-') + // 2. A solely '-' or '--' + // 3. A option which starts with '-' or '--' + while (optind < argc) + { + // case 1 + if (!optcur && (argv[optind][0] != '-')) + { + if (argofone) + { + optarg = argv[optind++]; + return 1; + } + else if (permute) + { + optind++; + continue; + } + return -1; + } + + // case 2 + if (!optcur && + ((0 == strcmp("-", argv[optind])) || + (0 == strcmp("--", argv[optind])))) + { + optind++; + break; + } + + // case 3 + const char *p = (argv[optind][1] == '-')? &argv[optind][2] : &argv[optind][1]; + + // matching long opts + do + { + if (!longopts || optcur || ((argv[optind][1] != '-') && !only)) + break; // continue to match short opts ... + + const char *r; + r = strchr(p, '='); + int plen = (r)? (int)(r-p) : (int)strlen(p); + + const struct option *xo = 0; + int hitcnt = 0; + for (const struct option *x = longopts; ; ++x) + { + if (!x->name && !x->flag && !x->has_arg && !x->val) // terminating case: option == {0,0,0,0} + break; + + if (!x->name) + continue; + + // Long option names may be abbreviated if the abbreviation + // is unique or is an exact match for some defined option. + if (0 == strncmp(p, x->name, plen)) + { + xo = x; + hitcnt++; + // is this an exact match? + if (plen == strlen(x->name)) + { + hitcnt = 1; + break; + } + } + } + + if (!xo) // unrecognized option + { + if (only) + break; // continue to match short opts.. + + if (opterr) + fprintf(stderr, "%s: unknown option \"%s\"\n\n", progname, argv[optind]); + optind++; + return '?'; + } + else if (hitcnt > 1) // ambiguous + { + if ((only) && (plen == 1)) + break; // continue to match short opts.. + + if (opterr) + fprintf(stderr, "%s: option \"%s\" is ambiguous\n\n", progname, argv[optind]); + optind++; + return '?'; + } + + if (longindex) + *longindex = (int)(xo - longopts); + + switch (xo->has_arg) + { + case required_argument: // argument required + case optional_argument: // optional argument + { + char valid = 1; + int curind = optind++; + + // Check whether the argument is provided as inline. i.e.: '--opt=argument' + const char *q = strchr(p, '='); + if (q) // Has inline argument. + { + optarg = (char*)(q+1); + } + else if (xo->has_arg == optional_argument) // No inline argument implies no argument for 'optional_argument' + { + ; + } + else if (optind < argc) // For required_argument, use the next arg value if no inline argument present. + { + optarg = argv[optind++]; + } + else // Missing argument. + { + valid = 0; + } + + if (valid) + { + if (xo->flag == 0) + return xo->val; + *xo->flag = xo->val; + return 0; + } + + if (opterr) + fprintf(stderr, "%s: option \"%s\" requires an argument\n\n", progname, argv[curind]); + if (missingarg) + return ':'; + } + return '?'; + + default: // no argument + optind++; + if (xo->flag == 0) + return xo->val; + *xo->flag = xo->val; + return 0; + } + } while (0); + + // matching short opts ... + if (optcur) + p = optcur; + optarg = 0; + const char *d = strchr(optstring, *p); + if (d && ((0 == strncmp(d+1, "::", 2)) || (*(d+1) == ':'))) + { + optind++; + optarg = 0; + optcur = 0; + const char required = (*(d+2) != ':') ? 1 : 0; + if (*(p+1) != '\0') + { + optarg = (char*)(p+1); + } + else if ((optind < argc) && (required || (argv[optind][0] != '-'))) + { + optarg = argv[optind]; + optind++; + } + else if (required) + { + if (opterr) + fprintf(stderr, "%s: option \"-%c\" requires an argument\n\n", progname, *p); + optopt = *p; + return (missingarg)? ':': '?'; + } + return *p; + } + + if (*(p+1) != '\0') + { + optcur = (char*)(p+1); + } + else + { + optind++; + optcur = 0; + } + + if (!d) + { + optopt = *p; + if (!missingarg && opterr) + fprintf(stderr, "%s: unknown option -- %c\n\n", progname, *p); + return '?'; + } + + return *p; + } // end of while (optind < argc) + + if (permute) + getopt_permute(argc, argv, optstring, longopts, only); + + return -1; +} + +int getopt(int argc, char * const argv[], const char *optstring) +{ + return getopt_impl(argc, argv, optstring, 0, 0, 0); +} + +int getopt_long(int argc, char * const argv[], const char *optstring, + const struct option *longopts, int *longindex) +{ + return getopt_impl(argc, argv, optstring, longopts, longindex, 0); +} + +int getopt_long_only(int argc, char * const argv[], const char *optstring, + const struct option *longopts, int *longindex) +{ + return getopt_impl(argc, argv, optstring, longopts, longindex, 1); +} + +int getsubopt(char **optionp, char * const *tokens, char **valuep) +{ + char *p = *optionp; + char *n = 0; + char *a = 0; + int ret = -1; + int nlen = 0; + char stop = 0; + + for (n=p; !stop; ++n) + { + switch(*n) + { + case '=': + if (!a) a = n + 1; + break; + case ',': + case '\0': + *optionp = (*n == ',')? n+1 : n; + *n = '\0'; + stop = 1; + break; + default: + if (!a) nlen++; + break; + } + } + + char found = 0; + for (int i=0; (nlen > 0) && (tokens[i] != NULL); ++i) + { + if (0 == strncmp(tokens[i], p, nlen)) + { + found = 1; + ret = i; + break; + } + } + + *valuep = (found)? a: p; + return ret; +} + diff --git a/src/mkit/as/xgetopt.h b/src/mkit/as/xgetopt.h new file mode 100644 index 00000000..627b6278 --- /dev/null +++ b/src/mkit/as/xgetopt.h @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2016 hklo.tw@gmail.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + ******************************************************************************** + * Original source repository ... https://github.com/matthklo/xgetopt + * + * All original xopt* and xget* labels have changed to opt* and get* so that this + * is a drop-in replacement for the GNU/BSD functions on Windows. + * + * Error messages have been changed to make them more consistent with MSYS2. + * + * In getopt_long_only(), ambiguous single letter options now try short options. + ********************************************************************************/ + + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *optarg; +extern int optind; +extern int opterr; +extern int optopt; +extern int optreset; + + +/***** + * This is a cross-platform implementation of legacy getopt related functions. + * Here provides 4 functions: getopt(), getopt_long(), getopt_long_only(), + * and getsubopt() which mimic almost the same functionality of both GNU + * and BSD's version of getopt(), getopt_long(), getopt_long_only, and + * getsubopt(). + * + * Since there were some differences between GNU and BSD's getopt impl, getopt + * have to choose a side on those differences. Here list the behaviours: + * + * Argv permuting: + * GNU: By default would permute the argv so that all non-option argv eventually + * will be moved to the end of argv. User can disable permuting by specifying + * a '+' char in the optstring. + * BSD: No permuting. + * xgetopt: Follow GNU. Both '+' and '-' flags in the front of optstring can be recognized + * and should work properly. + * + * value of optopt: + * GNU: Set optopt only when either meet an undefined option, or detect on a missing + * argument. + * BSD: Always set it to be the option code which is currently examining at. + * xgetopt: Follow GNU. + * + * value of optarg: + * GNU: Reset to 0 at the start of every getopt() call. + * BSD: No reseting. It remains the same value until next write by getopt(). + * xgetopt: Follow GNU. + * + * Reset state for parsing a new argc/argv set: + * GNU: Simply reset optind to be 1. However, it is impossible to reset parsing + * state when an internal short option parsing is taking place in argv[1]. + * BSD: Use another global boolean 'optreset' for this purpose. + * xgetopt: Both behaviours are supported. + * + * -W special case: + * GNU: If "W;" is present in optstring, the "-W foo" in commandline will be + * treated as the long option "--foo". + * BSD: No mentioned in the man page but seems to support such usage. + * xgetopt: Do NOT support -W special case. + */ + +int getopt( + int argc, + char * const argv[], + const char *optstr); + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +#define no_argument (0) +#define required_argument (1) +#define optional_argument (2) + +int getopt_long( + int argc, + char * const argv[], + const char *optstring, + const struct option *longopts, + int *longindex); + +int getopt_long_only( + int argc, + char * const argv[], + const char *optstring, + const struct option *longopts, + int *longindex); + + +int getsubopt( + char **optionp, + char * const *tokens, + char **valuep); + +#ifdef __cplusplus +} +#endif diff --git a/src/tools/Makefile b/src/tools/Makefile index 305c4175..9b6bdf5f 100644 --- a/src/tools/Makefile +++ b/src/tools/Makefile @@ -2,7 +2,7 @@ # Makefile for HuC tools sources # -SUBDIRS = pcxtool mod2mml mml wav2vox sym2inc pce2png +SUBDIRS = pcxtool mod2mml mml wav2vox sym2inc pce2png hulz all clean: @$(MAKE) $(SUBDIRS) "COMMAND=$@" diff --git a/src/tools/hulz/Makefile b/src/tools/hulz/Makefile new file mode 100644 index 00000000..9e585cae --- /dev/null +++ b/src/tools/hulz/Makefile @@ -0,0 +1,42 @@ +# Makefile for hulz +# +# Written for Linux development version, September 27, 2001 by Dave Shadoff +# + +# +# Defines +# + +BASEDIR=..d ..d .. +include ../../Make_src.inc + +HDRS = elmer.h targetver.h +OBJS = hulz.o + +LIBS = + +EXE = hulz$(EXESUFFIX) + +# +# Subdirectories +# + +all:: + $(MAKE) $(EXE) + +# +# Executable +# + +$(EXE): $(OBJS) $(LIBS) $(HDRS) + $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + $(CP) $(EXE) $(BINDIR) + +# +# Targets +# + +include $(MAKETARG) + +clean:: + rm -f $(EXE) $(BINDIR)/$(EXE) $(OBJS) diff --git a/src/tools/hulz/elmer.h b/src/tools/hulz/elmer.h new file mode 100644 index 00000000..811ca43e --- /dev/null +++ b/src/tools/hulz/elmer.h @@ -0,0 +1,82 @@ +// ************************************************************************** +// ************************************************************************** +// +// elmer.h +// +// General type definitions. +// +// Copyright John Brandwood 1994-2021. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// ************************************************************************** +// ************************************************************************** + +#ifndef __ELMER_h +#define __ELMER_h + +#ifdef _WIN32 + #include "targetver.h" + #define WIN32_LEAN_AND_MEAN + #include +#endif + +// +// Standard C99 includes, with Visual Studio workarounds. +// + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined (_MSC_VER) + #include + #define SSIZE_MAX UINT_MAX + #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) + #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) + #define strcasecmp _stricmp + #define strncasecmp _strnicmp +#else + #include + #ifndef O_BINARY + #define O_BINARY 0 + #define O_TEXT 0 + #endif +#endif + +#if defined (_MSC_VER) && (_MSC_VER < 1600) // i.e. before VS2010 + #define __STDC_LIMIT_MACROS + #include "msinttypes/stdint.h" +#else + #include +#endif + +#if defined (_MSC_VER) && (_MSC_VER < 1800) // i.e. before VS2013 + #define static_assert( test, message ) + #include "msinttypes/inttypes.h" + #include "msinttypes/stdbool.h" +#else + #include + #include +#endif + +// DETERMINE TARGET MACHINE BYTE ORDERING ... +// +// either BYTE_ORDER_LO_HI for 80x86 ordering, +// or BYTE_ORDER_HI_LO for 680x0 ordering. + +#ifdef PC + #define BYTE_ORDER_LO_HI 1 + #define BYTE_ORDER_HI_LO 0 +#endif + +#endif // __ELMER_h diff --git a/src/tools/hulz/hulz.c b/src/tools/hulz/hulz.c new file mode 100644 index 00000000..0354996e --- /dev/null +++ b/src/tools/hulz/hulz.c @@ -0,0 +1,2083 @@ +// ************************************************************************** +// ************************************************************************** +// +// HULZ.C +// +// Simple compressor for some LZSS-derived schemes found on the PC Engine. +// +// Copyright John Brandwood 2014-2024. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// ************************************************************************** +// ************************************************************************** + +#include "elmer.h" + +// +// DEFINITIONS +// + +#ifndef GIT_VERSION + #define GIT_VERSION "unknown" +#endif + +#ifndef GIT_DATE + #define GIT_DATE __DATE__ +#endif + +#define VERSION_STR "hulz (" GIT_VERSION ", " GIT_DATE ")" + +// Which compressor has been chosen? + +typedef uint8_t * (*compressor) ( + uint8_t * pSrcBuffer, + unsigned uSrcLength, + uint8_t * pDstBuffer, + unsigned uDstLength ); + +compressor g_pCompressorFunc = NULL; +compressor g_pDecompressFunc = NULL; + +// + +bool g_fDecompress = false; +bool g_fLazyMatch = true; + +uint8_t * g_pOutBuffer; +unsigned g_uOutLength; + +int g_iWindowFix; + + + +// ************************************************************************** +// ************************************************************************** +// +// BitInit () +// BitWriteHiLo () +// BitWriteLoHi () +// +// Bit-oriented buffered output to global g_pOutBuffer. +// + +unsigned g_uOutMask; +uint8_t * g_pOutBits = NULL; + +void BitInit ( void ) +{ + g_pOutBits = NULL; +} + +void BitWriteHiLo ( unsigned uBitValue ) +{ + if (g_pOutBits == NULL) { + g_uOutMask = 0x80; + g_pOutBits = g_pOutBuffer; + *g_pOutBuffer++ = 0; + } + + if (uBitValue & 1) { + *g_pOutBits |= g_uOutMask; + } + + g_uOutMask >>= 1; + + if (g_uOutMask == 0) { + g_pOutBits = NULL; + } +} + +void BitWriteLoHi ( unsigned uBitValue ) +{ + if (g_pOutBits == NULL) { + g_uOutMask = 0x01; + g_pOutBits = g_pOutBuffer; + *g_pOutBuffer++ = 0; + } + + if (uBitValue & 1) { + *g_pOutBits |= g_uOutMask; + } + + g_uOutMask <<= 1; + + if (g_uOutMask == 256) { + g_pOutBits = NULL; + } +} + + + +// ************************************************************************** +// ************************************************************************** +// +// NibbleInit () +// NibbleWriteHiLo () +// +// Nibble-oriented buffered output to global g_pOutBuffer. +// + +uint8_t * g_pNibble = NULL; + +void NibbleInit ( void ) +{ + g_pNibble = NULL; +} + +void NibbleWriteHiLo ( unsigned uValue ) +{ + if (g_pNibble == NULL) + { + g_pNibble = g_pOutBuffer++; + + *g_pNibble = (uValue & 15) << 4; + } else { + *g_pNibble = (uValue & 15) | *g_pNibble; + + g_pNibble = NULL; + } +} + + + +// ************************************************************************** +// ************************************************************************** +// +// InitStringMatch () +// +// Simple hash-based string search for Lempel-Ziv compression. +// +// HASH_WIN_SIZE is the size of the hash window used to track previous string +// occurrences, do not confuse it with the iMaxLzssDelta used to search for a +// current match! +// +// HASH_WIN_SIZE must be a power-of-two that is >= the largest iMaxLzssDelta. +// +// There is no harm to having a HASH_WIN_SIZE > iMaxLzssDelta, it just takes +// up more memory during compression. +// + +#define HASH_VAL_SIZE 16384 +#define CALC_HASH( iSrcOffset ) ((pSrcBuffer[ iSrcOffset + 0 ] & 0x7F) + 128 * (pSrcBuffer[ iSrcOffset + 1 ] & 0x7F)) + +#define HASH_WIN_SIZE 0x2000 // Use a default 8KB tracking window on the PC Engine. +#define HASH_WIN_MASK (HASH_WIN_SIZE - 1) + +// Array of the most recent source-offset for every possible hash value. + +int * g_pHashOffset; + +// Array of previous source-offset with the same hash value for every window location +// in the tracking window. + +int * g_pPrevOffset; + +// + +void InitStringMatch ( void ) +{ + int i; + + if (g_pHashOffset == NULL) { + g_pHashOffset = (int *) malloc( sizeof(int) * (HASH_VAL_SIZE + HASH_WIN_SIZE) ); + g_pPrevOffset = g_pHashOffset + HASH_VAL_SIZE; + } + + // Initialize the hash table. + + for (i = 0; i < HASH_VAL_SIZE; ++i) { + g_pHashOffset[i] = - 1; + } +} + + + +// ************************************************************************** +// ************************************************************************** +// +// FindStringMatch () +// +// Simple hash-based string search for Lempel-Ziv compression. +// +// HASH_WIN_SIZE is the size of the hash window used to track previous string +// occurrences, do not confuse it with the iMaxLzssDelta used to search for a +// current match! +// +// HASH_WIN_SIZE must be a power-of-two that is >= the largest iMaxLzssDelta. +// +// There is no harm to having a HASH_WIN_SIZE > iMaxLzssDelta, it just takes +// up more memory during compression. +// + +void __inline FindStringMatch ( + int * pFoundOffset, int * pFoundLength, + const uint8_t * pSrcBuffer, const int iSrcLength, + int iFromOffset, int iMaxLzssDelta, int iMaxLzssLength ) + +{ + // Local Variables. + + int iMinOffset = ((iFromOffset - iMaxLzssDelta) < 0) ? 0 : (iFromOffset - iMaxLzssDelta); + int iBestOffset = iMinOffset; + int iBestLength = 0; + int iTestOffset = g_pHashOffset[ CALC_HASH( iFromOffset ) ]; + int iTestLength; + + // Don't read beyond the pSrcBuffer. + + iMaxLzssLength = ((iSrcLength - iFromOffset) < iMaxLzssLength) ? (iSrcLength - iFromOffset) : iMaxLzssLength; + + // Stop searching when the test string is outside the iMaxLzssDelta window. + + while (iTestOffset >= iMinOffset) + { + // Quickly reject strings that won't be longer than the current-best. + + if (pSrcBuffer[ iFromOffset + iBestLength ] == pSrcBuffer[ iTestOffset + iBestLength ]) + { + iTestLength = 0; + + while ((iTestLength < iMaxLzssLength) && + (pSrcBuffer[ iFromOffset + iTestLength ] == pSrcBuffer[ iTestOffset + iTestLength ])) { + ++iTestLength; + } + + if (iTestLength > iBestLength) { + iBestOffset = iTestOffset; + iBestLength = iTestLength; + if (iBestLength == iMaxLzssLength) break; + } + } + + // Test the previous string with the same CALC_HASH() value. + + iTestOffset = g_pPrevOffset[ iTestOffset & HASH_WIN_MASK ]; + } + + *pFoundOffset = iBestOffset; + *pFoundLength = iBestLength; +} + + + +// ************************************************************************** +// ************************************************************************** +// +// CompressHLZ () +// +// Compress data in Hudson's 4-bit length, 8-bit offset LZSS. +// +// The window offset is stored as relative to the start of the data, and not +// as a delta from the current output, but some games start decompressing to +// their 256 byte ring-buffer at $xxEF intead of $xx00, and so an offset has +// to be added to the window address that is written. +// +// With a window start of $EF, this method is used by (at least) ... +// Tengai Makyo II - Manji Maru +// Dragon Slayer - The Legend of Heroes II +// Emerald Dragon +// Linda3 +// +// With a window start of $00, this method is used by (at least) ... +// Ys IV - The Dawn of Ys +// Gulliver Boy +// +// The bit buffer is stored hi-lo. +// The nibble buffer is stored hi-lo. +// +// Ys4 and Gulliver add a 1-byte header to signal whether the compressed data +// is encoded in byte (0) or word (1) format. +// +// This compressor does NOT handle Ys4's word format scheme! +// + +uint8_t * CompressHLZ ( + uint8_t * pSrcBuffer, unsigned uSrcLength, + uint8_t * pDstBuffer, unsigned uDstLength ) + +{ + // Local Variables. + + int iSrcOffset = 0; + int iCopyCount = 0; + int iSkipCount; + + int iHashValue; + int iSrcRemain; + int iBestOffset = 0; + int iBestLength; + int iNextOffset; + int iNextLength; + + // Set the search parameters for this particular LZSS-variant. + + const int iMinMatch = 2; + const int iMaxMatch = 17; + const int iMaxDelta = 256; + + // Initialize the hash table and window for string matching. + + InitStringMatch(); + + // Initialize the output. + + g_pOutBuffer = pDstBuffer; + g_uOutLength = uDstLength; + + BitInit(); + NibbleInit(); + + // Write a header to signal Ys4's BYTE compression if using Ys4's g_iWindowFix. + + if (g_iWindowFix == 0) { + *g_pOutBuffer++ = 0; + } + + // Loop around encoding strings until the buffer is empty. + + for (;;) + { + // Update the window and calc how much data is left to compress. + + iSrcRemain = uSrcLength - iSrcOffset; + + if (iSrcRemain < iMinMatch) { + iSrcOffset += iSrcRemain; + iCopyCount += iSrcRemain; + break; + } + + // Find the best match at the current position. + + iBestLength = 0; + + if (iSrcOffset != 0) { + FindStringMatch( &iBestOffset, &iBestLength, pSrcBuffer, uSrcLength, iSrcOffset, iMaxDelta, iMaxMatch ); + } + + // Move the window on by 1 byte. + + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + // Lazy match (compresses up to 1% better on a good day, usually less). + // + // Basically, if you can compress 1 extra byte, then that is a better thing + // to do instead of encoding 2 literals after the current match. + + if (g_fLazyMatch) + { + if ((iBestLength >= iMinMatch) && (iBestLength < iMaxMatch) && (iSrcRemain != iMinMatch)) + { + FindStringMatch( &iNextOffset, &iNextLength, pSrcBuffer, uSrcLength, iSrcOffset + 1, iMaxDelta, iMaxMatch ); + + if (iNextLength > iBestLength) { + ++iCopyCount; + ++iSrcOffset; + iBestLength = iNextLength; + iBestOffset = iNextOffset; + } + } + } + + // Keep track of COPY bytes, but don't process them, yet. + + if (iBestLength < iMinMatch) { + ++iCopyCount; + ++iSrcOffset; + continue; + } + + // First, write any COPY bytes. + + if (iCopyCount) + { + uint8_t * pCopyFrom = pSrcBuffer + iSrcOffset - iCopyCount; + + do { + // Signal that COPY is next. + + BitWriteHiLo( 1 ); + + *g_pOutBuffer++ = *pCopyFrom++; + } while (--iCopyCount); + } + + // Then write the LZSS "match". + // + // Signal that LZSS is next. + + BitWriteHiLo( 0 ); + + // Save LZSS offset (as an absolute window offset). + + *g_pOutBuffer++ = (iBestOffset + g_iWindowFix) & 255; + + // Save LZSS length - 2. + + NibbleWriteHiLo( iBestLength - 2 ); + + // Skip passed "matched" bytes, updating the window contents. + + ++iSrcOffset; + + iSkipCount = iBestLength - 1; + + while (iSkipCount--) + { + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + ++iSrcOffset; + } + + } // End of "for (;;)" + + // Encode the last COPY byte(s) (if there are any). + + if (iCopyCount) + { + uint8_t * pCopyFrom = pSrcBuffer + iSrcOffset - iCopyCount; + + do { + // Signal that COPY is next. + + BitWriteHiLo( 1 ); + + *g_pOutBuffer++ = *pCopyFrom++; + } while (--iCopyCount); + } + + // All done. + + return (g_pOutBuffer); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// DecompressHLZ () +// +// Decompress data in Hudson's 4-bit length, 8-bit offset LZSS. +// +// The window offset is stored as relative to the start of the data, and not +// as a delta from the current output, but some games start decompressing to +// their 256 byte ring-buffer at $xxEF intead of $xx00. +// +// With a window start of $EF, this method is used by (at least) ... +// Tengai Makyo II - Manji Maru +// Dragon Slayer - The Legend of Heroes II +// Emerald Dragon +// Linda3 +// +// With a window start of $00, this method is used by (at least) ... +// Ys IV - The Dawn of Ys +// Gulliver Boy +// +// The bit buffer is stored hi-lo. +// The nibble buffer is stored hi-lo. +// +// The compression has no end-of-file marker, and data is decompressed until +// all of the source file is used, whether the data makes sense or not. +// +// Ys4 and Gulliver add a 1-byte header to signal whether the compressed data +// is encoded in byte (0) or word (1) format. +// +// This decompressor does NOT handle Ys4's word format scheme! +// + +uint8_t * DecompressHLZ ( + uint8_t * pSrcBuffer, unsigned uSrcLength, + uint8_t * pDstBuffer, unsigned uDstLength ) + +{ + // Local Variables. + + int iSrcOffset = 0; + int iDstOffset = 0; + int iMatchLength = 0; + + int iNibbleOffset = 0; + + uint8_t uBitMask = 0; + uint8_t uBitFlag = 0; + + uint8_t uWinOffset; + uint8_t uMatchOffset; + + uint8_t aWinBuffer[ 256 ]; + + // Initialize the ring-buffer window, just in case Hudson really thought + // that a preload filled with $00 bytes was actually a sane idea. + // + // N.B. I *hate* LZSS decompressors using a ring-buffer, it isn't needed + // unless you are using a preload, and it just obfuscates the simplicity + // of the LZSS algorithm. + + memset( aWinBuffer, 0, 256 ); + + // Detect the Ys4 style compression-type. + // + // Since HLZ compression stores its LZSS flags hi-lo, and there absolutely + // must be a COPY (a 1-bit) in the first few bits, normally in the top bit + // if there is no preload, then the type can be easily determined. + + uWinOffset = 0xEF; + + if (pSrcBuffer[0] < 2) { + // This must be the Ys4 style compression-type. + + if (pSrcBuffer[0] == 1) { + printf( "hulz - Hudson's WORD compression is not supported!\n" ); + return (NULL); + } + + uWinOffset = 0x00; + ++iSrcOffset; + } + + // Loop around decompressing data bytes until something stops us. + + while ((iSrcOffset <= (int) uSrcLength) && (iDstOffset < (int) uDstLength)) + { + if (iMatchLength == 0) + { + // Before starting a new COPY or MATCH, is there any data left to decompress? + + if (iSrcOffset >= (int) uSrcLength) { + break; + } + + // Do we need to load another byte of flag bits? + + if (uBitMask == 0) { + uBitFlag = pSrcBuffer[ iSrcOffset++ ]; + uBitMask = 0x80; + } + + if (uBitFlag & uBitMask) { + // COPY 1 byte. + + pDstBuffer[ iDstOffset++ ] = + aWinBuffer[ uWinOffset++ ] = pSrcBuffer[ iSrcOffset++ ]; + } else { + // Read MATCH offset. + + uMatchOffset = pSrcBuffer[ iSrcOffset++ ]; + + // Read MATCH length. + + if (iNibbleOffset == 0) { + iNibbleOffset = iSrcOffset++; + iMatchLength = (pSrcBuffer[ iNibbleOffset ] >> 4) + 2; + } else { + iMatchLength = (pSrcBuffer[ iNibbleOffset ] & 15) + 2; + iNibbleOffset = 0; + } + } + + uBitMask >>= 1; + } else { + // MATCH 1 byte. + + pDstBuffer[ iDstOffset++ ] = + aWinBuffer[ uWinOffset++ ] = aWinBuffer[ uMatchOffset++ ]; + --iMatchLength; + } + } + + // Warn the user if something seems to be wrong. + + if ((iMatchLength != 0) || (iDstOffset == (int) uDstLength)) { + printf( "hulz - WARNING, too much decompessed data, output truncated!\n" ); + } else { + if (iSrcOffset != (int) uSrcLength) { + printf( "hulz - WARNING, read passed the end of compressed data!\n" ); + printf( "hulz - The file is either too short or a byte too long.\n" ); + } else { + if (uBitMask != 0) { + do { + if (uBitFlag & uBitMask) { + printf( "hulz - WARNING, flag bits indicate the input file is too short!\n" ); + } + uBitMask >>= 1; + } while (uBitMask != 0); + } + } + } + + return (pDstBuffer + iDstOffset); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// g_aHudsonPreload [] +// +// Hudson's runtime-generated 4KByte preload for Anearth Fantasy Stories. +// + +uint8_t g_aHudsonPreload [4096] = +{ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01, // |................| + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02, // |................| + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, // |................| + 0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, // |................| + 0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x06, // |................| + 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07, // |................| + 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, // |................| + 0x08,0x08,0x08,0x08,0x08,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09, // |................| + 0x09,0x09,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b, // |................| + 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0c, // |................| + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d, // |................| + 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e, // |................| + 0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, // |................| + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x11,0x11, // |................| + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12,0x12,0x12,0x12, // |................| + 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, // |................| + 0x13,0x13,0x13,0x13,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, // |................| + 0x14,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x16,0x16, // |................| + 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x17,0x17,0x17,0x17,0x17, // |................| + 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // |................| + 0x18,0x18,0x18,0x18,0x18,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19, // |................| + 0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1b, // |................| + 0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c, // |................| + 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d, // |................| + 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e, // |................| + 0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, // |................| + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x21,0x21, // | !!!| + 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x22,0x22,0x22,0x22,0x22,0x22, // |!!!!!!!!!!""""""| + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, // |"""""""#########| + 0x23,0x23,0x23,0x23,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // |####$$$$$$$$$$$$| + 0x24,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x25,0x26,0x26, // |$%%%%%%%%%%%%%&&| + 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x27,0x27,0x27,0x27,0x27, // |&&&&&&&&&&&'''''| + 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, // |''''''''((((((((| + 0x28,0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29, // |((((()))))))))))| + 0x29,0x29,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2b, // |))*************+| + 0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2c, // |++++++++++++,,,,| + 0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, // |,,,,,,,,,-------| + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e,0x2e, // |------..........| + 0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f, // |.../////////////| + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x31,0x31, // |0000000000000111| + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x32,0x32,0x32,0x32,0x32,0x32, // |1111111111222222| + 0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, // |2222222333333333| + 0x33,0x33,0x33,0x33,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34, // |3333444444444444| + 0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x36,0x36, // |4555555555555566| + 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x37,0x37,0x37,0x37, // |6666666666677777| + 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38, // |7777777788888888| + 0x38,0x38,0x38,0x38,0x38,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39, // |8888899999999999| + 0x39,0x39,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3b, // |99:::::::::::::;| + 0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3c, // |;;;;;;;;;;;;<<<<| + 0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d, // |<<<<<<<<<=======| + 0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e,0x3e, // |======>>>>>>>>>>| + 0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, // |>>>?????????????| + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x41,0x41,0x41, // |@@@@@@@@@@@@@AAA| + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x42,0x42,0x42, // |AAAAAAAAAABBBBBB| + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43, // |BBBBBBBCCCCCCCCC| + 0x43,0x43,0x43,0x43,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, // |CCCCDDDDDDDDDDDD| + 0x44,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x46,0x46, // |DEEEEEEEEEEEEEFF| + 0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x47,0x47,0x47,0x47,0x47, // |FFFFFFFFFFFGGGGG| + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48, // |GGGGGGGGHHHHHHHH| + 0x48,0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49, // |HHHHHIIIIIIIIIII| + 0x49,0x49,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4b, // |IIJJJJJJJJJJJJJK| + 0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4c, // |KKKKKKKKKKKKLLLL| + 0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d, // |LLLLLLLLLMMMMMMM| + 0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e, // |MMMMMMNNNNNNNNNN| + 0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f,0x4f, // |NNNOOOOOOOOOOOOO| + 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x51,0x51,0x51, // |PPPPPPPPPPPPPQQQ| + 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x52,0x52,0x52,0x52,0x52,0x52, // |QQQQQQQQQQRRRRRR| + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53, // |RRRRRRRSSSSSSSSS| + 0x53,0x53,0x53,0x53,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54, // |SSSSTTTTTTTTTTTT| + 0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x56,0x56, // |TUUUUUUUUUUUUUVV| + 0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x57,0x57,0x57,0x57,0x57, // |VVVVVVVVVVVWWWWW| + 0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58, // |WWWWWWWWXXXXXXXX| + 0x58,0x58,0x58,0x58,0x58,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, // |XXXXXYYYYYYYYYYY| + 0x59,0x59,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5b, // |YYZZZZZZZZZZZZZ[| + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5c, // |[[[[[[[[[[[[\\\\| + 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d, // |\\\\\\\\\]]]]]]]| + 0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e,0x5e, // |]]]]]]^^^^^^^^^^| + 0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, // |^^^_____________| + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x61,0x61,0x61, // |`````````````aaa| + 0x61,0x61,0x61,0x61,0x61,0x61,0x61,0x61,0x61,0x61,0x62,0x62,0x62,0x62,0x62,0x62, // |aaaaaaaaaabbbbbb| + 0x62,0x62,0x62,0x62,0x62,0x62,0x62,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63, // |bbbbbbbccccccccc| + 0x63,0x63,0x63,0x63,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64, // |ccccdddddddddddd| + 0x64,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x66,0x66, // |deeeeeeeeeeeeeff| + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x67,0x67,0x67,0x67,0x67, // |fffffffffffggggg| + 0x67,0x67,0x67,0x67,0x67,0x67,0x67,0x67,0x68,0x68,0x68,0x68,0x68,0x68,0x68,0x68, // |gggggggghhhhhhhh| + 0x68,0x68,0x68,0x68,0x68,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69, // |hhhhhiiiiiiiiiii| + 0x69,0x69,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6a,0x6b, // |iijjjjjjjjjjjjjk| + 0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6c, // |kkkkkkkkkkkkllll| + 0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d, // |lllllllllmmmmmmm| + 0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, // |mmmmmmnnnnnnnnnn| + 0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f, // |nnnooooooooooooo| + 0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x71,0x71,0x71, // |pppppppppppppqqq| + 0x71,0x71,0x71,0x71,0x71,0x71,0x71,0x71,0x71,0x71,0x72,0x72,0x72,0x72,0x72,0x72, // |qqqqqqqqqqrrrrrr| + 0x72,0x72,0x72,0x72,0x72,0x72,0x72,0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73,0x73, // |rrrrrrrsssssssss| + 0x73,0x73,0x73,0x73,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74, // |sssstttttttttttt| + 0x74,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x76,0x76, // |tuuuuuuuuuuuuuvv| + 0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x77,0x77,0x77,0x77,0x77, // |vvvvvvvvvvvwwwww| + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x78,0x78,0x78,0x78,0x78,0x78,0x78,0x78, // |wwwwwwwwxxxxxxxx| + 0x78,0x78,0x78,0x78,0x78,0x79,0x79,0x79,0x79,0x79,0x79,0x79,0x79,0x79,0x79,0x79, // |xxxxxyyyyyyyyyyy| + 0x79,0x79,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7a,0x7b, // |yyzzzzzzzzzzzzz{| + 0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7c, // |{{{{{{{{{{{{||||| + 0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d, // ||||||||||}}}}}}}| + 0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, // |}}}}}}~~~~~~~~~~| + 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, // |~~~.............| + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81, // |................| + 0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x82,0x82,0x82,0x82,0x82,0x82, // |................| + 0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83,0x83, // |................| + 0x83,0x83,0x83,0x83,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84, // |................| + 0x84,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x85,0x86,0x86, // |................| + 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x87,0x87,0x87,0x87,0x87, // |................| + 0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, // |................| + 0x88,0x88,0x88,0x88,0x88,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89, // |................| + 0x89,0x89,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8b, // |................| + 0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8b,0x8c,0x8c,0x8c,0x8c, // |................| + 0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d, // |................| + 0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e, // |................| + 0x8e,0x8e,0x8e,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f,0x8f, // |................| + 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x91,0x91,0x91, // |................| + 0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x92,0x92,0x92,0x92,0x92,0x92, // |................| + 0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, // |................| + 0x93,0x93,0x93,0x93,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94, // |................| + 0x94,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x96,0x96, // |................| + 0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x97,0x97,0x97,0x97,0x97, // |................| + 0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98, // |................| + 0x98,0x98,0x98,0x98,0x98,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, // |................| + 0x99,0x99,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9b, // |................| + 0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9c,0x9c,0x9c,0x9c, // |................| + 0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d, // |................| + 0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e, // |................| + 0x9e,0x9e,0x9e,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f, // |................| + 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa1,0xa1,0xa1, // |................| + 0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2, // |................| + 0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3, // |................| + 0xa3,0xa3,0xa3,0xa3,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4, // |................| + 0xa4,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa6,0xa6, // |................| + 0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa6,0xa7,0xa7,0xa7,0xa7,0xa7, // |................| + 0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa7,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8, // |................| + 0xa8,0xa8,0xa8,0xa8,0xa8,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9,0xa9, // |................| + 0xa9,0xa9,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xab, // |................| + 0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xac,0xac,0xac,0xac, // |................| + 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xad,0xad,0xad,0xad,0xad,0xad,0xad, // |................| + 0xad,0xad,0xad,0xad,0xad,0xad,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae,0xae, // |................| + 0xae,0xae,0xae,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf,0xaf, // |................| + 0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb1,0xb1,0xb1, // |................| + 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2, // |................| + 0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3,0xb3, // |................| + 0xb3,0xb3,0xb3,0xb3,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4, // |................| + 0xb4,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb5,0xb6,0xb6, // |................| + 0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb6,0xb7,0xb7,0xb7,0xb7,0xb7, // |................| + 0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8, // |................| + 0xb8,0xb8,0xb8,0xb8,0xb8,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9,0xb9, // |................| + 0xb9,0xb9,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xbb, // |................| + 0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbb,0xbc,0xbc,0xbc,0xbc, // |................| + 0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd, // |................| + 0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe,0xbe, // |................| + 0xbe,0xbe,0xbe,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf, // |................| + 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0xc1,0xc1, // |................| + 0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc1,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2, // |................| + 0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3, // |................| + 0xc3,0xc3,0xc3,0xc3,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4, // |................| + 0xc4,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc5,0xc6,0xc6, // |................| + 0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc7,0xc7,0xc7,0xc7,0xc7, // |................| + 0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8,0xc8, // |................| + 0xc8,0xc8,0xc8,0xc8,0xc8,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9, // |................| + 0xc9,0xc9,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xcb, // |................| + 0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcb,0xcc,0xcc,0xcc,0xcc, // |................| + 0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd, // |................| + 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xce,0xce, // |................| + 0xce,0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf, // |................| + 0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd0,0xd1,0xd1,0xd1, // |................| + 0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2, // |................| + 0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd3,0xd3, // |................| + 0xd3,0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4,0xd4, // |................| + 0xd4,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd6,0xd6, // |................| + 0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7,0xd7,0xd7, // |................| + 0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd7,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8, // |................| + 0xd8,0xd8,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9,0xd9, // |................| + 0xd9,0xd9,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xdb, // |................| + 0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xdc,0xdc,0xdc,0xdc, // |................| + 0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, // |................| + 0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xde,0xde,0xde,0xde,0xde,0xde,0xde,0xde,0xde,0xde, // |................| + 0xde,0xde,0xde,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf, // |................| + 0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe1,0xe1,0xe1, // |................| + 0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2, // |................| + 0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3,0xe3, // |................| + 0xe3,0xe3,0xe3,0xe3,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4, // |................| + 0xe4,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe5,0xe6,0xe6, // |................| + 0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe7, // |................| + 0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8, // |................| + 0xe8,0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9, // |................| + 0xe9,0xe9,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xeb, // |................| + 0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xec,0xec,0xec,0xec, // |................| + 0xec,0xec,0xec,0xec,0xec,0xec,0xec,0xec,0xec,0xed,0xed,0xed,0xed,0xed,0xed,0xed, // |................| + 0xed,0xed,0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee,0xee,0xee,0xee,0xee,0xee,0xee, // |................| + 0xee,0xee,0xee,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef, // |................| + 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1, // |................| + 0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2, // |................| + 0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3, // |................| + 0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4, // |................| + 0xf4,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf6,0xf6, // |................| + 0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,0xf7,0xf7, // |................| + 0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, // |................| + 0xf8,0xf8,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, // |................| + 0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfb, // |................| + 0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc, // |................| + 0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, // |................| + 0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, // |................| + 0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // |................| + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, // |................| + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, // |................| + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, // | !"#$%&'()*+,-./| + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, // |0123456789:;<=>?| + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, // |@ABCDEFGHIJKLMNO| + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, // |PQRSTUVWXYZ[\]^_| + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, // |`abcdefghijklmno| + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, // |pqrstuvwxyz{|}~.| + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, // |................| + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, // |................| + 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, // |................| + 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, // |................| + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, // |................| + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, // |................| + 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, // |................| + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, // |................| + 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0, // |................| + 0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0, // |................| + 0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd0, // |................| + 0xcf,0xce,0xcd,0xcc,0xcb,0xca,0xc9,0xc8,0xc7,0xc6,0xc5,0xc4,0xc3,0xc2,0xc1,0xc0, // |................| + 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0, // |................| + 0xaf,0xae,0xad,0xac,0xab,0xaa,0xa9,0xa8,0xa7,0xa6,0xa5,0xa4,0xa3,0xa2,0xa1,0xa0, // |................| + 0x9f,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90, // |................| + 0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80, // |................| + 0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70, // |.~}|{zyxwvutsrqp| + 0x6f,0x6e,0x6d,0x6c,0x6b,0x6a,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60, // |onmlkjihgfedcba`| + 0x5f,0x5e,0x5d,0x5c,0x5b,0x5a,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50, // |_^]\[ZYXWVUTSRQP| + 0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40, // |ONMLKJIHGFEDCBA@| + 0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30, // |?>=<;:9876543210| + 0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20, // |/.-,+*)('&%$#"! | + 0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10, // |................| + 0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // |................| + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, // | | + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 // | | +}; + + + +// ************************************************************************** +// ************************************************************************** +// +// CompressAFS () +// +// Compress data in Hudson's 4-bit length, 12-bit offset LZSS, with preload. +// +// The window offset is stored as relative to the start of the preload data, +// and not as a delta from the current output, and some games do not use all +// of the 4096-byte preload and start compressing at offset $xFEE instead of +// $x000. +// +// With a window start of $0FEE, this method is used by (at least) ... +// Anearth Fantasy Stories +// +// The bit buffer is stored lo-hi. +// +// The compressed data is preceded by an 8-byte header containing the sizes +// of both the compressed and uncompressed data. +// + +uint8_t * CompressAFS ( + uint8_t * pSrcBuffer, unsigned uSrcLength, + uint8_t * pDstBuffer, unsigned uDstLength ) + +{ + // Local Variables. + + int iSrcOffset = 0; + int iCopyCount = 0; + int iSkipCount; + + int iHashValue; + int iSrcRemain; + int iBestOffset; + int iBestLength; + int iNextOffset; + int iNextLength; + + uint8_t * pTmpBuffer = NULL; + + bool usePreload = true; + + // Set the search parameters for this particular LZSS-variant. + + const int iMinMatch = 3; + const int iMaxMatch = 18; + const int iMaxDelta = 0x1000; + + // Initialize the hash table and window for string matching. + + InitStringMatch(); + + // Initialize the output, which begins with an 8-byte chunk header. + + g_pOutBuffer = pDstBuffer + 8; + g_uOutLength = uDstLength - 8; + + BitInit(); + + // Write the uncompressed length to the chunk header. + + pDstBuffer[4] = (uint8_t) (uSrcLength & 255); + pDstBuffer[5] = (uint8_t) (uSrcLength / 256); + pDstBuffer[6] = 0; + pDstBuffer[7] = 0; + + // Handle preload by creating a copy of the pSrcBuffer. + // + // Hudson's AFS only uses 0x0FEE bytes out of the 0x1000 byte preload! + + pTmpBuffer = (uint8_t *) malloc( uSrcLength + 0x0FEE ); + + memcpy( pTmpBuffer + 0x0000, g_aHudsonPreload, 0x0FEE ); + memcpy( pTmpBuffer + 0x0FEE, pSrcBuffer, uSrcLength ); + + pSrcBuffer = pTmpBuffer; + uSrcLength = uSrcLength + 0x0FEE; + + if (usePreload) + { + // Add preload data to the window of known strings. + + while (iSrcOffset != 0x0FEE) + { + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + ++iSrcOffset; + } + } + else + { + // Ignore the preload data, but still start at offset 0x0FEE to keep + // Hudson's decompressor happy. + + iSrcOffset = 0x0FEE; + } + + // Loop around encoding strings until the buffer is empty. + + for (;;) + { + // Update the window and calc how much data is left to compress. + + iSrcRemain = uSrcLength - iSrcOffset; + + if (iSrcRemain < iMinMatch) { + iSrcOffset += iSrcRemain; + iCopyCount += iSrcRemain; + break; + } + + // Find the best match at the current position. + + iBestLength = 0; + + if (iSrcOffset != 0) { + FindStringMatch( &iBestOffset, &iBestLength, pSrcBuffer, uSrcLength, iSrcOffset, iMaxDelta, iMaxMatch ); + } + + // Move the window on by 1 byte. + + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + // Lazy match (compresses up to 1% better on a good day, usually less). + // + // Basically, if you can compress 1 extra byte, then that is a better thing + // to do instead of encoding 2 literals after the current match. + + if (g_fLazyMatch) + { + if ((iBestLength >= iMinMatch) && (iBestLength < iMaxMatch) && (iSrcRemain != iMinMatch)) + { + FindStringMatch( &iNextOffset, &iNextLength, pSrcBuffer, uSrcLength, iSrcOffset + 1, iMaxDelta, iMaxMatch ); + + if (iNextLength > iBestLength) { + ++iCopyCount; + ++iSrcOffset; + iBestLength = iNextLength; + iBestOffset = iNextOffset; + } + } + } + + // Keep track of COPY bytes, but don't process them, yet. + + if (iBestLength < iMinMatch) { + ++iCopyCount; + ++iSrcOffset; + continue; + } + + // First, write any COPY bytes. + + if (iCopyCount) + { + uint8_t * pCopyFrom = pSrcBuffer + iSrcOffset - iCopyCount; + + do { + // Signal that COPY is next. + + BitWriteLoHi( 1 ); + + *g_pOutBuffer++ = *pCopyFrom++; + } while (--iCopyCount); + } + + // Then write the LZSS "match". + // + // Mark this as an LZSS and not a COPY. + + BitWriteLoHi( 0 ); + + // In Hudson's compression, the offset is not relative to the output, but + // is actually the index into the 4KB window[] array! + + g_pOutBuffer[0] = (uint8_t) (iBestOffset & 255); + g_pOutBuffer[1] = (uint8_t) ((0xF0u & (iBestOffset >> 4)) + (iBestLength - 3)); + + g_pOutBuffer += 2; + + // Skip passed "matched" bytes, updating the window contents. + + ++iSrcOffset; + + iSkipCount = iBestLength - 1; + + while (iSkipCount--) + { + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + ++iSrcOffset; + } + + } // End of "for (;;)" + + // Encode the last COPY byte(s) (if there are any). + + if (iCopyCount) + { + uint8_t * pCopyFrom = pSrcBuffer + iSrcOffset - iCopyCount; + + do { + // Signal that COPY is next. + + BitWriteLoHi( 1 ); + + *g_pOutBuffer++ = *pCopyFrom++; + } while (--iCopyCount); + } + + // Write the compressed length to the chunk header. + + uDstLength = g_pOutBuffer - (pDstBuffer + 8); + + pDstBuffer[0] = (uint8_t) (uDstLength & 255); + pDstBuffer[1] = (uint8_t) (uDstLength / 256); + pDstBuffer[2] = 0; + pDstBuffer[3] = 0; + + // Free up the preload buffer. + + if (pTmpBuffer != NULL) + free( pTmpBuffer ); + + // All done. + + return (g_pOutBuffer); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// DecompressAFS () +// +// Decompress data in Hudson's 4-bit length, 12-bit offset LZSS, with buffer +// preload. +// +// The window offset is stored as relative to the start of the preload data, +// and not as a delta from the current output, and some games do not use all +// of the 4096-byte preload and start compressing at offset $xFEE instead of +// $x000. +// +// With a window start of $0FEE, this method is used by (at least) ... +// Anearth Fantasy Stories +// +// The bit buffer is stored lo-hi. +// +// The compressed data is preceded by an 8-byte header containing the sizes +// of both the compressed and uncompressed data. +// + +uint8_t * DecompressAFS ( + uint8_t * pSrcBuffer, unsigned uSrcLength, + uint8_t * pDstBuffer, unsigned uDstLength ) + +{ + // Local Variables. + + int iSrcLength; + int iDstLength; + + int iSrcOffset = 0; + int iDstOffset = 0; + int iMatchLength = 0; + + uint8_t uBitMask = 0; + uint8_t uBitFlag = 0; + + int iWinOffset; + int iMatchOffset; + + uint8_t aWinBuffer[ 4096 ]; + + // Initialize the ring-buffer window. + + memcpy( aWinBuffer, g_aHudsonPreload, 4096 ); + + iWinOffset = 0x0FEE; + + // Read the compressed and decompressed sizes from the header. + + iSrcLength = pSrcBuffer[0] + (0x00000100 * pSrcBuffer[1]) + (0x00010000 * pSrcBuffer[2]) + (0x01000000 * pSrcBuffer[3]); + iDstLength = pSrcBuffer[4] + (0x00000100 * pSrcBuffer[5]) + (0x00010000 * pSrcBuffer[6]) + (0x01000000 * pSrcBuffer[7]); + + if ((iSrcLength < 0) || (uSrcLength < (unsigned) (iSrcLength + 8))) { + printf( "hulz - ERROR, header indicates some compressed data is missing!\n" ); + return (NULL); + } + + iSrcLength += 8; + + if ((iDstLength < 0) || (uDstLength < (unsigned) (iDstLength))) { + printf( "hulz - ERROR, header says the decompressed data is more than %u bytes!\n", uDstLength ); + return (NULL); + } + + iSrcOffset = 8; + + // Loop around decompressing data bytes until something stops us. + + while ((iSrcOffset <= iSrcLength) && (iDstOffset < iDstLength)) + { + if (iMatchLength == 0) + { + // Before starting a new COPY or MATCH, is there any data left to decompress? + + if (iSrcOffset >= (int) uSrcLength) { + break; + } + + // Do we need to load another byte of flag bits? + + if (uBitMask == 0) { + uBitFlag = pSrcBuffer[ iSrcOffset++ ]; + uBitMask = 0x01; + } + + if (uBitFlag & uBitMask) { + // COPY 1 byte. + + pDstBuffer[ iDstOffset++ ] = + aWinBuffer[ iWinOffset++ ] = pSrcBuffer[ iSrcOffset++ ]; + iWinOffset &= 0x0FFF; + } else { + // Read MATCH offset. + + iMatchOffset = pSrcBuffer[ iSrcOffset++ ]; + iMatchOffset = iMatchOffset + 256 * (pSrcBuffer[ iSrcOffset ] >> 4); + + // Read MATCH length. + + iMatchLength = (pSrcBuffer[ iSrcOffset++ ] & 15) + 3; + } + + uBitMask <<= 1; + } else { + // MATCH 1 byte. + + pDstBuffer[ iDstOffset++ ] = + aWinBuffer[ iWinOffset++ ] = aWinBuffer[ iMatchOffset++ ]; + iWinOffset &= 0x0FFF; + iMatchOffset &= 0x0FFF; + --iMatchLength; + } + } + + // Warn the user if something seems to be wrong. + + if ((iMatchLength != 0) || (iDstOffset != iDstLength)) { + printf( "hulz - WARNING, decompessed data length does not match length in header!\n" ); + } else { + if (iSrcOffset != iSrcLength) { + printf( "hulz - WARNING, read passed the end of compressed data!\n" ); + } else { + if (uBitMask != 0) { + do { + if (uBitFlag & uBitMask) { + printf( "hulz - WARNING, flag bits indicate the input file is too short!\n" ); + } + uBitMask <<= 1; + } while (uBitMask != 0); + } + } + } + + return (pDstBuffer + iDstOffset); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// CompressLZ8 () +// +// Compress data in Elmer's 16-bit length, 8-bit offset LZ4-variant. +// +// The window offset is stored as relative to the start of the data, and not +// as a delta from the current output, which is quicker for decompression to +// a page-aligned output (or ring-buffer). +// +// Both COPY and MATCH counts are encoded as variable-length formats, either +// nibble or nibble+byte or nibble+byte+word. +// +// The nibble buffer is stored hi-lo. +// +// N.B. This is a pretty useless format, please use ZX0 instead! +// + +uint8_t * CompressLZ8 ( + uint8_t * pSrcBuffer, unsigned uSrcLength, + uint8_t * pDstBuffer, unsigned uDstLength ) + +{ + // Local Variables. + + int iSrcOffset = 0; + int iCopyCount = 0; + int iSkipCount; + + int iHashValue; + int iSrcRemain; + int iBestOffset; + int iBestLength; + int iNextOffset; + int iNextLength; + int iPrevOffset = 0; + int iPrevLength = 0; + + // Set the search parameters for this particular LZSS-variant. + + const int iMinMatch = 2; + const int iMaxMatch = 65536; + const int iMaxDelta = 256; + + // Initialize the hash table and window for string matching. + + InitStringMatch(); + + // Initialize the output. + + g_pOutBuffer = pDstBuffer; + g_uOutLength = uDstLength; + + BitInit(); + NibbleInit(); + + // Loop around encoding strings until the buffer is empty. + + for (;;) + { + // Update the window and calc how much data is left to compress. + + iSrcRemain = uSrcLength - iSrcOffset; + + if (iSrcRemain < iMinMatch) { + iSrcOffset += iSrcRemain; + iCopyCount += iSrcRemain; + break; + } + + // Find the best match at the current position. + + iBestLength = 0; + + if (iSrcOffset != 0) { + FindStringMatch( &iBestOffset, &iBestLength, pSrcBuffer, uSrcLength, iSrcOffset, iMaxDelta, iMaxMatch ); + } + + // Move the window on by 1 byte. + + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + // Lazy match (compresses up to 1% better on a good day, usually less). + // + // With variable-length encoding, the cost of ignoring the current match is + // rather ugly to calculate. + + if (g_fLazyMatch) + { + if ((iBestLength >= iMinMatch) && (iBestLength < iMaxMatch) && (iSrcRemain != iMinMatch)) + { + int iLazyCost = 8; + + FindStringMatch( &iNextOffset, &iNextLength, pSrcBuffer, uSrcLength, iSrcOffset + 1, iMaxDelta, iMaxMatch ); + + if (iCopyCount == 0) { + iLazyCost += 4; + } else + if (iCopyCount == 15) { + iLazyCost += 8; + } else + if (iCopyCount == 255) { + iLazyCost += 16; + } + + if (iBestLength <= 16) { + if (iNextLength > 256) { + iLazyCost += 16; + } else + if (iNextLength > 16) { + iLazyCost += 8; + } + } else + if (iBestLength <= 256) { + if (iNextLength > 256) { + iLazyCost += 16; + } + } + + iLazyCost = (iLazyCost + 7) / 8; + + if (iNextLength >= (iBestLength + iLazyCost)) { + ++iCopyCount; + ++iSrcOffset; + iBestLength = iNextLength; + iBestOffset = iNextOffset; + } + } + } + + // Keep track of COPY bytes, but don't process them, yet. + + if (iBestLength < iMinMatch) { + ++iCopyCount; + ++iSrcOffset; + continue; + } + + // Got a new LZSS match! + // + // First, write the previous match now that we know what follows it. + + if (iPrevLength) { + // Save LZSS length with "followed-by-copy-or-lzss" flag in the bottom bit. + + int iTempLength = ((iPrevLength - 1) * 2) + ((iCopyCount == 0) ? 1 : 0); + + if (iTempLength < 16) { + NibbleWriteHiLo( iTempLength ); + } else { + NibbleWriteHiLo( 0 ); + if (iTempLength < 256) { + *g_pOutBuffer++ = iTempLength; + } else { + *g_pOutBuffer++ = 0; + *g_pOutBuffer++ = (iTempLength >> 8); + *g_pOutBuffer++ = (iTempLength & 255); + } + } + + // Save LZSS offset. + + *g_pOutBuffer++ = iPrevOffset & 255; + } + + // Then write any COPY bytes. + + if (iCopyCount) { + uint8_t * pCopyFrom; + + // Save COPY length. + + if (iCopyCount < 16) { + NibbleWriteHiLo( iCopyCount ); + } else { + NibbleWriteHiLo( 0 ); + if (iCopyCount < 256) { + *g_pOutBuffer++ = iCopyCount; + } else { + *g_pOutBuffer++ = 0; + *g_pOutBuffer++ = (iCopyCount >> 8) - (((iCopyCount & 255) == 0) ? 1 : 0); + *g_pOutBuffer++ = (iCopyCount & 255); + } + } + + // Save each individual COPY byte. + + pCopyFrom = pSrcBuffer + iSrcOffset - iCopyCount; + + do { + *g_pOutBuffer++ = *pCopyFrom++; + } while (--iCopyCount); + } + + // Remember the LZSS "match", but don't write it until we know what follows it. + + iPrevLength = iBestLength; + iPrevOffset = iBestOffset; + + // Skip passed "matched" bytes, updating the window contents. + + ++iSrcOffset; + + iSkipCount = iBestLength - 1; + + while (iSkipCount--) + { + iHashValue = CALC_HASH( iSrcOffset ); + + g_pPrevOffset[ iSrcOffset & HASH_WIN_MASK ] = g_pHashOffset[ iHashValue ]; + g_pHashOffset[ iHashValue ] = iSrcOffset; + + ++iSrcOffset; + } + + } // End of "for (;;)" + + // We have now reached the end of the data to compress! + // + // First, write the previous match now that we know what follows it. + + if (iPrevLength) { + // Save LZSS length with "what-comes-next" flag in the bottom bit. + + int iTempLength = ((iPrevLength - 1) * 2) + ((iCopyCount == 0) ? 1 : 0); + + if (iTempLength < 16) { + NibbleWriteHiLo( iTempLength ); + } else { + NibbleWriteHiLo( 0 ); + if (iTempLength < 256) { + *g_pOutBuffer++ = iTempLength; + } else { + *g_pOutBuffer++ = 0; + *g_pOutBuffer++ = (iTempLength >> 8); + *g_pOutBuffer++ = (iTempLength & 255); + } + } + + // Save LZSS offset. + + *g_pOutBuffer++ = iPrevOffset & 255; + } + + // Write the last COPY byte(s) (if there are any). + + if (iCopyCount) { + uint8_t * pCopyFrom; + + // Save COPY length. + + if (iCopyCount < 16) { + NibbleWriteHiLo( iCopyCount ); + } else { + NibbleWriteHiLo( 0 ); + if (iCopyCount < 256) { + *g_pOutBuffer++ = iCopyCount; + } else { + *g_pOutBuffer++ = 0; + *g_pOutBuffer++ = (iCopyCount >> 8) - (((iCopyCount & 255) == 0) ? 1 : 0); + *g_pOutBuffer++ = (iCopyCount & 255); + } + } + + // Save each individual COPY byte. + + pCopyFrom = pSrcBuffer + iSrcOffset - iCopyCount; + + do { + *g_pOutBuffer++ = *pCopyFrom++; + } while (--iCopyCount); + } + + // Write the end-of-file token. + + NibbleWriteHiLo( 0 ); + + *g_pOutBuffer++ = 1; + + // All done. + + return (g_pOutBuffer); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// DecompressLZ8 () +// +// Compress data in Elmer's 16-bit length, 8-bit offset LZ4-variant. +// +// The window offset is stored as relative to the start of the data, and not +// as a delta from the current output, which is quicker for decompression to +// a page-aligned output (or ring-buffer). +// +// Both COPY and MATCH counts are encoded as variable-length formats, either +// nibble or nibble+byte or nibble+byte+word. +// +// The nibble buffer is stored hi-lo. +// +// N.B. This is a pretty useless format, please use ZX0 instead! +// + +uint8_t * DecompressLZ8 ( + uint8_t * pSrcBuffer, unsigned uSrcLength, + uint8_t * pDstBuffer, unsigned uDstLength ) + +{ + // Local Variables. + + int iSrcOffset = 0; + int iDstOffset = 0; + + int iMatchIsNext = 0; + + int iCopyLength = 0; + int iMatchLength = 0; + + uint8_t * pNibbleOffset = NULL; + + uint8_t uWinOffset = 0; + uint8_t uMatchOffset = 0; + + uint8_t aWinBuffer[ 256 ]; + + // Initialize the ring-buffer window. + // + // N.B. I *hate* LZSS decompressors using a ring-buffer, it isn't needed + // unless you are using a preload, and it just obfuscates the simplicity + // of the LZSS algorithm ... but I guess that it's a simple way to avoid + // reading outside the buffer area if we're given bad data to decompress. + + memset( aWinBuffer, 0, 256 ); + + // Loop around decompressing data bytes until something stops us. + + while ((iSrcOffset <= (int) uSrcLength) && (iDstOffset < (int) uDstLength)) + { + if ((iCopyLength == 0) && (iMatchLength == 0)) + { + int iLength; + + // Before starting a new COPY or MATCH, is there any data left to decompress? + // + // This shouldn't be necessary with an EOF marker, but it helps if given bad + // data. + + if (iSrcOffset >= (int) uSrcLength) { + break; + } + + // Read the next length. + + if (pNibbleOffset == NULL) { + pNibbleOffset = pSrcBuffer + iSrcOffset++; + iLength = (*pNibbleOffset >> 4); + } else { + iLength = (*pNibbleOffset & 15); + pNibbleOffset = NULL; + } + + if (iLength == 0) { + // Read 8-bit length. + + iLength = pSrcBuffer[ iSrcOffset++ ]; + + if (iLength == 1) { + // Got EOF marker. + + break; + } + + if (iLength == 0) { + // Read 16-bit length. + + iLength = 256 * pSrcBuffer[ iSrcOffset++ ]; + iLength = iLength + pSrcBuffer[ iSrcOffset++ ]; + } + } + + // Now that we've got the length, what to do with it? + + if (iMatchIsNext == 0) { + iMatchIsNext = 1; + + // Set COPY length. + + iCopyLength = iLength; + if ((iLength & 255) == 0) iCopyLength += 256; + } else { + iMatchIsNext = iLength & 1; + + // Set MATCH length. + + iMatchLength = (iLength >> 1) + 1; + + // Get MATCH offset. + + uMatchOffset = pSrcBuffer[ iSrcOffset++ ]; + } + } else { + // There's still an incomplete COPY or MATCH to process. + + if (iMatchLength == 0) { + // COPY 1 byte. + + pDstBuffer[ iDstOffset++ ] = + aWinBuffer[ uWinOffset++ ] = pSrcBuffer[ iSrcOffset++ ]; + --iCopyLength; + } else { + // MATCH 1 byte. + + pDstBuffer[ iDstOffset++ ] = + aWinBuffer[ uWinOffset++ ] = aWinBuffer[ uMatchOffset++ ]; + --iMatchLength; + } + } + } + + // Warn the user if something seems to be wrong. + + if (iDstOffset == (int) uDstLength) { + printf( "hulz - WARNING, too much decompessed data, output truncated!\n" ); + } else + if ((iCopyLength != 0) || (iMatchLength != 0) || (iSrcOffset != (int) uSrcLength)) { + printf( "hulz - WARNING, read passed the end of compressed data!\n" ); + printf( "hulz - The file is probably too short.\n" ); + } + + return (pDstBuffer + iDstOffset); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// ReadBinaryFile () +// +// Uses POSIX file functions rather than C file functions. +// +// Google "FIO19-C" for the reason why. +// +// N.B. Will return an error for files larger than 2GB on a 32-bit system. +// +// N.B. Pads allocated buffer size to next 16-byte boundary. +// + +bool ReadBinaryFile ( const char *pName, uint8_t **pBuffer, size_t *pLength ) +{ + uint8_t * pData = NULL; + off_t uSize; + struct stat cStat; + + int hFile = open( pName, O_BINARY | O_RDONLY ); + + if (hFile == -1) + goto errorExit; + + if ((fstat( hFile, &cStat ) != 0) || (!S_ISREG( cStat.st_mode ))) + goto errorExit; + + if (cStat.st_size > SSIZE_MAX) + goto errorExit; + + uSize = cStat.st_size; + + pData = (uint8_t *) calloc( (uSize + 15) >> 4, 16 ); + + if (pData == NULL) + goto errorExit; + + if (read( hFile, pData, uSize ) != uSize) + goto errorExit; + + close( hFile ); + + *pBuffer = pData; + *pLength = uSize; + + return (true); + + // Handle errors. + +errorExit: + + if (pData != NULL) free( pData ); + if (hFile >= 0) close( hFile ); + + *pBuffer = NULL; + *pLength = 0; + + return (false); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// WriteBinaryFile () +// +// Uses POSIX file functions rather than C file functions, just because +// it might save some space since ReadBinaryFile() uses POSIX functions. +// + +bool WriteBinaryFile ( const char *pName, uint8_t *pBuffer, size_t iLength ) +{ + int hFile = open( pName, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE ); + + if (hFile == -1) + goto errorExit; + + if (write( hFile, pBuffer, iLength) != iLength ) + goto errorExit; + + close( hFile ); + + return (true); + + // Handle errors. + +errorExit: + + if (hFile >= 0) close( hFile ); + + return (false); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// ProcessFile () +// + +int ProcessFile ( const char *pSrcName, const char *pDstName ) + +{ + // Local variables. + + uint8_t * pSrcBuffer = NULL; + size_t uSrcLength = 0; + + uint8_t * pDstBuffer = NULL; + size_t uDstLength = 0; + + uint8_t * pDstFinish = NULL; + + // Read the original data from the source file. + + if (!ReadBinaryFile( pSrcName, &pSrcBuffer, &uSrcLength )) + { + printf( "hulz - Unable to read \"%s\" into memory!\n", pSrcName ); + return (1); + } + + // Some of Hudson's compression schemes are limited to a 16-bit length. + + if (uSrcLength > 65536) + { + printf( "hulz - File is too big, PC Engine compression is limited to 64KB!\n" ); + return (1); + } + + // Allocate 128KB of memory for the compresed data. + + uDstLength = 128 * 1024; + pDstBuffer = malloc( uDstLength ); + + // Compress or decompress the data using the desired method. + + if (g_fDecompress) { + if (g_pDecompressFunc == NULL) { + printf( "hulz - Decompression method not specified!\n" ); + return (1); + } + pDstFinish = (*g_pDecompressFunc)( pSrcBuffer, (int) uSrcLength, pDstBuffer, (int) uDstLength ); + } else { + if (g_pCompressorFunc == NULL) { + printf( "hulz - Compression method not specified!\n" ); + return (1); + } + pDstFinish = (*g_pCompressorFunc)( pSrcBuffer, (int) uSrcLength, pDstBuffer, (int) uDstLength ); + } + + if (pDstFinish == NULL) + { + return (1); + } + + // Write the compressed data to the output file. + + if (!WriteBinaryFile( pDstName, pDstBuffer, pDstFinish - pDstBuffer )) + { + printf( "hulz - Unable to write output file \"%s\"!\n", pDstName ); + return (1); + } + + // Free up the buffers before finishing. + + free( pDstBuffer ); + free( pSrcBuffer ); + + return (0); +} + + + +// ************************************************************************** +// ************************************************************************** +// +// ProcessOption () +// + +int ProcessOption ( char * pOption ) + +{ + // Process option string. + + switch( pOption[1] ) + { + // Display help. + + case '?': + case 'h': + { + printf + ( + "Purpose : Compress data with various methods used on the PC Engine\n" + "\n" + "Usage : hulz [