├── .gitignore ├── Makefile ├── c++-coding-style.md ├── common ├── 2600 │ └── vcs.wiz ├── gb │ ├── bcd.wiz │ ├── gb.wiz │ ├── gbc_util.wiz │ ├── joy.wiz │ ├── math.wiz │ ├── memory.wiz │ ├── oam.wiz │ └── sgb_util.wiz ├── gg │ ├── hello_tiles.chr │ ├── hello_tiles.png │ ├── img2gg16.py │ ├── img2gg8.py │ ├── minirpg_sprites.chr │ ├── minirpg_sprites.png │ └── sms.wiz ├── msx │ ├── hello_tiles.chr │ ├── hello_tiles.png │ ├── img2msx16.py │ ├── img2msx8.py │ └── msx.wiz ├── nes │ ├── bobble_tiles.chr │ ├── bobble_tiles.png │ ├── hello_tiles.chr │ ├── hello_tiles.png │ ├── img2chr.py │ ├── minirpg_sprites.chr │ ├── minirpg_sprites.png │ ├── nes.wiz │ ├── scroller_tiles.chr │ └── scroller_tiles.png ├── pce │ ├── hello_tiles.chr │ ├── hello_tiles.png │ ├── img2pce8.py │ ├── minirpg_sprites.chr │ ├── minirpg_sprites.png │ └── pce.wiz ├── snes │ ├── hello_tiles.chr │ ├── hello_tiles.png │ ├── hello_tiles_compact.chr │ ├── hello_tiles_compact.png │ ├── icd2.wiz │ ├── img2snes.py │ ├── minirpg_sprites.chr │ ├── minirpg_sprites.png │ └── snes.wiz └── spc │ └── spc.wiz ├── examples ├── 2600 │ └── finalduck │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── main.wiz │ │ ├── random.wiz │ │ └── readme.txt ├── gb │ ├── frogegg │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── font.chr │ │ ├── font.png │ │ ├── main.wiz │ │ ├── metatilekit.png │ │ ├── mock-dmg-3x-twitter.png │ │ ├── mock-dmg.png │ │ ├── mock-gbc-3x-twitter.png │ │ ├── mock-gbc.png │ │ ├── sprites.chr │ │ ├── sprites.png │ │ ├── tiles.chr │ │ ├── tiles.png │ │ └── video.wiz │ ├── hypercat │ │ ├── art.wiz │ │ ├── banks.wiz │ │ ├── bkg_tileset.chr │ │ ├── build │ │ ├── build.bat │ │ ├── kitty.wiz │ │ ├── main.wiz │ │ ├── random.wiz │ │ ├── spr_tileset.chr │ │ ├── text.wiz │ │ └── video.wiz │ ├── sgb_icd2_6003_test │ │ ├── build_sgb │ │ ├── build_sgb.bat │ │ ├── gb │ │ │ ├── banks.wiz │ │ │ ├── main.wiz │ │ │ ├── sgbx_protocol.wiz │ │ │ └── video.wiz │ │ └── snes │ │ │ ├── banks.wiz │ │ │ ├── main.wiz │ │ │ └── ram.wiz │ ├── sgb_snes_custom_protcol │ │ ├── build_sgb │ │ ├── build_sgb.bat │ │ ├── gb │ │ │ ├── banks.wiz │ │ │ ├── main.wiz │ │ │ ├── sgbx_protocol.wiz │ │ │ ├── video.wiz │ │ │ └── vram_buffer.wiz │ │ ├── snes │ │ │ ├── main.wiz │ │ │ ├── ram.wiz │ │ │ ├── sgb │ │ │ │ └── banks.wiz │ │ │ └── snes2spc.wiz │ │ └── spc │ │ │ └── main.wiz │ ├── sgb_snes_upload │ │ ├── build_sfc │ │ ├── build_sfc.bat │ │ ├── build_sgb │ │ ├── build_sgb.bat │ │ ├── gb │ │ │ ├── banks.wiz │ │ │ ├── main.wiz │ │ │ └── video.wiz │ │ ├── snes │ │ │ ├── main.wiz │ │ │ ├── ram.wiz │ │ │ ├── sfc │ │ │ │ └── banks.wiz │ │ │ ├── sgb │ │ │ │ └── banks.wiz │ │ │ └── snes2spc.wiz │ │ └── spc │ │ │ └── main.wiz │ ├── snake │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── main.wiz │ │ ├── player.wiz │ │ └── video.wiz │ └── xzone │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── main.wiz │ │ ├── mask_tiles.png │ │ ├── mask_tileset.chr │ │ ├── tables.wiz │ │ └── video.wiz ├── gg │ └── hello │ │ ├── build │ │ ├── build.bat │ │ └── hello.wiz ├── msx │ └── hello │ │ ├── build │ │ ├── build.bat │ │ └── hello.wiz ├── nes │ ├── hello │ │ ├── build │ │ ├── build.bat │ │ └── hello.wiz │ ├── shmup │ │ ├── banks.wiz │ │ ├── bg_tiles.chr │ │ ├── bg_tiles.png │ │ ├── build │ │ ├── build.bat │ │ ├── bullet.wiz │ │ ├── bullet_definitions.wiz │ │ ├── bullet_normal.wiz │ │ ├── collision.wiz │ │ ├── enemy_ghost.wiz │ │ ├── entity.wiz │ │ ├── entity_definitions.wiz │ │ ├── fx_enemy_death.wiz │ │ ├── globals.wiz │ │ ├── joy.wiz │ │ ├── main.wiz │ │ ├── math.wiz │ │ ├── nes_topdown_shmup1.png │ │ ├── player.wiz │ │ ├── shmup_player_update.png │ │ ├── shmup_sprites.chr │ │ ├── shmup_sprites.png │ │ ├── utility.wiz │ │ └── video.wiz │ ├── slimes │ │ ├── ai_wander.wiz │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── common.wiz │ │ ├── data.wiz │ │ ├── directions.wiz │ │ ├── entity.wiz │ │ ├── hero.wiz │ │ ├── joy.wiz │ │ ├── main.wiz │ │ ├── ram.wiz │ │ ├── random.wiz │ │ └── slime.wiz │ └── vwf │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── globals.wiz │ │ ├── main.wiz │ │ ├── vram_buffer.wiz │ │ ├── vwf.wiz │ │ └── vwf_font.chr ├── pce │ └── hello │ │ ├── banks.wiz │ │ ├── build │ │ ├── build.bat │ │ ├── main.wiz │ │ └── ram.wiz └── snes │ └── hello │ ├── banks.wiz │ ├── build │ ├── build.bat │ ├── main.wiz │ ├── ram.wiz │ ├── snes2spc.wiz │ └── spc_main.wiz ├── license.md ├── makefile_find_command.bat ├── readme.md ├── src ├── wiz-emscripten │ └── pre-js.js └── wiz │ ├── ast │ ├── expression.cpp │ ├── expression.h │ ├── expression.natvis │ ├── qualifiers.h │ ├── statement.cpp │ ├── statement.h │ ├── statement.natvis │ ├── type_expression.cpp │ ├── type_expression.h │ └── type_expression.natvis │ ├── compiler │ ├── address.h │ ├── bank.cpp │ ├── bank.h │ ├── builtins.cpp │ ├── builtins.h │ ├── compiler.cpp │ ├── compiler.h │ ├── config.cpp │ ├── config.h │ ├── definition.cpp │ ├── definition.h │ ├── definition.natvis │ ├── instruction.cpp │ ├── instruction.h │ ├── instruction.natvis │ ├── ir_node.cpp │ ├── ir_node.h │ ├── ir_node.natvis │ ├── operations.cpp │ ├── operations.h │ ├── symbol_table.cpp │ ├── symbol_table.h │ ├── version.cpp │ └── version.h │ ├── format │ ├── debug │ │ ├── debug_format.cpp │ │ ├── debug_format.h │ │ ├── mlb_debug_format.cpp │ │ ├── mlb_debug_format.h │ │ ├── rgbds_sym_debug_format.cpp │ │ ├── rgbds_sym_debug_format.h │ │ ├── wla_sym_debug_format.cpp │ │ └── wla_sym_debug_format.h │ └── output │ │ ├── binary_output_format.cpp │ │ ├── binary_output_format.h │ │ ├── gb_output_format.cpp │ │ ├── gb_output_format.h │ │ ├── nes_output_format.cpp │ │ ├── nes_output_format.h │ │ ├── output_format.cpp │ │ ├── output_format.h │ │ ├── sms_output_format.cpp │ │ ├── sms_output_format.h │ │ ├── snes_output_format.cpp │ │ └── snes_output_format.h │ ├── parser │ ├── parser.cpp │ ├── parser.h │ ├── scanner.cpp │ ├── scanner.h │ ├── token.cpp │ └── token.h │ ├── platform │ ├── gb_platform.cpp │ ├── gb_platform.h │ ├── mos6502_platform.cpp │ ├── mos6502_platform.h │ ├── platform.cpp │ ├── platform.h │ ├── pokemon_mini_platform.cpp │ ├── pokemon_mini_platform.h │ ├── spc700_platform.cpp │ ├── spc700_platform.h │ ├── wdc65816_platform.cpp │ ├── wdc65816_platform.h │ ├── z80_platform.cpp │ └── z80_platform.h │ ├── utility │ ├── array_view.h │ ├── bit_flags.h │ ├── bitwise_overloads.h │ ├── enable_bitwise.h │ ├── fwd_unique_ptr.h │ ├── import_manager.cpp │ ├── import_manager.h │ ├── import_options.h │ ├── int128.h │ ├── int128.natvis │ ├── logger.cpp │ ├── logger.h │ ├── macros.h │ ├── misc.cpp │ ├── misc.h │ ├── option_parser.h │ ├── optional.h │ ├── optional.natvis │ ├── overload.h │ ├── path.cpp │ ├── path.h │ ├── ptr_pool.h │ ├── reader.cpp │ ├── reader.h │ ├── report.cpp │ ├── report.h │ ├── report_error_flags.cpp │ ├── report_error_flags.h │ ├── resource_manager.cpp │ ├── resource_manager.h │ ├── scope_guard.h │ ├── source_location.cpp │ ├── source_location.h │ ├── source_location.natvis │ ├── string_pool.h │ ├── string_view.h │ ├── string_view.natvis │ ├── text.cpp │ ├── text.h │ ├── tty.cpp │ ├── tty.h │ ├── unique_ptr.h │ ├── unique_ptr.natvis │ ├── variant.h │ ├── variant.natvis │ ├── win32.cpp │ ├── win32.h │ ├── writer.cpp │ └── writer.h │ └── wiz.cpp ├── syntax └── sublime2 │ └── wiz.tmLanguage ├── tests ├── block │ ├── 6502_alu.wiz │ ├── 6502_do_while.wiz │ ├── 6502_flags.wiz │ ├── 6502_func.wiz │ ├── 6502_func_fallthrough.wiz │ ├── 6502_func_inline.wiz │ ├── 6502_func_tail_call.wiz │ ├── 6502_goto.wiz │ ├── 6502_goto_and2.wiz │ ├── 6502_goto_and3.wiz │ ├── 6502_goto_and_or.wiz │ ├── 6502_goto_bit_a.wiz │ ├── 6502_goto_far.wiz │ ├── 6502_goto_far_synthetic.wiz │ ├── 6502_goto_not_and2.wiz │ ├── 6502_goto_not_or2.wiz │ ├── 6502_goto_or2.wiz │ ├── 6502_goto_or3.wiz │ ├── 6502_if.wiz │ ├── 6502_inc_dec.wiz │ ├── 6502_interrupts.wiz │ ├── 6502_load_store.wiz │ ├── 6502_nested_while.wiz │ ├── 6502_push_pop.wiz │ ├── 6502_return_if.wiz │ ├── 6502_return_on_if_else_path.wiz │ ├── 6502_while.wiz │ ├── 65c02_do_while.wiz │ ├── 65c02_func_inline.wiz │ ├── 65c02_if.wiz │ ├── 65c02_push_pop.wiz │ ├── 65c02_while.wiz │ ├── _6502_memmap.wiz │ ├── _gb_memmap.wiz │ ├── _z80_memmap.wiz │ ├── gb_load_highpage.wiz │ ├── spc700_16_bit.wiz │ ├── spc700_alu.wiz │ ├── spc700_cbne_dbnz.wiz │ ├── spc700_divmod.wiz │ ├── spc700_dp_dp.wiz │ ├── spc700_dp_imm.wiz │ ├── spc700_if.wiz │ ├── spc700_inc_dec.wiz │ ├── spc700_indirect_x_y.wiz │ ├── spc700_jump_indirect.wiz │ ├── spc700_load_store.wiz │ ├── spc700_memory_bit_operations.wiz │ ├── spc700_misc.wiz │ ├── spc700_shift.wiz │ ├── spc700_stack.wiz │ ├── spc700_status_flags.wiz │ ├── spc700_subroutines.wiz │ ├── spc700_tset1_tclr1.wiz │ ├── z80_bitindex_i8.wiz │ ├── z80_func_call.wiz │ ├── z80_func_tail_call.wiz │ └── z80_return_if.wiz ├── failure │ ├── bank.wiz │ ├── duplicate_bank_name.wiz │ ├── duplicate_func_args.wiz │ ├── duplicate_func_args_vars.wiz │ ├── duplicate_func_name.wiz │ ├── duplicate_func_name_namespace.wiz │ ├── duplicate_let_inline_for.wiz │ ├── duplicate_let_name.wiz │ ├── duplicate_let_name_namespace.wiz │ ├── duplicate_var_name.wiz │ ├── duplicate_var_name_namespace.wiz │ ├── func_call_incompatible_assignment.wiz │ ├── func_call_wrong_order.wiz │ ├── func_call_wrong_order_vars.wiz │ ├── in_inside_func.wiz │ ├── inline_for_not_iterable.wiz │ ├── inline_func_break.wiz │ ├── inline_func_continue.wiz │ ├── invalid_attributes.wiz │ ├── invalid_type.wiz │ ├── invalid_type_func.wiz │ ├── invalid_type_iexpr.wiz │ ├── missing_brace_0.wiz │ ├── missing_brace_1.wiz │ ├── missing_brace_2.wiz │ ├── missing_brace_3.wiz │ ├── missing_brace_4.wiz │ └── write_only_read_modify_write.wiz ├── wiztests.py └── wiztests.sh ├── try-in-browser ├── build.bat ├── license.md ├── nes-embed.js ├── style.css ├── try.html └── wiz.js └── vc ├── wiz.sln ├── wiz.vcxproj └── wiz.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | *.d 3 | *.gb 4 | *.gbc 5 | *.gg 6 | *.sms 7 | *.nes 8 | *.sfc 9 | *.smc 10 | *.spc 11 | *.pce 12 | *.nl 13 | *.a26 14 | *.sym 15 | *.[Oo]bj 16 | [Tt]humbs.db 17 | *.DS_Store 18 | *.i 19 | *.vsp 20 | *.ncb 21 | *.suo 22 | *.tlb 23 | *.tlh 24 | *.bak 25 | *.[Cc]ache 26 | *.ilk 27 | *.pdb 28 | *.sdf 29 | *.opensdf 30 | *.vcxproj.user 31 | *.log 32 | *.lib 33 | *.sbr 34 | *.sdf 35 | *.exe 36 | *.pdb 37 | *.out.* 38 | *.a 39 | *.o 40 | *.la 41 | vc/[Dd]ebug 42 | vc/[Oo]ptimized\ [Dd]ebug 43 | vc/[Rr]elease 44 | vc/Win32/ 45 | vc/x64/ 46 | vc/tests/[Dd]ebug 47 | vc/tests/[Rr]elease 48 | ~$* 49 | *.swp 50 | *.swo 51 | *~ 52 | vc/ipch 53 | obj/ 54 | *.VC.db 55 | *.VC.opendb 56 | *.deb 57 | *.vspx 58 | *.psess 59 | *.bin 60 | *.rom 61 | *.mlb 62 | vc/.vs 63 | LOCALFILES/ -------------------------------------------------------------------------------- /common/gb/gbc_util.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | 4 | namespace gbc_util { 5 | in hram { 6 | var gbc_detected : u8; 7 | var gba_detected : u8; 8 | } 9 | 10 | // Must be called near the very start of the program (relies on startup state of a and b registers) 11 | // After: 12 | // gbc_detected = 1 if running on GBC-compatible hardware, 0 otherwise. 13 | // gba_detected = 1 if running on a GBA, 0 otherwise. 14 | func detect() { 15 | if a == 0x11 { 16 | gba_detected = a = b & 1; 17 | gbc_detected = a = 1; 18 | } else { 19 | a = 0; 20 | gba_detected = a; 21 | gbc_detected = a; 22 | } 23 | } 24 | 25 | // Arguments: b = desired speed setting (gb.color.SPEED_MASK_TURBO_ON or gb.color.SPEED_MASK_TURBO_OFF) 26 | func set_speed(desired_speed : u8 in b) { 27 | if { a = gbc_detected; } && a != 0 { 28 | if { a = gb.color.speed & b; } && a != b { 29 | gb.joy.ctrl = a = 0x30; 30 | gb.color.speed = a = gb.color.SPEED_MASK_SWITCH; 31 | stop(); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /common/gb/memory.wiz: -------------------------------------------------------------------------------- 1 | // Fills a range in memory with a specified byte value. 2 | // 3 | // Notes: 4 | // - Some memory is unsafe to write while other hardware is using it. 5 | // - This will not work for 0xFExx addressses. Use the OAM library instead for modifying OAM memory. 6 | // 7 | // Arguments: 8 | // 9 | // hl = destination address 10 | // a = value 11 | // bc = byte count 12 | // 13 | // After: hl += bc, bc = 0, a is preserved. 14 | func memset(dest : *u8 in hl, value : u8 in a, count : u16 in bc) { 15 | memset_inline(dest, value, count); 16 | } 17 | 18 | inline func memset_inline(dest : *u8 in hl, value : u8 in a, count : u16 in bc) { 19 | ++<:count; ++>:count; 20 | goto start; 21 | repeat: 22 | *dest++ = value; 23 | start: 24 | --<:count; goto repeat if !zero; 25 | -->:count; goto repeat if !zero; 26 | } 27 | 28 | 29 | // Copies count bytes from source to destination. 30 | // 31 | // Notes: 32 | // - Some memory is unsafe to write to while other hardware is using it. 33 | // - This will not work for 0xFExx addressses. Use the OAM library instead for modifying OAM memory. 34 | // 35 | // Arguments: 36 | // 37 | // de = destination address 38 | // hl = source address 39 | // bc = byte count 40 | // 41 | // After: de += bc, hl += bc, bc = 0 42 | func memcpy(dest : *u8 in de, source : *u8 in hl, count : u16 in bc) { 43 | memcpy_inline(dest, source, count); 44 | } 45 | 46 | inline func memcpy_inline(dest : *u8 in de, source : *u8 in hl, count : u16 in bc) { 47 | ++<:count; ++>:count; 48 | goto start; 49 | repeat: 50 | *dest++ = a = *source++; 51 | start: 52 | --<:count; goto repeat if !zero; 53 | -->:count; goto repeat if !zero; 54 | } -------------------------------------------------------------------------------- /common/gb/oam.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | 4 | namespace oam { 5 | in hram { 6 | var transfer_func_code : [u8; 9]; 7 | } 8 | 9 | // Initializes the oam library and sets up the oam.transfer routine. 10 | func init() { 11 | de = &transfer_func_code as u16; 12 | hl = _transfer as u16; 13 | c = (_transfer_end as u16 - _transfer as u16) as u8; 14 | do { 15 | *(de as *u8) = a = *(hl++ as *u8); 16 | de++; 17 | c--; 18 | } while !zero; 19 | } 20 | 21 | // Copies sprite data to the OAM. 22 | // 23 | // Requires: 24 | // - Exclusive access to OAM. 25 | // - Interrupts disabled (or during an interrupt, which disables interrupts) 26 | // 27 | // Arguments: 28 | // a = high byte of of sprite data address (must be between 0x00 .. 0xF1) 29 | let transfer = &transfer_func_code as func(addr_hi : u8 in a); 30 | 31 | func _transfer(addr_hi : u8 in a) { 32 | gb.lcd.dma = a; 33 | 34 | // Wait about 200ms 35 | a = 40; 36 | do { 37 | a--; 38 | } while !zero; 39 | } 40 | _transfer_end: 41 | 42 | // Clears out OAM using "safe" instructions that work correctly in the 0xFE00..0xFEFF range. 43 | // 44 | // Requires: Exclusive access to OAM. 45 | func clear() { 46 | hl = 0xFE00; 47 | c = 160; 48 | a = 0; 49 | do { 50 | *(hl as *u8) = a; 51 | l++; 52 | c--; 53 | } while !zero; 54 | } 55 | } -------------------------------------------------------------------------------- /common/gg/hello_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/gg/hello_tiles.chr -------------------------------------------------------------------------------- /common/gg/hello_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/gg/hello_tiles.png -------------------------------------------------------------------------------- /common/gg/minirpg_sprites.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/gg/minirpg_sprites.chr -------------------------------------------------------------------------------- /common/gg/minirpg_sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/gg/minirpg_sprites.png -------------------------------------------------------------------------------- /common/msx/hello_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/msx/hello_tiles.chr -------------------------------------------------------------------------------- /common/msx/hello_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/msx/hello_tiles.png -------------------------------------------------------------------------------- /common/msx/img2msx16.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import os.path 4 | import PIL.Image 5 | 6 | def write_chr(w, h, data, f): 7 | buf = [] 8 | for y in range(0, h, 8): 9 | for x in range(0, w, 8): 10 | for j in range(8): 11 | # Write the bits of this column. 12 | c = 0 13 | for i in range(8): 14 | c = (c << 1) | (1 if data[x + i, y + j] != 0 else 0) 15 | buf.append(c) 16 | f.write(bytes(buf)) 17 | 18 | if __name__ == '__main__': 19 | import sys 20 | 21 | if len(sys.argv) > 1: 22 | WIDTH = 128 23 | HEIGHT = None 24 | for arg in range(1, len(sys.argv)): 25 | filename = sys.argv[arg] 26 | 27 | if filename[0] == '-': 28 | exit('Invalid argument `' + filename + '`.') 29 | continue 30 | 31 | try: 32 | img = PIL.Image.open(filename) 33 | except IOError as e: 34 | if os.path.isdir(filename): 35 | exit(filename + ' is a directory.') 36 | if os.path.exists(filename): 37 | exit(filename + ' has an unsupported filetype, or you lack permission to open it.') 38 | else: 39 | exit('File ' + filename + ' does not exist!') 40 | 41 | w, h = img.size 42 | if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT: 43 | exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.') 44 | if not img.palette: 45 | exit('Image ' + filename + ' has no palette.') 46 | data = img.load() 47 | 48 | save_filename = os.path.splitext(filename)[0] + '.chr' 49 | try: 50 | f = open(save_filename, 'wb') 51 | except Exception as e: 52 | exit('Failure attempting to write ' + save_filename) 53 | 54 | write_chr(w, h, data, f) 55 | f.close() 56 | print(' ' + filename + ' -> ' + save_filename) 57 | else: 58 | print('Usage: ' + sys.argv[0] + ' file [file...]') 59 | print('Converts files like foo.png into MSX1-friendly formats like foo.chr') 60 | -------------------------------------------------------------------------------- /common/nes/bobble_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/bobble_tiles.chr -------------------------------------------------------------------------------- /common/nes/bobble_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/bobble_tiles.png -------------------------------------------------------------------------------- /common/nes/hello_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/hello_tiles.chr -------------------------------------------------------------------------------- /common/nes/hello_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/hello_tiles.png -------------------------------------------------------------------------------- /common/nes/minirpg_sprites.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/minirpg_sprites.chr -------------------------------------------------------------------------------- /common/nes/minirpg_sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/minirpg_sprites.png -------------------------------------------------------------------------------- /common/nes/scroller_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/scroller_tiles.chr -------------------------------------------------------------------------------- /common/nes/scroller_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/nes/scroller_tiles.png -------------------------------------------------------------------------------- /common/pce/hello_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/pce/hello_tiles.chr -------------------------------------------------------------------------------- /common/pce/hello_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/pce/hello_tiles.png -------------------------------------------------------------------------------- /common/pce/minirpg_sprites.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/pce/minirpg_sprites.chr -------------------------------------------------------------------------------- /common/pce/minirpg_sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/pce/minirpg_sprites.png -------------------------------------------------------------------------------- /common/snes/hello_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/snes/hello_tiles.chr -------------------------------------------------------------------------------- /common/snes/hello_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/snes/hello_tiles.png -------------------------------------------------------------------------------- /common/snes/hello_tiles_compact.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/snes/hello_tiles_compact.chr -------------------------------------------------------------------------------- /common/snes/hello_tiles_compact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/snes/hello_tiles_compact.png -------------------------------------------------------------------------------- /common/snes/minirpg_sprites.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/snes/minirpg_sprites.chr -------------------------------------------------------------------------------- /common/snes/minirpg_sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/common/snes/minirpg_sprites.png -------------------------------------------------------------------------------- /examples/2600/finalduck/banks.wiz: -------------------------------------------------------------------------------- 1 | bank rom @ 0xF000 : [constdata; 4096]; 2 | bank ram @ 0x80 : [vardata; 128]; -------------------------------------------------------------------------------- /examples/2600/finalduck/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/2600 main.wiz -o finalduck.a26 4 | -------------------------------------------------------------------------------- /examples/2600/finalduck/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/2600 main.wiz -o finalduck.a26 2 | pause -------------------------------------------------------------------------------- /examples/2600/finalduck/random.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | // Random Number Library 4 | // 5 | // Uses a Galois Linear Feedback Shift Register to generate random numbers. 6 | // http://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs 7 | // 8 | // [random.lo] and [random.hi] must be defined in RAM somewhere. 9 | namespace random { 10 | in ram { 11 | var lo : u8; 12 | var hi : u8; 13 | } 14 | 15 | // The polynomial value is taken from here: 16 | // http://users.ece.cmu.edu/~koopman/lfsr/16.txt 17 | let LSFR_POLYNOMIAL = 0x845F; 18 | 19 | // Get a pseudorandom 16-bit number. 20 | // Precondition: 21 | // random.lo, random.hi are currently seeded to some non-zero value. 22 | // Return: 23 | // random.lo, random.hi = result 24 | func next() { 25 | random.hi = random.hi >>> 1; 26 | random.lo = random.lo >>>># 1; 27 | 28 | if carry { 29 | random.lo = a = random.lo ^ LSFR_POLYNOMIAL as u8; 30 | random.hi = a = random.hi ^ (LSFR_POLYNOMIAL >> 8) as u8; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /examples/2600/finalduck/readme.txt: -------------------------------------------------------------------------------- 1 | =========================== 2 | FINAL DUCK 3 | for Atari 2600 4 | 5 | --------------------------- 6 | 7 | by Andrew G. Crowell 8 | =========================== 9 | 10 | Eat the bread! 11 | Two ducks face against each other. 12 | First player to 10 points wins. 13 | If you shoot the other player, they will be knocked back, and sometimes lose a point. 14 | 15 | Controls 16 | -------- 17 | 18 | Uses the 2600 joystick. 19 | 20 | Directionals = move 21 | Button = fire missile / eat 22 | 23 | How to Open 24 | ----------- 25 | 26 | The ROM is for an Atari 2600. For the best experience, download the ROM onto a 27 | flash cartridge such as the Harmony Cartridge, and play on your Atari 2600 VCS console. 28 | Altenatively, use the Stella emulator. 29 | 30 | Source Code 31 | ----------- 32 | 33 | The source for Final Duck is licensed under the MIT License: 34 | 35 | Copyright (c) 2015 Andrew G. Crowell 36 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy 38 | of this software and associated documentation files (the "Software"), to deal 39 | in the Software without restriction, including without limitation the rights 40 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 41 | copies of the Software, and to permit persons to whom the Software is 42 | furnished to do so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be included in 45 | all copies or substantial portions of the Software. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 48 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 49 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 50 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 51 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 52 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 53 | THE SOFTWARE. -------------------------------------------------------------------------------- /examples/gb/frogegg/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | bank rom @ 0x0000 : [constdata; 0x4000]; 4 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 5 | bank ram @ 0xC000 : [vardata; 0x1000]; 6 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 7 | bank hram @ 0xFF80 : [vardata; 128]; 8 | 9 | in rom @ 0x40 { 10 | push(af); 11 | push(bc); 12 | push(de); 13 | push(hl); 14 | ^goto draw; 15 | } 16 | 17 | in rom @ 0x48 { 18 | push(af); 19 | push(bc); 20 | push(de); 21 | push(hl); 22 | ^goto stat; 23 | } 24 | 25 | in rom @ 0x50 { 26 | push(af); 27 | push(bc); 28 | push(de); 29 | push(hl); 30 | ^goto timer; 31 | } 32 | 33 | in rom @ 0x58 { 34 | push(af); 35 | push(bc); 36 | push(de); 37 | push(hl); 38 | ^goto serial; 39 | } 40 | 41 | in rom @ 0x60 { 42 | push(af); 43 | push(bc); 44 | push(de); 45 | push(hl); 46 | ^goto joypad; 47 | } 48 | 49 | in rom @ 0x100 { 50 | ^goto main; 51 | } -------------------------------------------------------------------------------- /examples/gb/frogegg/build: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/gb main.wiz -o frogegg.gb 4 | -------------------------------------------------------------------------------- /examples/gb/frogegg/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/gb main.wiz -o frogegg.gb -s rgbds 2 | pause -------------------------------------------------------------------------------- /examples/gb/frogegg/font.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/font.chr -------------------------------------------------------------------------------- /examples/gb/frogegg/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/font.png -------------------------------------------------------------------------------- /examples/gb/frogegg/metatilekit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/metatilekit.png -------------------------------------------------------------------------------- /examples/gb/frogegg/mock-dmg-3x-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/mock-dmg-3x-twitter.png -------------------------------------------------------------------------------- /examples/gb/frogegg/mock-dmg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/mock-dmg.png -------------------------------------------------------------------------------- /examples/gb/frogegg/mock-gbc-3x-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/mock-gbc-3x-twitter.png -------------------------------------------------------------------------------- /examples/gb/frogegg/mock-gbc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/mock-gbc.png -------------------------------------------------------------------------------- /examples/gb/frogegg/sprites.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/sprites.chr -------------------------------------------------------------------------------- /examples/gb/frogegg/sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/sprites.png -------------------------------------------------------------------------------- /examples/gb/frogegg/tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/tiles.chr -------------------------------------------------------------------------------- /examples/gb/frogegg/tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/frogegg/tiles.png -------------------------------------------------------------------------------- /examples/gb/frogegg/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | 4 | namespace video { 5 | in ram { 6 | var update_requested : u8; 7 | } 8 | 9 | inline func init() { 10 | update_requested = a = 0; 11 | } 12 | 13 | inline func wait() { 14 | do { 15 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 16 | } while a != gb.lcd.STAT_MODE_VBLANK; 17 | } 18 | 19 | inline func disable() { 20 | wait(); 21 | gb.lcd.ctrl = a = 0; 22 | } 23 | 24 | func request_update() { 25 | hl = &update_requested as u16; 26 | ++*(hl as *u8); 27 | 28 | do { 29 | halt(); 30 | a = *(hl as *u8); 31 | } while a != 0; 32 | } 33 | 34 | func acknowledge_update() { 35 | if { a = update_requested; } && a != 0 { 36 | update_requested = a = 0; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /examples/gb/hypercat/art.wiz: -------------------------------------------------------------------------------- 1 | namespace art { 2 | const background_tileset = embed "bkg_tileset.chr"; 3 | const sprite_tileset = embed "spr_tileset.chr"; 4 | } -------------------------------------------------------------------------------- /examples/gb/hypercat/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | config { 4 | title = "HYPERCAT", 5 | gbc_compatible = false, 6 | } 7 | 8 | bank rom @ 0x0000 : [constdata; 0x4000]; 9 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 10 | bank ram @ 0xC000 : [vardata; 0x1000]; 11 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 12 | bank hram @ 0xFF80 : [vardata; 0x80]; 13 | 14 | in rom @ 0x38 { 15 | while true { 16 | debug_break(); 17 | } 18 | } 19 | 20 | in rom @ 0x40 { 21 | push(af); 22 | push(bc); 23 | push(de); 24 | push(hl); 25 | ^goto draw; 26 | } 27 | 28 | in rom @ 0x48 { 29 | push(af); 30 | push(bc); 31 | push(de); 32 | push(hl); 33 | ^goto stat; 34 | } 35 | 36 | in rom @ 0x50 { 37 | push(af); 38 | push(bc); 39 | push(de); 40 | push(hl); 41 | ^goto timer; 42 | } 43 | 44 | in rom @ 0x58 { 45 | push(af); 46 | push(bc); 47 | push(de); 48 | push(hl); 49 | ^goto serial; 50 | } 51 | 52 | in rom @ 0x60 { 53 | push(af); 54 | push(bc); 55 | push(de); 56 | push(hl); 57 | ^goto joypad; 58 | } 59 | 60 | in rom @ 0x100 { 61 | ^goto main; 62 | } 63 | 64 | in ram { 65 | var t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 : u8; 66 | } -------------------------------------------------------------------------------- /examples/gb/hypercat/bkg_tileset.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/hypercat/bkg_tileset.chr -------------------------------------------------------------------------------- /examples/gb/hypercat/build: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/gb main.wiz -o hypercat.gb 4 | -------------------------------------------------------------------------------- /examples/gb/hypercat/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/gb main.wiz -o hypercat.gb -s rgbds 2 | 3 | pause -------------------------------------------------------------------------------- /examples/gb/hypercat/random.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | namespace random { 4 | in ram { 5 | var index : u8; 6 | var value : u8; 7 | } 8 | 9 | const table : [u8] = [92, 172, 23, 203, 56, 84, 161, 225, 57, 62, 142, 135, 74, 16, 88, 12, 228, 227, 91, 2, 27, 99, 100, 116, 107, 58, 110, 15, 18, 162, 247, 7, 219, 255, 108, 175, 52, 151, 130, 94, 69, 60, 133, 177, 115, 95, 173, 231, 51, 204, 199, 68, 33, 47, 214, 13, 83, 89, 181, 242, 96, 112, 104, 25, 102, 132, 190, 179, 10, 166, 222, 226, 8, 24, 165, 238, 244, 240, 4, 220, 152, 131, 141, 1, 106, 55, 117, 139, 49, 170, 50, 93, 75, 233, 66, 194, 212, 103, 129, 198, 64, 163, 224, 5, 241, 178, 76, 234, 79, 28, 195, 114, 144, 207, 218, 101, 41, 128, 37, 137, 158, 171, 211, 70, 85, 188, 217, 249, 97, 118, 138, 59, 184, 143, 63, 202, 6, 126, 245, 200, 42, 159, 136, 90, 148, 48, 180, 185, 210, 19, 235, 209, 169, 32, 205, 121, 221, 164, 71, 150, 153, 156, 11, 223, 155, 81, 3, 254, 17, 206, 67, 167, 29, 54, 140, 174, 239, 186, 236, 191, 43, 87, 61, 73, 160, 82, 230, 168, 111, 248, 113, 157, 44, 38, 77, 125, 176, 193, 30, 40, 105, 243, 127, 182, 145, 21, 122, 45, 250, 183, 208, 36, 192, 14, 201, 246, 146, 197, 124, 53, 252, 253, 78, 232, 215, 39, 134, 35, 123, 20, 9, 26, 22, 109, 213, 120, 147, 34, 229, 86, 72, 149, 98, 154, 80, 237, 189, 0, 216, 196, 119, 65, 46, 251, 187, 31]; 10 | 11 | func init() { 12 | index = a = 0; 13 | value = a; 14 | } 15 | 16 | func next() : u8 in a { 17 | var table_index : u16 in bc; 18 | var entry : *u8 in hl; 19 | 20 | <:table_index = a = index; 21 | >:table_index = 0; 22 | 23 | <>:entry = <>:&table + <>:table_index; 24 | 25 | table_index++; 26 | index = a = <:table_index; 27 | value = a = *entry; 28 | return a; 29 | } 30 | } -------------------------------------------------------------------------------- /examples/gb/hypercat/spr_tileset.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/hypercat/spr_tileset.chr -------------------------------------------------------------------------------- /examples/gb/hypercat/text.wiz: -------------------------------------------------------------------------------- 1 | namespace text { 2 | debug_break(); 3 | const charset : [u8] = [26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 60, 26, 26, 26, 26, 26, 61, 26, 26, 26, 37, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 26, 26, 26, 26, 26, 26, 26, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 59, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26]; 4 | debug_break(); 5 | 6 | namespace string { 7 | const title = "H Y P E R C A T\0"; 8 | const press_start = "PRESS START\0"; 9 | const andrew_g_crowell = "ANDREW G. CROWELL\0"; 10 | const love = "LOVE\0"; 11 | const food = "FOOD\0"; 12 | const hug = "HUG\0"; 13 | const feed = "FEED\0"; 14 | const clean = "CLEAN\0"; 15 | const lights = "LIGHTS\0"; 16 | } 17 | 18 | func print(message : *const u8 in bc, dest : *u8 in de) { 19 | while { a = *message; } && a != 0 { 20 | var charset_entry : *const u8 in hl; 21 | <:charset_entry = a = --a + <:&charset; 22 | >:charset_entry = a = 0 +# >:&charset; 23 | *dest++ = a = *charset_entry; 24 | message++; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /examples/gb/hypercat/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "oam"; 3 | import "banks"; 4 | import "memory"; 5 | 6 | namespace video { 7 | in ram { 8 | var dark_mode : u8; 9 | var request_redraw : u8; 10 | var oam_buffer_ptr : *u8; 11 | var oam_buffer_data @ 0xCF00 : [u8; 160]; 12 | } 13 | 14 | func init() { 15 | request_redraw = a = 0; 16 | dark_mode = a; 17 | 18 | oam_buffer_clear(); 19 | } 20 | 21 | func wait() { 22 | do { 23 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 24 | } while a != gb.lcd.STAT_MODE_VBLANK; 25 | } 26 | 27 | func delay_frame() { 28 | wait(); 29 | do { 30 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 31 | } while !zero; 32 | } 33 | 34 | func disable() { 35 | wait(); 36 | gb.lcd.ctrl = a = 0; 37 | } 38 | 39 | func request_update() { 40 | var r : *u8 in hl; 41 | r = &request_redraw; 42 | ++*r; 43 | 44 | do { 45 | halt(); 46 | a = *r; 47 | } while a != 0; 48 | } 49 | 50 | func oam_buffer_clear() { 51 | memset(&oam_buffer_data[0], 0, oam_buffer_data.len); 52 | 53 | <:oam_buffer_ptr = a = <:&oam_buffer_data; 54 | >:oam_buffer_ptr = a = >:&oam_buffer_data; 55 | } 56 | 57 | func oam_buffer_open() : *u8 in hl { 58 | var oam : *u8 in hl; 59 | 60 | <>:oam = <>:&oam_buffer_ptr; 61 | a = *oam++; 62 | h = *oam; 63 | l = a; 64 | 65 | return oam; 66 | } 67 | 68 | func oam_buffer_close(oam : *u8 in hl) { 69 | <:oam_buffer_ptr = a = <:oam; 70 | >:oam_buffer_ptr = a = >:oam; 71 | } 72 | 73 | func acknowledge_update() { 74 | if { a = request_redraw; } && a != 0 { 75 | oam.transfer(>:&oam_buffer_data); 76 | 77 | if { a = dark_mode; } && a == 0 { 78 | gb.mono.palette.bg = a = 0b00011011; 79 | } else { 80 | gb.mono.palette.bg = a = 0b11100100; 81 | } 82 | 83 | var r : *u8 in hl; 84 | r = &request_redraw; 85 | --*r; 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /examples/gb/sgb_icd2_6003_test/build_sgb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | cd `dirname $0` 4 | pushd snes 5 | ../../../../bin/wiz -I../../../../common/snes/ -I../ main.wiz --system=wdc65816 -o ../snes_main.bin 6 | popd 7 | pushd gb 8 | ../../../../bin/wiz -I../../../../common/gb/ -I../ main.wiz -o ../sgb_icd2_6003_test.gb 9 | popd -------------------------------------------------------------------------------- /examples/gb/sgb_icd2_6003_test/build_sgb.bat: -------------------------------------------------------------------------------- 1 | pushd snes 2 | ..\..\..\..\bin\wiz.exe -I../../../../common/snes/ -I../ main.wiz --system=wdc65816 -o ../snes_main.bin 3 | @if %ERRORLEVEL% NEQ 0 goto error 4 | popd 5 | pushd gb 6 | ..\..\..\..\bin\wiz.exe -I../../../../common/gb/ -I../ main.wiz -o ../sgb_icd2_6003_test.gb 7 | @if %ERRORLEVEL% NEQ 0 goto error 8 | popd 9 | @echo * Success! 10 | @goto done 11 | :error 12 | @echo * Failed. 13 | popd 14 | :done 15 | pause -------------------------------------------------------------------------------- /examples/gb/sgb_icd2_6003_test/gb/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | config { 4 | title = "HELLO", 5 | sgb_compatible = true, 6 | } 7 | 8 | bank rom @ 0x0000 : [constdata; 0x4000]; 9 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 10 | bank ram @ 0xC000 : [vardata; 0x1000]; 11 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 12 | bank hram @ 0xFF80 : [vardata; 0x80]; 13 | 14 | in rom @ 0x40 { 15 | push(af); 16 | push(bc); 17 | push(de); 18 | push(hl); 19 | ^goto draw; 20 | } 21 | 22 | in rom @ 0x48 { 23 | push(af); 24 | push(bc); 25 | push(de); 26 | push(hl); 27 | ^goto stat; 28 | } 29 | 30 | in rom @ 0x50 { 31 | push(af); 32 | push(bc); 33 | push(de); 34 | push(hl); 35 | ^goto timer; 36 | } 37 | 38 | in rom @ 0x58 { 39 | push(af); 40 | push(bc); 41 | push(de); 42 | push(hl); 43 | ^goto serial; 44 | } 45 | 46 | in rom @ 0x60 { 47 | push(af); 48 | push(bc); 49 | push(de); 50 | push(hl); 51 | ^goto joypad; 52 | } 53 | 54 | in rom @ 0x100 { 55 | ^goto main; 56 | } -------------------------------------------------------------------------------- /examples/gb/sgb_icd2_6003_test/gb/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | 4 | namespace video { 5 | in ram { 6 | namespace request { 7 | var redraw : u8; 8 | } 9 | } 10 | 11 | inline func init() { 12 | request.redraw = a = 0; 13 | } 14 | 15 | inline func wait() { 16 | do { 17 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 18 | } while a != gb.lcd.STAT_MODE_VBLANK; 19 | } 20 | 21 | inline func disable() { 22 | wait(); 23 | gb.lcd.ctrl = a = 0; 24 | } 25 | 26 | func request_update() { 27 | hl = &request.redraw as u16; 28 | ++*(hl as *u8); 29 | 30 | do { 31 | halt(); 32 | a = *(hl as *u8); 33 | } while a != 0; 34 | } 35 | 36 | func acknowledge_update() { 37 | if { a = request.redraw; } && a != 0 { 38 | request.redraw = a = 0; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /examples/gb/sgb_icd2_6003_test/snes/banks.wiz: -------------------------------------------------------------------------------- 1 | config { trim = true } 2 | 3 | let FORMAT_SFC_LOROM = false; 4 | let FORMAT_SGB_BINARY = true; 5 | 6 | bank zeropage @ 0x00 : [vardata; 256]; 7 | bank stackpage @ 0x100 : [vardata; 256]; 8 | bank lowram @ 0x200 : [vardata; 0x1E00]; 9 | bank prg @ 0x7F0000 : [varinitdata; 0x4000]; 10 | bank far_ram @ 0x7E2000 : [vardata; 0xE000]; 11 | bank far_ram2 @ 0x7F8000 : [vardata; 0x8000]; 12 | -------------------------------------------------------------------------------- /examples/gb/sgb_icd2_6003_test/snes/ram.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8 : u16; 6 | var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8 : *u8; 7 | var fptr0 @ &b0, fptr4 @ &b4, fptr8 @ &b8 : far *u8; 8 | 9 | var mosaic : u8; 10 | var timer : u8; 11 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/build_sgb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | cd `dirname $0` 4 | pushd spc 5 | ../../../../bin/wiz -I../../../../common/spc/ -I../ main.wiz --system=spc700 -o ../spc_main.bin 6 | popd 7 | pushd snes 8 | ../../../../bin/wiz -I../../../../common/snes/ -Isgb/ -I../ main.wiz --system=wdc65816 -o ../snes_main.bin 9 | popd 10 | pushd gb 11 | ../../../../bin/wiz -I../../../../common/gb/ -I../ main.wiz -o ../sgb_snes_custom_protocol.gb 12 | popd -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/build_sgb.bat: -------------------------------------------------------------------------------- 1 | pushd spc 2 | ..\..\..\..\bin\wiz.exe -I../../../../common/spc/ -I../ main.wiz --system=spc700 -o ../spc_main.bin 3 | @if %ERRORLEVEL% NEQ 0 goto error 4 | popd 5 | pushd snes 6 | ..\..\..\..\bin\wiz.exe -I../../../../common/snes/ -Isgb/ -I../ main.wiz --system=wdc65816 -o ../snes_main.bin 7 | @if %ERRORLEVEL% NEQ 0 goto error 8 | popd 9 | pushd gb 10 | ..\..\..\..\bin\wiz.exe -I../../../../common/gb/ -I../ main.wiz -o ../sgb_snes_custom_protocol.gb 11 | @if %ERRORLEVEL% NEQ 0 goto error 12 | popd 13 | @echo * Success! 14 | @goto done 15 | :error 16 | @echo * Failed. 17 | popd 18 | :done 19 | pause -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/gb/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | config { 4 | title = "HELLO", 5 | sgb_compatible = true, 6 | } 7 | 8 | bank rom @ 0x0000 : [constdata; 0x4000]; 9 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 10 | bank ram @ 0xC000 : [vardata; 0x1000]; 11 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 12 | bank hram @ 0xFF80 : [vardata; 0x80]; 13 | 14 | in rom @ 0x40 { 15 | push(af); 16 | push(bc); 17 | push(de); 18 | push(hl); 19 | ^goto draw; 20 | } 21 | 22 | in rom @ 0x48 { 23 | push(af); 24 | push(bc); 25 | push(de); 26 | push(hl); 27 | ^goto stat; 28 | } 29 | 30 | in rom @ 0x50 { 31 | push(af); 32 | push(bc); 33 | push(de); 34 | push(hl); 35 | ^goto timer; 36 | } 37 | 38 | in rom @ 0x58 { 39 | push(af); 40 | push(bc); 41 | push(de); 42 | push(hl); 43 | ^goto serial; 44 | } 45 | 46 | in rom @ 0x60 { 47 | push(af); 48 | push(bc); 49 | push(de); 50 | push(hl); 51 | ^goto joypad; 52 | } 53 | 54 | in rom @ 0x100 { 55 | ^goto main; 56 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/gb/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | 4 | namespace video { 5 | in ram { 6 | namespace request { 7 | var redraw : u8; 8 | } 9 | } 10 | 11 | inline func init() { 12 | request.redraw = a = 0; 13 | } 14 | 15 | inline func wait() { 16 | do { 17 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 18 | } while a != gb.lcd.STAT_MODE_VBLANK; 19 | } 20 | 21 | inline func disable() { 22 | wait(); 23 | gb.lcd.ctrl = a = 0; 24 | } 25 | 26 | func request_update() { 27 | hl = &request.redraw as u16; 28 | ++*(hl as *u8); 29 | 30 | do { 31 | halt(); 32 | a = *(hl as *u8); 33 | } while a != 0; 34 | } 35 | 36 | func acknowledge_update() { 37 | if { a = request.redraw; } && a != 0 { 38 | request.redraw = a = 0; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/snes/ram.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8 : u16; 6 | var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8 : *u8; 7 | var fptr0 @ &b0, fptr4 @ &b4, fptr8 @ &b8 : far *u8; 8 | 9 | var mosaic : u8; 10 | var timer : u8; 11 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/snes/sgb/banks.wiz: -------------------------------------------------------------------------------- 1 | config { trim = true } 2 | 3 | let FORMAT_SFC_LOROM = false; 4 | let FORMAT_SGB_BINARY = true; 5 | 6 | bank zeropage @ 0x00 : [vardata; 256]; 7 | bank stackpage @ 0x100 : [vardata; 256]; 8 | bank lowram @ 0x200 : [vardata; 0x1E00]; 9 | bank prg @ 0x7F0000 : [varinitdata; 0x4000]; 10 | bank far_ram @ 0x7E2000 : [vardata; 0xE000]; 11 | bank far_ram2 @ 0x7F8000 : [vardata; 0x8000]; 12 | -------------------------------------------------------------------------------- /examples/gb/sgb_snes_custom_protcol/snes/snes2spc.wiz: -------------------------------------------------------------------------------- 1 | import "snes"; 2 | import "ram"; 3 | 4 | namespace snes2spc { 5 | let IPL_TRANSFER_ROUTINE_ADDRESS = 0xFFC9; 6 | 7 | // Copies length bytes from the source address in SNES memory to the destination address in SPC memory. 8 | // Care must be taken to not overwrite RAM used by the IPL handler routine of the SPC. 9 | // Expects the default IPL transfer routine is available to handle this request. 10 | // NMI and IRQ must be off during transfer. 11 | #[mem8, idx16] 12 | func transfer(dest : u16 in xx, source : far *u8 in fptr0, length : u16 in yy) { 13 | a = 0xAA; 14 | do {} while a != snes.apu.input0; 15 | 16 | snes.apu.output1 = a = 1; 17 | snes.apu.output32 = xx; 18 | snes.apu.output0 = a = 0xCC; 19 | do {} while a != snes.apu.input0; 20 | 21 | xx = yy; 22 | yy = 0; 23 | do { 24 | a = source[yy]; 25 | snes.apu.output1 = a; 26 | snes.apu.output0 = a = y; 27 | do {} while a != snes.apu.input0; 28 | 29 | yy++; 30 | xx--; 31 | } while !zero; 32 | 33 | snes.apu.output1 = a = 0; 34 | snes.apu.output32 = xx = IPL_TRANSFER_ROUTINE_ADDRESS; 35 | snes.apu.output0 = a = snes.apu.input0 + 3; 36 | do {} while a != snes.apu.input0; 37 | } 38 | 39 | // Requests the SPC to begin execution at a specific address in SPC RAM. 40 | // Unless the SPC restores it, the default IPL transfer method will no longer be available after this. 41 | // Expects the default IPL transfer routine is available to handle this request. 42 | // NMI and IRQ must be off during transfer. 43 | #[mem8, idx16] 44 | func dispatch(routine : u16 in xx) { 45 | a = 0xAA; 46 | do {} while a != snes.apu.input0; 47 | 48 | snes.apu.output1 = a = 0; 49 | snes.apu.output32 = xx; 50 | snes.apu.output0 = a = 0xCC; 51 | do {} while a != snes.apu.input0; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/build_sfc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | cd `dirname $0` 4 | pushd spc 5 | ../../../../bin/wiz -I../../../../common/spc/ -I../ main.wiz --system=spc700 -o ../spc_main.bin 6 | popd 7 | pushd snes 8 | ../../../../bin/wiz -I../../../../common/snes/ -Isfc/ -I../ main.wiz -o ../snes_main.sfc 9 | popd 10 | -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/build_sfc.bat: -------------------------------------------------------------------------------- 1 | pushd spc 2 | ..\..\..\..\bin\wiz.exe -I../../../../common/spc/ -I../ main.wiz --system=spc700 -o ../spc_main.bin 3 | @if ERRORLEVEL 1 goto error 4 | popd 5 | pushd snes 6 | ..\..\..\..\bin\wiz.exe -I../../../../common/snes/ -Isfc/ -I../ main.wiz -o ../snes_main.sfc 7 | @if ERRORLEVEL 1 goto error 8 | popd 9 | @echo * Success! 10 | @goto done 11 | :error 12 | @echo * Failed. 13 | popd 14 | :done 15 | pause -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/build_sgb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | cd `dirname $0` 4 | pushd spc 5 | ../../../../bin/wiz -I../../../../common/spc/ -I../ main.wiz --system=spc700 -o ../spc_main.bin 6 | popd 7 | pushd snes 8 | ../../../../bin/wiz -I../../../../common/snes/ -Isgb/ -I../ main.wiz --system=wdc65816 -o ../snes_main.bin 9 | popd 10 | pushd gb 11 | ../../../../bin/wiz -I../../../../common/gb/ -I../ main.wiz -o ../sgb_snes_upload.gb 12 | popd -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/build_sgb.bat: -------------------------------------------------------------------------------- 1 | pushd spc 2 | ..\..\..\..\bin\wiz.exe -I../../../../common/spc/ -I../ main.wiz --system=spc700 -o ../spc_main.bin 3 | @if ERRORLEVEL 1 goto error 4 | popd 5 | pushd snes 6 | ..\..\..\..\bin\wiz.exe -I../../../../common/snes/ -Isgb/ -I../ main.wiz --system=wdc65816 -o ../snes_main.bin 7 | @if ERRORLEVEL 1 goto error 8 | popd 9 | pushd gb 10 | ..\..\..\..\bin\wiz.exe -I../../../../common/gb/ -I../ main.wiz -o ../sgb_snes_upload.gb 11 | @if ERRORLEVEL 1 goto error 12 | popd 13 | @echo * Success! 14 | @goto done 15 | :error 16 | @echo * Failed. 17 | popd 18 | :done 19 | pause -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/gb/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | config { 4 | title = "HELLO", 5 | sgb_compatible = true, 6 | } 7 | 8 | bank rom @ 0x0000 : [constdata; 0x4000]; 9 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 10 | bank ram @ 0xC000 : [vardata; 0x1000]; 11 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 12 | bank hram @ 0xFF80 : [vardata; 0x80]; 13 | 14 | in rom @ 0x40 { 15 | push(af); 16 | push(bc); 17 | push(de); 18 | push(hl); 19 | ^goto draw; 20 | } 21 | 22 | in rom @ 0x48 { 23 | push(af); 24 | push(bc); 25 | push(de); 26 | push(hl); 27 | ^goto stat; 28 | } 29 | 30 | in rom @ 0x50 { 31 | push(af); 32 | push(bc); 33 | push(de); 34 | push(hl); 35 | ^goto timer; 36 | } 37 | 38 | in rom @ 0x58 { 39 | push(af); 40 | push(bc); 41 | push(de); 42 | push(hl); 43 | ^goto serial; 44 | } 45 | 46 | in rom @ 0x60 { 47 | push(af); 48 | push(bc); 49 | push(de); 50 | push(hl); 51 | ^goto joypad; 52 | } 53 | 54 | in rom @ 0x100 { 55 | ^goto main; 56 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/gb/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | 4 | namespace video { 5 | in ram { 6 | namespace request { 7 | var redraw : u8; 8 | } 9 | } 10 | 11 | inline func init() { 12 | request.redraw = a = 0; 13 | } 14 | 15 | inline func wait() { 16 | do { 17 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 18 | } while a != gb.lcd.STAT_MODE_VBLANK; 19 | } 20 | 21 | inline func disable() { 22 | wait(); 23 | gb.lcd.ctrl = a = 0; 24 | } 25 | 26 | func request_update() { 27 | hl = &request.redraw as u16; 28 | ++*(hl as *u8); 29 | 30 | do { 31 | halt(); 32 | a = *(hl as *u8); 33 | } while a != 0; 34 | } 35 | 36 | func acknowledge_update() { 37 | if { a = request.redraw; } && a != 0 { 38 | // TODO: stuff. 39 | 40 | request.redraw = a = 0; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/snes/ram.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8 : u16; 6 | var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8 : *u8; 7 | var fptr0 @ &b0, fptr4 @ &b4, fptr8 @ &b8 : far *u8; 8 | 9 | var mosaic : u8; 10 | var timer : u8; 11 | } 12 | 13 | in far_ram { 14 | var foo : u8; 15 | } -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/snes/sfc/banks.wiz: -------------------------------------------------------------------------------- 1 | config { map_mode = "lorom" } 2 | 3 | let FORMAT_SFC_LOROM = true; 4 | let FORMAT_SGB_BINARY = false; 5 | 6 | bank zeropage @ 0x00 : [vardata; 256]; 7 | bank stack @ 0x100 : [vardata; 256]; 8 | bank prg @ 0x8000 : [constdata; 0x8000]; 9 | bank far_ram @ 0x7F8000 : [vardata; 0x8000]; -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/snes/sgb/banks.wiz: -------------------------------------------------------------------------------- 1 | config { trim = true } 2 | 3 | let FORMAT_SFC_LOROM = false; 4 | let FORMAT_SGB_BINARY = true; 5 | 6 | bank zeropage @ 0x00 : [vardata; 256]; 7 | bank stackpage @ 0x100 : [vardata; 256]; 8 | bank prg @ 0x7F0000 : [varinitdata; 0x4000]; 9 | bank far_ram @ 0x7F8000 : [vardata; 0x8000]; 10 | -------------------------------------------------------------------------------- /examples/gb/sgb_snes_upload/snes/snes2spc.wiz: -------------------------------------------------------------------------------- 1 | import "snes"; 2 | import "ram"; 3 | 4 | namespace snes2spc { 5 | let IPL_TRANSFER_ROUTINE_ADDRESS = 0xFFC9; 6 | 7 | // Copies length bytes from the source address in SNES memory to the destination address in SPC memory. 8 | // Care must be taken to not overwrite RAM used by the IPL handler routine of the SPC. 9 | // Expects the default IPL transfer routine is available to handle this request. 10 | // NMI and IRQ must be off during transfer. 11 | #[mem8, idx16] 12 | func transfer(dest : u16 in xx, source : far *u8 in fptr0, length : u16 in yy) { 13 | a = 0xAA; 14 | do {} while a != snes.apu.input0; 15 | 16 | snes.apu.output1 = a = 1; 17 | snes.apu.output32 = xx; 18 | snes.apu.output0 = a = 0xCC; 19 | do {} while a != snes.apu.input0; 20 | 21 | xx = yy; 22 | yy = 0; 23 | do { 24 | a = source[yy]; 25 | snes.apu.output1 = a; 26 | snes.apu.output0 = a = y; 27 | do {} while a != snes.apu.input0; 28 | 29 | yy++; 30 | xx--; 31 | } while !zero; 32 | 33 | snes.apu.output1 = a = 0; 34 | snes.apu.output32 = xx = IPL_TRANSFER_ROUTINE_ADDRESS; 35 | snes.apu.output0 = a = snes.apu.input0 + 3; 36 | do {} while a != snes.apu.input0; 37 | } 38 | 39 | // Requests the SPC to begin execution at a specific address in SPC RAM. 40 | // Unless the SPC restores it, the default IPL transfer method will no longer be available after this. 41 | // Expects the default IPL transfer routine is available to handle this request. 42 | // NMI and IRQ must be off during transfer. 43 | #[mem8, idx16] 44 | func dispatch(routine : u16 in xx) { 45 | a = 0xAA; 46 | do {} while a != snes.apu.input0; 47 | 48 | snes.apu.output1 = a = 0; 49 | snes.apu.output32 = xx; 50 | snes.apu.output0 = a = 0xCC; 51 | do {} while a != snes.apu.input0; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/gb/snake/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | config { 4 | title = "SNAKE", 5 | } 6 | 7 | bank rom @ 0x0000 : [constdata; 0x4000]; 8 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 9 | bank ram @ 0xC000 : [vardata; 0x1000]; 10 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 11 | bank hram @ 0xFF80 : [vardata; 0x80]; 12 | 13 | in rom @ 0x40 { 14 | push(af); 15 | push(bc); 16 | push(de); 17 | push(hl); 18 | ^goto draw; 19 | } 20 | 21 | in rom @ 0x48 { 22 | push(af); 23 | push(bc); 24 | push(de); 25 | push(hl); 26 | ^goto stat; 27 | } 28 | 29 | in rom @ 0x50 { 30 | push(af); 31 | push(bc); 32 | push(de); 33 | push(hl); 34 | ^goto timer; 35 | } 36 | 37 | in rom @ 0x58 { 38 | push(af); 39 | push(bc); 40 | push(de); 41 | push(hl); 42 | ^goto serial; 43 | } 44 | 45 | in rom @ 0x60 { 46 | push(af); 47 | push(bc); 48 | push(de); 49 | push(hl); 50 | ^goto joypad; 51 | } 52 | 53 | in rom @ 0x100 { 54 | ^goto main; 55 | } -------------------------------------------------------------------------------- /examples/gb/snake/build: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/gb main.wiz -o snake.gb 4 | -------------------------------------------------------------------------------- /examples/gb/snake/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/gb main.wiz -o snake.gb -s rgbds 2 | pause -------------------------------------------------------------------------------- /examples/gb/snake/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "banks"; 3 | import "player"; 4 | 5 | namespace video { 6 | in ram { 7 | namespace request { 8 | var redraw : u8; 9 | var move_snake : u8; 10 | } 11 | } 12 | 13 | inline func init() { 14 | request.redraw = a = 0; 15 | } 16 | 17 | inline func wait() { 18 | do { 19 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 20 | } while a != gb.lcd.STAT_MODE_VBLANK; 21 | } 22 | 23 | inline func disable() { 24 | wait(); 25 | gb.lcd.ctrl = a = 0; 26 | } 27 | 28 | func request_update() { 29 | hl = &request.redraw as u16; 30 | ++*(hl as *u8); 31 | 32 | do { 33 | halt(); 34 | a = *(hl as *u8); 35 | } while a != 0; 36 | } 37 | 38 | func acknowledge_update() { 39 | if { a = request.redraw; } && a != 0 { 40 | if { a = request.move_snake; } && a != 0 { 41 | // Drop trail. 42 | l = a = (player.tail_index << 1) + <:&player.buffer; 43 | h = a = >:&player.buffer +# 0; 44 | a = *(hl++ as *u8); 45 | h = *(hl as *u8); 46 | l = a; 47 | *(hl as *u8) = 1; 48 | 49 | // Check the tile under the head. 50 | l = a = (player.head_index << 1) + <:&player.buffer; 51 | h = a = >:&player.buffer +# 0; 52 | a = *(hl++ as *u8); 53 | h = *(hl as *u8); 54 | l = a; 55 | a = *(hl as *u8); 56 | if a == 0 { 57 | // Die. 58 | disable(); 59 | } else { 60 | // Reposition head. 61 | *(hl as *u8) = 0; 62 | } 63 | 64 | request.move_snake = a = 0; 65 | } 66 | 67 | request.redraw = a = 0; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /examples/gb/xzone/banks.wiz: -------------------------------------------------------------------------------- 1 | import "main"; 2 | 3 | bank rom @ 0x0000 : [constdata; 0x4000]; 4 | bank rom2 @ 0x4000 : [constdata; 0x4000]; 5 | bank ram @ 0xC000 : [vardata; 0x1000]; 6 | bank ram2 @ 0xD000 : [vardata; 0x1000]; 7 | bank hram @ 0xFF80 : [vardata; 0x80]; 8 | 9 | in rom @ 0x40 { 10 | push(af); 11 | push(bc); 12 | push(de); 13 | push(hl); 14 | ^goto draw; 15 | } 16 | 17 | in rom @ 0x48 { 18 | push(af); 19 | push(bc); 20 | push(de); 21 | push(hl); 22 | ^goto stat; 23 | } 24 | 25 | in rom @ 0x50 { 26 | push(af); 27 | push(bc); 28 | push(de); 29 | push(hl); 30 | ^goto timer; 31 | } 32 | 33 | in rom @ 0x58 { 34 | push(af); 35 | push(bc); 36 | push(de); 37 | push(hl); 38 | ^goto serial; 39 | } 40 | 41 | in rom @ 0x60 { 42 | push(af); 43 | push(bc); 44 | push(de); 45 | push(hl); 46 | ^goto joypad; 47 | } 48 | 49 | in rom @ 0x100 { 50 | ^goto main; 51 | } -------------------------------------------------------------------------------- /examples/gb/xzone/build: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/gb main.wiz -o xzone.gb 4 | -------------------------------------------------------------------------------- /examples/gb/xzone/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/gb main.wiz -o xzone.gb -s rgbds 2 | pause -------------------------------------------------------------------------------- /examples/gb/xzone/mask_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/xzone/mask_tiles.png -------------------------------------------------------------------------------- /examples/gb/xzone/mask_tileset.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/gb/xzone/mask_tileset.chr -------------------------------------------------------------------------------- /examples/gb/xzone/tables.wiz: -------------------------------------------------------------------------------- 1 | namespace tables { 2 | const sine : [i16] = [0, 807, 1614, 2419, 3224, 4026, 4826, 5623, 6417, 7206, 7992, 8772, 9547, 10317, 11080, 11836, 12585, 13327, 14060, 14785, 15501, 16208, 16905, 17591, 18267, 18931, 19585, 20226, 20855, 21471, 22074, 22664, 23241, 23803, 24350, 24883, 25401, 25903, 26389, 26860, 27314, 27752, 28173, 28576, 28963, 29331, 29682, 30015, 30330, 30626, 30904, 31163, 31403, 31624, 31825, 32008, 32171, 32314, 32438, 32542, 32627, 32691, 32736, 32761, 32766, 32751, 32716, 32661, 32587, 32493, 32379, 32245, 32092, 31919, 31727, 31516, 31285, 31036, 30767, 30480, 30175, 29851, 29509, 29149, 28772, 28377, 27964, 27535, 27089, 26627, 26148, 25654, 25144, 24618, 24078, 23523, 22954, 22371, 21774, 21165, 20542, 19907, 19259, 18600, 17930, 17249, 16557, 15856, 15145, 14424, 13695, 12957, 12212, 11459, 10699, 9933, 9161, 8383, 7600, 6812, 6020, 5225, 4426, 3625, 2822, 2017, 1210, 403, -403, -1210, -2017, -2822, -3625, -4426, -5225, -6020, -6812, -7600, -8383, -9161, -9933, -10699, -11459, -12212, -12957, -13695, -14424, -15145, -15856, -16557, -17249, -17930, -18600, -19259, -19907, -20542, -21165, -21774, -22371, -22954, -23523, -24078, -24618, -25144, -25654, -26148, -26627, -27089, -27535, -27964, -28377, -28772, -29149, -29509, -29851, -30175, -30480, -30767, -31036, -31285, -31516, -31727, -31919, -32092, -32245, -32379, -32493, -32587, -32661, -32716, -32751, -32766, -32761, -32736, -32691, -32627, -32542, -32438, -32314, -32171, -32008, -31825, -31624, -31403, -31163, -30904, -30626, -30330, -30015, -29682, -29331, -28963, -28576, -28173, -27752, -27314, -26860, -26389, -25903, -25401, -24883, -24350, -23803, -23241, -22664, -22074, -21471, -20855, -20226, -19585, -18931, -18267, -17591, -16905, -16208, -15501, -14785, -14060, -13327, -12585, -11836, -11080, -10317, -9547, -8772, -7992, -7206, -6417, -5623, -4826, -4026, -3224, -2419, -1614, -807, 0]; 3 | } -------------------------------------------------------------------------------- /examples/gb/xzone/video.wiz: -------------------------------------------------------------------------------- 1 | import "gb"; 2 | import "gbc_util"; 3 | import "banks"; 4 | import "oam"; 5 | import "memory"; 6 | import "tables"; 7 | 8 | namespace video { 9 | in ram { 10 | var redraw : u8; 11 | var oam_buffer @ 0xCF00 : [u8; 160]; 12 | } 13 | 14 | func init() { 15 | redraw = a = 0; 16 | memset(&oam_buffer[0], 0, 160); 17 | } 18 | 19 | func wait() { 20 | do { 21 | a = gb.lcd.stat & gb.lcd.STAT_MODE_MASK; 22 | } while a != gb.lcd.STAT_MODE_VBLANK; 23 | } 24 | 25 | func disable() { 26 | wait(); 27 | gb.lcd.ctrl = a = 0; 28 | } 29 | 30 | func request_update() { 31 | hl = &redraw as u16; 32 | ++*(hl as *u8); 33 | 34 | do { 35 | halt(); 36 | a = *(hl as *u8); 37 | } while a != 0; 38 | } 39 | 40 | func acknowledge_update() { 41 | if { a = redraw; } && a != 0 { 42 | oam.transfer((&oam_buffer as u16 >> 8) as u8); 43 | 44 | redraw = a = 0; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /examples/gg/hello/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/gg hello.wiz -o hello.gg 4 | -------------------------------------------------------------------------------- /examples/gg/hello/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/gg hello.wiz -o hello.gg 2 | pause -------------------------------------------------------------------------------- /examples/msx/hello/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/msx hello.wiz --system=z80 -o hello.rom -------------------------------------------------------------------------------- /examples/msx/hello/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/msx hello.wiz --system=z80 -o hello.rom 2 | pause -------------------------------------------------------------------------------- /examples/nes/hello/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/nes hello.wiz --system=6502 -o hello.nes 4 | -------------------------------------------------------------------------------- /examples/nes/hello/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/nes hello.wiz --system=6502 -o hello.nes 2 | pause -------------------------------------------------------------------------------- /examples/nes/shmup/banks.wiz: -------------------------------------------------------------------------------- 1 | bank zeropage @ 0x00 : [vardata; 256]; 2 | bank stackpage @ 0x100 : [vardata; 256]; 3 | bank oampage @ 0x200 : [vardata; 256]; 4 | bank ram @ 0x300 : [vardata; 256 * 5]; 5 | bank prg @ 0x8000 : [constdata; 32768]; 6 | bank chr : [chrdata; 8192]; 7 | 8 | config { 9 | vertical_mirror = true, 10 | battery = false, 11 | } -------------------------------------------------------------------------------- /examples/nes/shmup/bg_tiles.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/shmup/bg_tiles.chr -------------------------------------------------------------------------------- /examples/nes/shmup/bg_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/shmup/bg_tiles.png -------------------------------------------------------------------------------- /examples/nes/shmup/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/nes main.wiz --system=6502 -o shmup.nes 4 | -------------------------------------------------------------------------------- /examples/nes/shmup/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/nes main.wiz --system=6502 -o shmup.nes 2 | pause -------------------------------------------------------------------------------- /examples/nes/shmup/bullet_definitions.wiz: -------------------------------------------------------------------------------- 1 | import "bullet_normal"; 2 | 3 | namespace bullet_definitions { 4 | enum Type : u8 { 5 | NONE, 6 | NORMAL_FORWARD, 7 | NORMAL_DIAGONAL_1, 8 | NORMAL_DIAGONAL_2, 9 | } 10 | 11 | func unused() {} 12 | 13 | const init_handlers_l = [<:unused, <:bullet_normal.init, <:bullet_normal.init, <:bullet_normal.init]; 14 | const init_handlers_h = [>:unused, >:bullet_normal.init, >:bullet_normal.init, >:bullet_normal.init]; 15 | const draw_handlers_l = [<:unused, <:bullet_normal.draw_forward, <:bullet_normal.draw_diagonal_1, <:bullet_normal.draw_diagonal_2]; 16 | const draw_handlers_h = [>:unused, >:bullet_normal.draw_forward, >:bullet_normal.draw_diagonal_1, >:bullet_normal.draw_diagonal_2]; 17 | const update_handlers_l = [<:unused, <:bullet_normal.update_forward, <:bullet_normal.update_diagonal_1, <:bullet_normal.update_diagonal_2]; 18 | const update_handlers_h = [>:unused, >:bullet_normal.update_forward, >:bullet_normal.update_diagonal_1, >:bullet_normal.update_diagonal_2]; 19 | const hitbox_x : [i8] = [0, -4, -4, -4]; 20 | const hitbox_y : [i8] = [0, -6, -6, -6]; 21 | const hitbox_x2 : [i8] = [0, 4, 4, 4]; 22 | const hitbox_y2 : [i8] = [0, 5, 5, 5]; 23 | const damage : [u8] = [0, 1, 1, 1, 1]; 24 | } -------------------------------------------------------------------------------- /examples/nes/shmup/entity_definitions.wiz: -------------------------------------------------------------------------------- 1 | import "player"; 2 | import "enemy_ghost"; 3 | import "fx_enemy_death"; 4 | 5 | namespace entity_definitions { 6 | enum Type : u8 { 7 | NONE, 8 | PLAYER, 9 | ENEMY_GHOST, 10 | FX_ENEMY_DEATH, 11 | } 12 | 13 | func unused() {} 14 | 15 | const init_handlers_l = [<:unused, <:entity_player.init, <:enemy_ghost.init, <:fx_enemy_death.init]; 16 | const init_handlers_h = [>:unused, >:entity_player.init, >:enemy_ghost.init, >:fx_enemy_death.init]; 17 | const draw_handlers_l = [<:unused, <:entity_player.draw, <:enemy_ghost.draw, <:fx_enemy_death.draw]; 18 | const draw_handlers_h = [>:unused, >:entity_player.draw, >:enemy_ghost.draw, >:fx_enemy_death.draw]; 19 | const update_handlers_l = [<:unused, <:entity_player.update, <:enemy_ghost.update, <:fx_enemy_death.update]; 20 | const update_handlers_h = [>:unused, >:entity_player.update, >:enemy_ghost.update, >:fx_enemy_death.update]; 21 | const hitbox_x : [i8] = [0, -1, -8, 0]; 22 | const hitbox_y : [i8] = [0, -4, -8, 0]; 23 | const hitbox_x2 : [i8] = [0, 0, 7, 0]; 24 | const hitbox_y2 : [i8] = [0, 0, 7, 0]; 25 | } -------------------------------------------------------------------------------- /examples/nes/shmup/fx_enemy_death.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | import "video"; 3 | import "entity"; 4 | import "globals"; 5 | import "collision"; 6 | 7 | namespace fx_enemy_death { 8 | func init() { 9 | entity.flash_timer[x] = a = 12; 10 | } 11 | 12 | func draw() { 13 | <:w0 = a = entity.x_pixel[x]; 14 | >:w0 = a = entity.x_screen[x]; 15 | <:w2 = a = entity.y_pixel[x]; 16 | >:w2 = a = entity.y_screen[x]; 17 | 18 | b4 = a = 0; 19 | 20 | if { a = entity.flash_timer[x]; } && a >= 9 { 21 | b4 = a = a & 0x3 | 0x4; 22 | b5 = a = sizeof(typeof(video.orb_frame_data)); 23 | <:ptr6 = a = <:&video.orb_frame_data[0]; 24 | >:ptr6 = a = >:&video.orb_frame_data[0]; 25 | } else if a >= 6 { 26 | b4 = a = a & 0x3 | 0x4; 27 | b5 = a = sizeof(typeof(video.orb2_frame_data)); 28 | <:ptr6 = a = <:&video.orb2_frame_data[0]; 29 | >:ptr6 = a = >:&video.orb2_frame_data[0]; 30 | } else if a >= 3 { 31 | b5 = a = sizeof(typeof(video.orb3_frame_data)); 32 | <:ptr6 = a = <:&video.orb3_frame_data[0]; 33 | >:ptr6 = a = >:&video.orb3_frame_data[0]; 34 | } else { 35 | b5 = a = sizeof(typeof(video.orb4_frame_data)); 36 | <:ptr6 = a = <:&video.orb4_frame_data[0]; 37 | >:ptr6 = a = >:&video.orb4_frame_data[0]; 38 | } 39 | x = oam_buffer_index; 40 | 41 | video.draw_metasprite(x, w0, w2, b4, b5, ptr6); 42 | 43 | oam_buffer_index = x; 44 | x = entity.current_index; 45 | } 46 | 47 | func update() { 48 | if { a = entity.flash_timer[x]; } && !zero { 49 | entity.flash_timer[x]--; 50 | if zero { 51 | entity.type[x] = a = 0; 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /examples/nes/shmup/globals.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8, w10 @ &b10 : u16; 6 | var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8, ptr10 @ &b10 : *u8; 7 | 8 | var oam_buffer_index : u8; 9 | var oam_buffer_free_slots : u8; 10 | 11 | let DRAW_INDEX_FRAME_INCREMENT = 7; 12 | let DRAW_INDEX_LOOP_INCREMENT = 23; 13 | var draw_index : u8; 14 | 15 | var vblank_redraw_requested : u8; 16 | var vblank_disable_screen_requested : u8; 17 | 18 | var timer : u8; 19 | var scroll_x_l : u8; 20 | var scroll_x_h : u8; 21 | var scroll_y_l : u8; 22 | var scroll_y_h : u8; 23 | } 24 | 25 | in oampage { 26 | var oam_buffer_data : [u8; 256]; 27 | } 28 | 29 | in ram { 30 | 31 | } -------------------------------------------------------------------------------- /examples/nes/shmup/joy.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | import "nes"; 3 | 4 | namespace joy { 5 | in zeropage { 6 | var unpress : u8; 7 | var pressed : u8; 8 | } 9 | 10 | func init() { 11 | unpress = a = 0; 12 | pressed = a = 0; 13 | } 14 | 15 | // Reads controller and stores the result in controls 16 | // Derived from code posted by blargg on nesdevwiki 17 | func update() { 18 | // Strobe controller 19 | nes.joy.output = a = 1; 20 | nes.joy.output = a = 0; 21 | 22 | // Read all 8 buttons 23 | for x in 8 .. 1 by -1 { 24 | // Read next button state and mask off low 2 bits. 25 | // Compare with $01, which will set carry flag if 26 | // either or both bits are set. 27 | a = nes.joy.input1 & 0x3; 28 | cmp(a, 1); 29 | // Now, rotate the carry flag into the top of A, 30 | // land shift all the other buttons to the right 31 | pressed = a = pressed >>>># 1; 32 | } 33 | 34 | // Remove unpress flag for controls no longer being held. 35 | unpress = a = unpress & pressed; 36 | // Remove controls that have the unpress flag set. 37 | // (Keep controls that don't have the unpress flag set) 38 | pressed = a = ~unpress & pressed; 39 | } 40 | } -------------------------------------------------------------------------------- /examples/nes/shmup/nes_topdown_shmup1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/shmup/nes_topdown_shmup1.png -------------------------------------------------------------------------------- /examples/nes/shmup/shmup_player_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/shmup/shmup_player_update.png -------------------------------------------------------------------------------- /examples/nes/shmup/shmup_sprites.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/shmup/shmup_sprites.chr -------------------------------------------------------------------------------- /examples/nes/shmup/shmup_sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/shmup/shmup_sprites.png -------------------------------------------------------------------------------- /examples/nes/shmup/utility.wiz: -------------------------------------------------------------------------------- 1 | import "globals"; 2 | 3 | func call_handler(func_ptr : func in w0) { 4 | return (*(&func_ptr as *func))(); 5 | } -------------------------------------------------------------------------------- /examples/nes/slimes/ai_wander.wiz: -------------------------------------------------------------------------------- 1 | import "ram"; 2 | import "entity"; 3 | import "directions"; 4 | import "random"; 5 | 6 | namespace ai_wander { 7 | const direction_wait_base : [u8] = [60]; 8 | const direction_wait_random : [u8] = [60]; 9 | const wander_speed_lo : [u8] = [128]; 10 | const wander_speed_hi : [u8] = [0]; 11 | 12 | let direction_timer = entity.v1; 13 | let wander_setting = entity.v2; 14 | 15 | func init() { 16 | random.next(); 17 | entity.direction[x] = a = a & 0x3; 18 | } 19 | 20 | func update() { 21 | if { a = direction_timer[x]; } && zero { 22 | entity.direction[x] = a = (entity.direction[x] & 0x2) ^ 0x2; 23 | random.next(); 24 | entity.direction[x] = a = a & 1 | entity.direction[x]; 25 | 26 | random.next(); 27 | y = wander_setting[x]; 28 | 29 | while a >= direction_wait_random[y] { 30 | a -= direction_wait_random[y]; 31 | } 32 | direction_timer[x] = a = a + direction_wait_base[y]; 33 | } else { 34 | direction_timer[x]--; 35 | } 36 | 37 | t0 = a = 0; 38 | t1 = a; 39 | t2 = a; 40 | t3 = a; 41 | y = entity.direction[x]; 42 | if { a = directions.x_offset[y]; } && !zero { 43 | if negative { 44 | y = wander_setting[x]; 45 | t0 = a = -wander_speed_lo[y]; 46 | t1 = a = (wander_speed_hi[y] ^ 0xFF) +# 0; 47 | } else { 48 | y = wander_setting[x]; 49 | t0 = a = wander_speed_lo[y]; 50 | t1 = a = wander_speed_hi[y]; 51 | } 52 | } 53 | 54 | y = entity.direction[x]; 55 | if { a = directions.y_offset[y]; } && !zero { 56 | if negative { 57 | y = wander_setting[x]; 58 | t2 = a = -wander_speed_lo[y]; 59 | t3 = a = (wander_speed_hi[y] ^ 0xFF) +# 0; 60 | } else { 61 | y = wander_setting[x]; 62 | t2 = a = wander_speed_lo[y]; 63 | t3 = a = wander_speed_hi[y]; 64 | } 65 | } 66 | 67 | entity.move(t0, t1, t2, t3); 68 | 69 | if { a = t15; } && zero { 70 | direction_timer[x] = a = 0; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /examples/nes/slimes/banks.wiz: -------------------------------------------------------------------------------- 1 | config { 2 | format = "nes", 3 | cart_type = "nrom", 4 | } 5 | 6 | bank zeropage @ 0x00 : [vardata; 256]; 7 | bank stack @ 0x100 : [vardata; 256]; 8 | bank ram @ 0x200 : [vardata; 256 * 6]; 9 | bank prg @ 0x8000 : [prgdata; 0x8000]; 10 | bank chr : [chrdata; 0x2000]; -------------------------------------------------------------------------------- /examples/nes/slimes/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/nes main.wiz --system=6502 -o game.nes 4 | -------------------------------------------------------------------------------- /examples/nes/slimes/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/nes main.wiz --system=6502 -o slimes.nes 2 | pause -------------------------------------------------------------------------------- /examples/nes/slimes/common.wiz: -------------------------------------------------------------------------------- 1 | import "ram"; 2 | import "nes"; 3 | import "data"; 4 | 5 | #[fallthrough] func call_t0() { 6 | goto *(&t0 as *func); 7 | } 8 | 9 | func clear_nametable_vram() { 10 | a = nes.ppu.status; 11 | nes.ppu.address = a = >:nes.ppu.ADDRESS_NAMETABLE_DATA; 12 | nes.ppu.address = a = <:nes.ppu.ADDRESS_NAMETABLE_DATA; 13 | a = 0; 14 | 15 | for y in 8 .. 1 by -1 { 16 | for x in 0 .. 255 { 17 | nes.ppu.data = a; 18 | } 19 | } 20 | } 21 | 22 | 23 | func load_tilemap() { 24 | a = nes.ppu.status; 25 | nes.ppu.address = a = >:nes.ppu.ADDRESS_NAMETABLE_DATA; 26 | nes.ppu.address = a = <:nes.ppu.ADDRESS_NAMETABLE_DATA; 27 | 28 | for y in 0 .. 119 { 29 | a = tilemap_ptr[y]; 30 | 31 | inline for let i in 0 .. 7 { 32 | a <<= 1; 33 | if carry { 34 | x = tilemap_fg_tile; 35 | } else { 36 | x = tilemap_bg_tile; 37 | } 38 | nes.ppu.data = x; 39 | } 40 | } 41 | } 42 | 43 | func load_palette() { 44 | a = nes.ppu.status; 45 | nes.ppu.address = a = >:nes.ppu.ADDRESS_PALETTE_DATA; 46 | nes.ppu.address = a = <:nes.ppu.ADDRESS_PALETTE_DATA; 47 | 48 | for x in 0 .. (nes.ppu.PALETTE_SIZE * nes.ppu.PALETTE_COUNT) - 1 { 49 | nes.ppu.data = a = data.palette[x]; 50 | } 51 | } 52 | 53 | func print_text() { 54 | let START_X = 10; 55 | let START_Y = 3; 56 | let TILE_ADDRESS = nes.ppu.ADDRESS_NAMETABLE_DATA + START_Y * 32 + START_X; 57 | 58 | // Read PPU status to reset its state. 59 | a = nes.ppu.status; 60 | // Now setup the PPU for copying tiles. 61 | nes.ppu.address = a = >:TILE_ADDRESS; 62 | nes.ppu.address = a = <:TILE_ADDRESS; 63 | 64 | x = 0; 65 | 66 | while { a = data.message[x]; } && !zero { 67 | x++; 68 | nes.ppu.data = a; 69 | } 70 | } -------------------------------------------------------------------------------- /examples/nes/slimes/directions.wiz: -------------------------------------------------------------------------------- 1 | namespace directions { 2 | let LEFT = 0; 3 | let RIGHT = 1; 4 | let UP = 2; 5 | let DOWN = 3; 6 | 7 | const x_offset : [u8] = [-1 as u8 as iexpr, 1, 0, 0]; 8 | const y_offset : [u8] = [0, 0, -1 as u8 as iexpr, 1]; 9 | } -------------------------------------------------------------------------------- /examples/nes/slimes/joy.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | import "nes"; 3 | 4 | namespace joy { 5 | in zeropage { 6 | var unpress : u8; 7 | var controls : u8; 8 | } 9 | 10 | func init() { 11 | unpress = a = 0; 12 | controls = a = 0; 13 | } 14 | 15 | // Reads controller and stores the result in controls 16 | // Derived from code posted by blargg on nesdevwiki 17 | func update() { 18 | // Strobe controller 19 | nes.joy.output = a = 1; 20 | nes.joy.output = a = 0; 21 | // Read all 8 buttons 22 | for x in 8 .. 1 by -1 { 23 | // Read next button state and mask off low 2 bits. 24 | // Compare with $01, which will set carry flag if 25 | // either or both bits are set. 26 | a = nes.joy.input1 & 0x3; 27 | cmp(a, 1); 28 | // Now, rotate the carry flag into the top of A, 29 | // land shift all the other buttons to the right 30 | controls = a = controls >>>># 1; 31 | } 32 | // Remove unpress flag for controls no longer being held. 33 | unpress = a = unpress & controls; 34 | // Remove controls that have the unpress flag set. 35 | // (Keep controls that don't have the unpress flag set) 36 | controls = a = ~unpress & controls; 37 | } 38 | } -------------------------------------------------------------------------------- /examples/nes/slimes/ram.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 : u8; 5 | 6 | var tilemap_ptr : *u8; 7 | var tilemap_bg_tile : u8; 8 | var tilemap_fg_tile : u8; 9 | 10 | let DRAW_REQUEST_WAIT_FRAME = 0x01; 11 | let DRAW_REQUEST_UPDATE_SPRITES = 0x02; 12 | var draw_request : u8; 13 | } 14 | 15 | in ram @ 0x200 { 16 | var oam_buffer : [u8; 256]; 17 | } -------------------------------------------------------------------------------- /examples/nes/slimes/random.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | namespace random { 4 | in ram { 5 | var index : u8; 6 | var value : u8; 7 | } 8 | 9 | const table : [u8] = [92, 172, 23, 203, 56, 84, 161, 225, 57, 62, 142, 135, 74, 16, 88, 12, 228, 227, 91, 2, 27, 99, 100, 116, 107, 58, 110, 15, 18, 162, 247, 7, 219, 255, 108, 175, 52, 151, 130, 94, 69, 60, 133, 177, 115, 95, 173, 231, 51, 204, 199, 68, 33, 47, 214, 13, 83, 89, 181, 242, 96, 112, 104, 25, 102, 132, 190, 179, 10, 166, 222, 226, 8, 24, 165, 238, 244, 240, 4, 220, 152, 131, 141, 1, 106, 55, 117, 139, 49, 170, 50, 93, 75, 233, 66, 194, 212, 103, 129, 198, 64, 163, 224, 5, 241, 178, 76, 234, 79, 28, 195, 114, 144, 207, 218, 101, 41, 128, 37, 137, 158, 171, 211, 70, 85, 188, 217, 249, 97, 118, 138, 59, 184, 143, 63, 202, 6, 126, 245, 200, 42, 159, 136, 90, 148, 48, 180, 185, 210, 19, 235, 209, 169, 32, 205, 121, 221, 164, 71, 150, 153, 156, 11, 223, 155, 81, 3, 254, 17, 206, 67, 167, 29, 54, 140, 174, 239, 186, 236, 191, 43, 87, 61, 73, 160, 82, 230, 168, 111, 248, 113, 157, 44, 38, 77, 125, 176, 193, 30, 40, 105, 243, 127, 182, 145, 21, 122, 45, 250, 183, 208, 36, 192, 14, 201, 246, 146, 197, 124, 53, 252, 253, 78, 232, 215, 39, 134, 35, 123, 20, 9, 26, 22, 109, 213, 120, 147, 34, 229, 86, 72, 149, 98, 154, 80, 237, 189, 0, 216, 196, 119, 65, 46, 251, 187, 31]; 10 | 11 | func init() { 12 | index = a = 0; 13 | value = a; 14 | } 15 | 16 | func next() { 17 | y = index; 18 | index++; 19 | value = a = table[y]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/nes/slimes/slime.wiz: -------------------------------------------------------------------------------- 1 | import "ram"; 2 | import "entity"; 3 | import "ai_wander"; 4 | 5 | namespace slime { 6 | func spawn() { 7 | entity.spawn(); 8 | entity.max_hp[x] = a = 10; 9 | entity.hp[x] = a; 10 | entity.pixel_x[x] = a = t0; 11 | entity.pixel_y[x] = a = t1; 12 | entity.update_lo[x] = a = <:update; 13 | entity.update_hi[x] = a = >:update; 14 | 15 | entity.flags[x] = a = entity.flags[x] | entity.FLAGS_HOSTILE; 16 | ai_wander.init(); 17 | ai_wander.wander_setting[x] = a = 0; 18 | } 19 | 20 | func update() { 21 | ai_wander.update(); 22 | 23 | let frame = t0; 24 | entity.anim_timer[x]++; 25 | 26 | frame = a = 0; 27 | if { a = entity.anim_timer[x]; } && a >= 20 { 28 | if a >= 40 { 29 | entity.anim_timer[x] = a = 0; 30 | } 31 | frame++; 32 | } 33 | 34 | entity.frame[x] = a = 20 + frame; 35 | } 36 | } -------------------------------------------------------------------------------- /examples/nes/vwf/banks.wiz: -------------------------------------------------------------------------------- 1 | config { 2 | format = "nes", 3 | } 4 | 5 | bank zeropage @ 0x00 : [vardata; 256]; 6 | bank stack @ 0x100 : [vardata; 256]; 7 | bank ram @ 0x200 : [vardata; 1536]; 8 | bank prg @ 0x8000 : [constdata; 32768]; -------------------------------------------------------------------------------- /examples/nes/vwf/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/nes main.wiz -o vwf.nes 4 | -------------------------------------------------------------------------------- /examples/nes/vwf/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/nes main.wiz -o vwf.nes 2 | pause -------------------------------------------------------------------------------- /examples/nes/vwf/globals.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var ptr0 @ &b0, ptr2 @ &b2, ptr4 @ &b4, ptr6 @ &b6, ptr8 @ &b8, ptr10 @ &b10, ptr12 @ &b12, ptr14 @ &b14 : *u8; 6 | 7 | var text_delay : u8; 8 | var text_ptr : *u8; 9 | var text_color : u8; 10 | var text_hold_timer : u8; 11 | 12 | var text_message_index : u8; 13 | } -------------------------------------------------------------------------------- /examples/nes/vwf/vwf_font.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wiz-lang/wiz/5a8ea1ce15953d6ed9d222a54a31cb6447c79121/examples/nes/vwf/vwf_font.chr -------------------------------------------------------------------------------- /examples/pce/hello/banks.wiz: -------------------------------------------------------------------------------- 1 | bank zeropage @ 0x2000 : [vardata; 256]; 2 | bank stack @ 0x2100 : [vardata; 256]; 3 | bank prg @ 0xE000 : [constdata; 0x2000]; 4 | bank chr @ 0x8000 : [constdata; 0x4000]; 5 | -------------------------------------------------------------------------------- /examples/pce/hello/build: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | cd `dirname $0` 3 | ../../../bin/wiz -I../../../common/pce main.wiz -o hello.pce 4 | -------------------------------------------------------------------------------- /examples/pce/hello/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/pce main.wiz -o hello.pce 2 | pause -------------------------------------------------------------------------------- /examples/pce/hello/ram.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8 : u16; 6 | 7 | var mosaic : u8; 8 | var timer : u8; 9 | } -------------------------------------------------------------------------------- /examples/snes/hello/banks.wiz: -------------------------------------------------------------------------------- 1 | config { 2 | map_mode = "lorom", 3 | fastrom = true, 4 | } 5 | 6 | bank zeropage @ 0x00 : [vardata; 256]; 7 | bank stack @ 0x100 : [vardata; 256]; 8 | bank prg @ 0x808000 : [constdata; 0x8000]; 9 | bank far_ram @ 0xFE8000 : [vardata; 0x8000]; -------------------------------------------------------------------------------- /examples/snes/hello/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set +e 3 | cd `dirname $0` 4 | ../../../bin/wiz -I../../../common/spc spc_main.wiz --system=spc700 -o spc_main.bin 5 | ../../../bin/wiz -I../../../common/snes main.wiz -o hello.sfc 6 | -------------------------------------------------------------------------------- /examples/snes/hello/build.bat: -------------------------------------------------------------------------------- 1 | ..\..\..\bin\wiz.exe -I../../../common/spc spc_main.wiz --system=spc700 -o spc_main.bin 2 | @if ERRORLEVEL 1 goto error 3 | ..\..\..\bin\wiz.exe -I../../../common/snes main.wiz -o hello.sfc 4 | @if ERRORLEVEL 1 goto error 5 | @echo * Success! 6 | @goto done 7 | :error 8 | @echo * Failed. 9 | :done 10 | pause -------------------------------------------------------------------------------- /examples/snes/hello/ram.wiz: -------------------------------------------------------------------------------- 1 | import "banks"; 2 | 3 | in zeropage { 4 | var b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 : u8; 5 | var w0 @ &b0, w2 @ &b2, w4 @ &b4, w6 @ &b6, w8 @ &b8 : u16; 6 | 7 | var mosaic : u8; 8 | var timer : u8; 9 | var wow : *u8; 10 | var wow2 : far *u8; 11 | var wow3 : func(); 12 | var wow4 : far func(); 13 | } 14 | 15 | in far_ram { 16 | var foo : u8; 17 | } -------------------------------------------------------------------------------- /examples/snes/hello/snes2spc.wiz: -------------------------------------------------------------------------------- 1 | import "snes"; 2 | import "ram"; 3 | 4 | namespace snes2spc { 5 | let IPL_TRANSFER_ROUTINE_ADDRESS = 0xFFC9; 6 | 7 | // Copies length bytes from the source address in SNES memory to the destination address in SPC memory. 8 | // Care must be taken to not overwrite RAM used by the IPL handler routine of the SPC. 9 | // Expects the default IPL transfer routine is available to handle this request. 10 | // NMI and IRQ must be off during transfer. 11 | #[mem8, idx16] 12 | func transfer(dest : u16 in xx, source : u16 in w0, length : u16 in yy) { 13 | a = 0xAA; 14 | do {} while a != snes.apu.input0; 15 | 16 | snes.apu.output1 = a = 1; 17 | snes.apu.output32 = xx; 18 | snes.apu.output0 = a = 0xCC; 19 | do {} while a != snes.apu.input0; 20 | 21 | xx = yy; 22 | yy = 0; 23 | do { 24 | a = (w0 as *u8)[yy]; 25 | snes.apu.output1 = a; 26 | snes.apu.output0 = a = y; 27 | do {} while a != snes.apu.input0; 28 | 29 | yy++; 30 | xx--; 31 | } while !zero; 32 | 33 | snes.apu.output1 = a = 0; 34 | snes.apu.output32 = xx = IPL_TRANSFER_ROUTINE_ADDRESS; 35 | snes.apu.output0 = a = snes.apu.input0 + 3; 36 | do {} while a != snes.apu.input0; 37 | } 38 | 39 | // Requests the SPC to begin execution at a specific address in SPC RAM. 40 | // Unless the SPC restores it, the default IPL transfer method will no longer be available after this. 41 | // Expects the default IPL transfer routine is available to handle this request. 42 | // NMI and IRQ must be off during transfer. 43 | #[mem8, idx16] 44 | func dispatch(routine : u16 in xx) { 45 | a = 0xAA; 46 | do {} while a != snes.apu.input0; 47 | 48 | snes.apu.output1 = a = 0; 49 | snes.apu.output32 = xx; 50 | snes.apu.output0 = a = 0xCC; 51 | do {} while a != snes.apu.input0; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | This code is released under an MIT license. 2 | 3 | Copyright (C) 2019 by Andrew G. Crowell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /makefile_find_command.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 2>nul where %1 -------------------------------------------------------------------------------- /src/wiz-emscripten/pre-js.js: -------------------------------------------------------------------------------- 1 | var Module = { 2 | print: function(text) {}, 3 | printErr: function(text) {} 4 | }; -------------------------------------------------------------------------------- /src/wiz/ast/qualifiers.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_AST_QUALIFIERS_H 2 | #define WIZ_AST_QUALIFIERS_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace wiz { 9 | enum class Qualifiers { 10 | None, 11 | 12 | Const = 0x01, 13 | WriteOnly = 0x02, 14 | Extern = 0x04, 15 | Far = 0x08, 16 | LValue = 0x10, 17 | }; 18 | 19 | WIZ_BITWISE_OVERLOADS(Qualifiers) 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /src/wiz/ast/type_expression.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {kind,en} {array} 5 | {kind,en} {designatedStorage} 6 | {kind,en} {function} 7 | {kind,en} {identifier} 8 | {kind,en} {pointer} 9 | {kind,en} {resolvedIdentifier} 10 | {kind,en} {tuple} 11 | {kind,en} {typeOf} 12 | 13 | kind 14 | array 15 | designatedStorage 16 | function 17 | identifier 18 | pointer 19 | resolvedIdentifier 20 | tuple 21 | typeOf 22 | location 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/wiz/compiler/address.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_COMPILER_ADDRESS_H 2 | #define WIZ_COMPILER_ADDRESS_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace wiz { 9 | class Bank; 10 | 11 | struct Address { 12 | Address() = default; 13 | Address(const Address& other) = default; 14 | 15 | Address( 16 | Optional relativePosition, 17 | Optional absolutePosition, 18 | const Bank* bank) 19 | : relativePosition(relativePosition), 20 | absolutePosition(absolutePosition), 21 | bank(bank) {} 22 | 23 | Address& operator =(const Address& other) = default; 24 | 25 | bool operator ==(const Address& other) const { 26 | return relativePosition.hasValue() == other.relativePosition.hasValue() 27 | && (!relativePosition.hasValue() || relativePosition.get() == other.relativePosition.get()) 28 | && absolutePosition.hasValue() == other.absolutePosition.hasValue() 29 | && (!absolutePosition.hasValue() || absolutePosition.get() == other.absolutePosition.get()) 30 | && bank == other.bank; 31 | } 32 | 33 | bool operator !=(const Address& other) const { 34 | return !(*this == other); 35 | } 36 | 37 | Optional relativePosition; 38 | Optional absolutePosition; 39 | const Bank* bank = nullptr; 40 | }; 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /src/wiz/compiler/config.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_COMPILER_CONFIG_H 2 | #define WIZ_COMPILER_CONFIG_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace wiz { 15 | class Report; 16 | struct Expression; 17 | 18 | class Config { 19 | public: 20 | Config(); 21 | ~Config(); 22 | 23 | bool add(Report* report, StringView key, FwdUniquePtr value); 24 | const Expression* get(StringView key) const; 25 | bool has(StringView key) const; 26 | const Expression* checkValue(Report* report, StringView key, bool required) const; 27 | Optional> checkBoolean(Report* report, StringView key, bool required) const; 28 | Optional> checkInteger(Report* report, StringView key, bool required) const; 29 | Optional> checkString(Report* report, StringView key, bool required) const; 30 | Optional> checkFixedString(Report* report, StringView key, std::size_t maxLength, bool required) const; 31 | 32 | private: 33 | std::unordered_map> items; 34 | }; 35 | } 36 | 37 | #endif -------------------------------------------------------------------------------- /src/wiz/compiler/ir_node.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace wiz { 4 | template <> 5 | void FwdDeleter::operator()(const IrNode* ptr) { 6 | delete ptr; 7 | } 8 | 9 | IrNode::~IrNode() { 10 | switch (kind) { 11 | case IrNodeKind::PushRelocation: pushRelocation.~PushRelocation(); break; 12 | case IrNodeKind::PopRelocation: popRelocation.~PopRelocation(); break; 13 | case IrNodeKind::Label: label.~Label(); break; 14 | case IrNodeKind::Code: code.~Code(); break; 15 | case IrNodeKind::Var: var.~Var(); break; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/wiz/compiler/ir_node.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {kind,en} {pushRelocation} 5 | {kind,en} {popRelocation} 6 | {kind,en} {label} 7 | {kind,en} {code} 8 | {kind,en} {var} 9 | 10 | kind 11 | pushRelocation 12 | popRelocation 13 | label 14 | code 15 | var 16 | location 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/wiz/compiler/operations.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_COMPILER_OPERATIONS_H 2 | #define WIZ_COMPILER_OPERATIONS_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | enum class BinaryOperatorKind; 8 | 9 | bool isValidArithmeticOp(BinaryOperatorKind op); 10 | bool isValidComparisonOp(BinaryOperatorKind op); 11 | std::pair applyIntegerArithmeticOp(BinaryOperatorKind op, Int128 left, Int128 right); 12 | bool applyIntegerComparisonOp(BinaryOperatorKind op, Int128 left, Int128 right); 13 | bool applyBooleanComparisonOp(BinaryOperatorKind op, bool left, bool right); 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /src/wiz/compiler/symbol_table.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_COMPILER_SYMBOL_TABLE_H 2 | #define WIZ_COMPILER_SYMBOL_TABLE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace wiz { 13 | struct Definition; 14 | class Report; 15 | 16 | class SymbolTable { 17 | public: 18 | static std::string generateBlockName(); 19 | 20 | SymbolTable(); 21 | SymbolTable(SymbolTable* parent, StringView namespaceName); 22 | ~SymbolTable(); 23 | 24 | SymbolTable* getParent() const; 25 | std::string getFullName() const; 26 | void printKeys(Report* report) const; 27 | 28 | void getDefinitions(std::vector& results) const; 29 | void getDefinitions(std::vector& results) const; 30 | 31 | Definition* addDefinition(Report* report, FwdUniquePtr def); 32 | 33 | template 34 | Definition* createDefinition(Report* report, Args&&... args) { 35 | auto definition = makeFwdUnique(std::forward(args)...); 36 | return addDefinition(report, std::move(definition)); 37 | } 38 | 39 | bool addImport(SymbolTable* scope); 40 | bool addRecursiveImport(SymbolTable* scope); 41 | Definition* findLocalMemberDefinition(StringView name) const; 42 | void findImportedMemberDefinitions(StringView name, std::set& results) const; 43 | void findMemberDefinitions(StringView name, std::set& results) const; 44 | void findUnqualifiedDefinitions(StringView name, std::set& results) const; 45 | 46 | private: 47 | SymbolTable* parent; 48 | StringView namespaceName; 49 | std::vector imports; 50 | std::unordered_map> namesToDefinitions; 51 | }; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/wiz/compiler/version.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace wiz { 6 | namespace version { 7 | extern const char* const Text = "0.1.2 (alpha)"; 8 | 9 | // Numeric version format: 10 | // major (4 digits) 11 | // minor (2 digits) 12 | // revision (2 digits). 13 | const std::uint32_t ID = UINT64_C(102); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/wiz/compiler/version.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_COMPILER_VERSION_H 2 | #define WIZ_COMPILER_VERSION_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | namespace version { 8 | extern const char* const Text; 9 | extern const std::uint32_t ID; 10 | } 11 | } 12 | 13 | #endif -------------------------------------------------------------------------------- /src/wiz/format/debug/debug_format.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace wiz { 7 | DebugFormatCollection::DebugFormatCollection() { 8 | add("mlb"_sv, std::make_unique()); 9 | add("rgbds"_sv, std::make_unique()); 10 | add("wla"_sv, std::make_unique()); 11 | } 12 | 13 | DebugFormatCollection::~DebugFormatCollection() {} 14 | 15 | std::size_t DebugFormatCollection::getFormatNameCount() const { 16 | return formatNames.size(); 17 | } 18 | 19 | StringView DebugFormatCollection::getFormatName(std::size_t index) const { 20 | return formatNames[index]; 21 | } 22 | 23 | void DebugFormatCollection::add(StringView name, std::unique_ptr format) { 24 | const auto ptr = format.get(); 25 | formats.push_back(std::move(format)); 26 | formatNames.push_back(name); 27 | formatsByName[name] = ptr; 28 | } 29 | 30 | DebugFormat* DebugFormatCollection::find(StringView name) const { 31 | const auto match = formatsByName.find(name); 32 | if (match != formatsByName.end()) { 33 | return match->second; 34 | } 35 | return nullptr; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/wiz/format/debug/mlb_debug_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_DEBUG_MLB_DEBUG_FORMAT_H 2 | #define WIZ_FORMAT_DEBUG_MLB_DEBUG_FORMAT_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class MlbDebugFormat : public DebugFormat { 8 | public: 9 | MlbDebugFormat(); 10 | ~MlbDebugFormat() override; 11 | 12 | bool generate(DebugFormatContext& context) override; 13 | }; 14 | } 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/wiz/format/debug/rgbds_sym_debug_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_DEBUG_RGBDS_SYM_DEBUG_FORMAT_H 2 | #define WIZ_FORMAT_DEBUG_RGBDS_SYM_DEBUG_FORMAT_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class RgbdsSymDebugFormat : public DebugFormat { 8 | public: 9 | RgbdsSymDebugFormat(); 10 | ~RgbdsSymDebugFormat() override; 11 | 12 | bool generate(DebugFormatContext& context) override; 13 | }; 14 | } 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/wiz/format/debug/wla_sym_debug_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_DEBUG_WLA_SYM_DEBUG_FORMAT_H 2 | #define WIZ_FORMAT_DEBUG_WLA_SYM_DEBUG_FORMAT_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class WlaSymDebugFormat : public DebugFormat { 8 | public: 9 | WlaSymDebugFormat(); 10 | ~WlaSymDebugFormat() override; 11 | 12 | bool generate(DebugFormatContext& context) override; 13 | }; 14 | } 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/wiz/format/output/binary_output_format.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace wiz { 7 | BinaryOutputFormat::BinaryOutputFormat() {} 8 | BinaryOutputFormat::~BinaryOutputFormat() {} 9 | 10 | bool BinaryOutputFormat::generate(OutputFormatContext& context) { 11 | const auto report = context.report; 12 | const auto config = context.config; 13 | const auto& banks = context.banks; 14 | auto& data = context.data; 15 | 16 | const auto trim = config->checkBoolean(report, "trim"_sv, false); 17 | std::size_t trimmedBankIndex = SIZE_MAX; 18 | 19 | if (trim) { 20 | for (std::size_t i = banks.size() - 1; i < banks.size(); --i) { 21 | if (isBankKindStored(banks[i]->getKind())) { 22 | trimmedBankIndex = i; 23 | break; 24 | } 25 | } 26 | } 27 | 28 | for (std::size_t i = 0; i != banks.size(); ++i) { 29 | const auto& bank = banks[i]; 30 | const auto bankData = trimmedBankIndex == i ? bank->getUsedData() : bank->getData(); 31 | 32 | context.bankOffsets[bank] = data.size(); 33 | data.reserve(data.size() + bankData.size()); 34 | data.insert(data.end(), bankData.begin(), bankData.end()); 35 | } 36 | 37 | return true; 38 | } 39 | } -------------------------------------------------------------------------------- /src/wiz/format/output/binary_output_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_OUTPUT_BINARY_OUTPUT_FORMAT_H 2 | #define WIZ_FORMAT_OUTPUT_BINARY_OUTPUT_FORMAT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | class BinaryOutputFormat : public OutputFormat { 9 | public: 10 | BinaryOutputFormat(); 11 | ~BinaryOutputFormat() override; 12 | 13 | bool generate(OutputFormatContext& context) override; 14 | }; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /src/wiz/format/output/gb_output_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_OUTPUT_GB_OUTPUT_FORMAT_H 2 | #define WIZ_FORMAT_OUTPUT_GB_OUTPUT_FORMAT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | class GameBoyOutputFormat : public OutputFormat { 9 | public: 10 | GameBoyOutputFormat(); 11 | ~GameBoyOutputFormat() override; 12 | 13 | bool generate(OutputFormatContext& context) override; 14 | }; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /src/wiz/format/output/nes_output_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_OUTPUT_NES_OUTPUT_FORMAT_H 2 | #define WIZ_FORMAT_OUTPUT_NES_OUTPUT_FORMAT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | class NesOutputFormat : public OutputFormat { 9 | public: 10 | NesOutputFormat(); 11 | ~NesOutputFormat() override; 12 | 13 | bool generate(OutputFormatContext& context) override; 14 | }; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /src/wiz/format/output/output_format.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace wiz { 9 | Optional OutputFormatContext::getOutputOffset(Address address) const { 10 | const auto bankOffset = bankOffsets.find(address.bank); 11 | return bankOffset != bankOffsets.end() && address.relativePosition.hasValue() 12 | ? address.relativePosition.get() + bankOffset->second 13 | : Optional(); 14 | } 15 | 16 | 17 | 18 | OutputFormatCollection::OutputFormatCollection() { 19 | add("bin"_sv, std::make_unique()); 20 | add("gb"_sv, std::make_unique()); 21 | add("nes"_sv, std::make_unique()); 22 | add("sms"_sv, std::make_unique(SmsOutputFormat::SystemType::MasterSystem)); 23 | add("gg"_sv, std::make_unique(SmsOutputFormat::SystemType::GameGear)); 24 | add("sfc"_sv, std::make_unique()); 25 | add("smc"_sv, std::make_unique()); 26 | } 27 | 28 | OutputFormatCollection::~OutputFormatCollection() {} 29 | 30 | void OutputFormatCollection::add(StringView name, std::unique_ptr format) { 31 | formats[name] = std::move(format); 32 | } 33 | 34 | OutputFormat* OutputFormatCollection::find(StringView name) const { 35 | const auto match = formats.find(name); 36 | if (match != formats.end()) { 37 | return match->second.get(); 38 | } 39 | return nullptr; 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/wiz/format/output/sms_output_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_OUTPUT_SMS_OUTPUT_FORMAT_H 2 | #define WIZ_FORMAT_OUTPUT_SMS_OUTPUT_FORMAT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | class SmsOutputFormat : public OutputFormat { 9 | public: 10 | enum class SystemType { 11 | MasterSystem, 12 | GameGear 13 | }; 14 | 15 | SmsOutputFormat(SystemType systemType); 16 | ~SmsOutputFormat() override; 17 | 18 | bool generate(OutputFormatContext& context) override; 19 | private: 20 | SystemType systemType; 21 | }; 22 | } 23 | 24 | #endif -------------------------------------------------------------------------------- /src/wiz/format/output/snes_output_format.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_FORMAT_OUTPUT_SNES_OUTPUT_FORMAT_H 2 | #define WIZ_FORMAT_OUTPUT_SNES_OUTPUT_FORMAT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | class SnesOutputFormat : public OutputFormat { 9 | public: 10 | SnesOutputFormat(); 11 | ~SnesOutputFormat() override; 12 | 13 | bool generate(OutputFormatContext& context) override; 14 | }; 15 | 16 | class SnesSmcOutputFormat : public OutputFormat { 17 | public: 18 | SnesSmcOutputFormat(); 19 | ~SnesSmcOutputFormat() override; 20 | 21 | bool generate(OutputFormatContext& context) override; 22 | }; 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /src/wiz/parser/scanner.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PARSER_SCANNER_H 2 | #define WIZ_PARSER_SCANNER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace wiz { 13 | class Reader; 14 | class Report; 15 | class Location; 16 | struct Token; 17 | enum class TokenType; 18 | 19 | class Scanner { 20 | public: 21 | Scanner(std::unique_ptr reader, StringView originalPath, StringView expandedPath, StringPool* stringPool, Report* report); 22 | ~Scanner(); 23 | 24 | SourceLocation getLocation() const; 25 | Token next(); 26 | 27 | private: 28 | enum class State; 29 | 30 | std::unique_ptr reader; 31 | SourceLocation location; 32 | SourceLocation commentStartLocation; 33 | StringPool* stringPool; 34 | Report* report; 35 | char terminator; 36 | std::size_t position; 37 | State state; 38 | TokenType baseTokenType; 39 | std::uint8_t intermediateCharCode; 40 | 41 | std::string buffer; 42 | }; 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/wiz/platform/gb_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PLATFORM_GB_H 2 | #define WIZ_PLATFORM_GB_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class GameBoyPlatform : public Platform { 8 | public: 9 | GameBoyPlatform(); 10 | ~GameBoyPlatform() override; 11 | 12 | void reserveDefinitions(Builtins& builtins) override; 13 | Definition* getPointerSizedType() const override; 14 | Definition* getFarPointerSizedType() const override; 15 | std::unique_ptr getTestAndBranch(const Compiler& compiler, const Definition* type, BinaryOperatorKind op, const Expression* left, const Expression* right, std::size_t distanceHint) const override; 16 | Definition* getZeroFlag() const override; 17 | Int128 getPlaceholderValue() const override; 18 | 19 | private: 20 | FwdUniquePtr bitIndex7Expression; 21 | 22 | Definition* pointerSizedType = nullptr; 23 | Definition* farPointerSizedType = nullptr; 24 | 25 | Definition* a = nullptr; 26 | Definition* zero = nullptr; 27 | Definition* carry = nullptr; 28 | Definition* cmp = nullptr; 29 | Definition* bit = nullptr; 30 | }; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/wiz/platform/mos6502_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PLATFORM_MOS6502_H 2 | #define WIZ_PLATFORM_MOS6502_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class Mos6502Platform : public Platform { 8 | public: 9 | enum class Revision { 10 | Base6502, 11 | Base65C02, 12 | Wdc65C02, 13 | Rockwell65C02, 14 | Huc6280, 15 | }; 16 | 17 | Mos6502Platform(Revision revision); 18 | ~Mos6502Platform() override; 19 | 20 | void reserveDefinitions(Builtins& builtins) override; 21 | Definition* getPointerSizedType() const override; 22 | Definition* getFarPointerSizedType() const override; 23 | std::unique_ptr getTestAndBranch(const Compiler& compiler, const Definition* type, BinaryOperatorKind op, const Expression* left, const Expression* right, std::size_t distanceHint) const override; 24 | Definition* getZeroFlag() const override; 25 | Int128 getPlaceholderValue() const override; 26 | 27 | private: 28 | Revision revision; 29 | 30 | Definition* pointerSizedType = nullptr; 31 | Definition* farPointerSizedType = nullptr; 32 | 33 | Definition* a = nullptr; 34 | Definition* x = nullptr; 35 | Definition* y = nullptr; 36 | Definition* zero = nullptr; 37 | Definition* carry = nullptr; 38 | Definition* nointerrupt = nullptr; 39 | Definition* decimal = nullptr; 40 | Definition* overflow = nullptr; 41 | Definition* negative = nullptr; 42 | 43 | Definition* cmp = nullptr; 44 | Definition* bit = nullptr; 45 | Definition* tst = nullptr; 46 | Definition* tstbit = nullptr; 47 | }; 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/wiz/platform/pokemon_mini_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PLATFORM_POKEMON_MINI_H 2 | #define WIZ_PLATFORM_POKEMON_MINI_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class PokemonMiniPlatform : public Platform { 8 | public: 9 | PokemonMiniPlatform(); 10 | ~PokemonMiniPlatform() override; 11 | 12 | void reserveDefinitions(Builtins& builtins) override; 13 | Definition* getPointerSizedType() const override; 14 | Definition* getFarPointerSizedType() const override; 15 | std::unique_ptr getTestAndBranch(const Compiler& compiler, const Definition* type, BinaryOperatorKind op, const Expression* left, const Expression* right, std::size_t distanceHint) const override; 16 | Definition* getZeroFlag() const override; 17 | Int128 getPlaceholderValue() const override; 18 | 19 | private: 20 | Definition* pointerSizedType = nullptr; 21 | Definition* farPointerSizedType = nullptr; 22 | 23 | Definition* a = nullptr; 24 | Definition* ba = nullptr; 25 | Definition* hl = nullptr; 26 | Definition* x = nullptr; 27 | Definition* y = nullptr; 28 | Definition* sp = nullptr; 29 | Definition* zero = nullptr; 30 | Definition* carry = nullptr; 31 | Definition* overflow = nullptr; 32 | Definition* negative = nullptr; 33 | Definition* cmp = nullptr; 34 | Definition* test = nullptr; 35 | }; 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/wiz/platform/spc700_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PLATFORM_SPC700_H 2 | #define WIZ_PLATFORM_SPC700_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | struct Instruction; 8 | 9 | class Spc700Platform : public Platform { 10 | public: 11 | Spc700Platform(); 12 | ~Spc700Platform() override; 13 | 14 | void reserveDefinitions(Builtins& builtins) override; 15 | Definition* getPointerSizedType() const override; 16 | Definition* getFarPointerSizedType() const override; 17 | std::unique_ptr getTestAndBranch(const Compiler& compiler, const Definition* type, BinaryOperatorKind op, const Expression* left, const Expression* right, std::size_t distanceHint) const override; 18 | Definition* getZeroFlag() const override; 19 | Int128 getPlaceholderValue() const override; 20 | 21 | private: 22 | Definition* pointerSizedType = nullptr; 23 | Definition* farPointerSizedType = nullptr; 24 | 25 | Definition* a = nullptr; 26 | Definition* x = nullptr; 27 | Definition* y = nullptr; 28 | Definition* ya = nullptr; 29 | Definition* negative = nullptr; 30 | Definition* overflow = nullptr; 31 | Definition* direct_page = nullptr; 32 | Definition* break_flag = nullptr; 33 | Definition* half_carry = nullptr; 34 | Definition* interrupt = nullptr; 35 | Definition* zero = nullptr; 36 | Definition* carry = nullptr; 37 | Definition* cmp = nullptr; 38 | Definition* cmp_branch_not_equal = nullptr; 39 | Definition* dec_branch_not_zero = nullptr; 40 | }; 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/wiz/platform/wdc65816_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PLATFORM_WDC65816_H 2 | #define WIZ_PLATFORM_WDC65816_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class Wdc65816Platform : public Platform { 8 | public: 9 | Wdc65816Platform(); 10 | ~Wdc65816Platform() override; 11 | 12 | void reserveDefinitions(Builtins& builtins) override; 13 | Definition* getPointerSizedType() const override; 14 | Definition* getFarPointerSizedType() const override; 15 | std::unique_ptr getTestAndBranch(const Compiler& compiler, const Definition* type, BinaryOperatorKind op, const Expression* left, const Expression* right, std::size_t distanceHint) const override; 16 | Definition* getZeroFlag() const override; 17 | Int128 getPlaceholderValue() const override; 18 | 19 | private: 20 | std::uint32_t modeMem8 = 0; 21 | std::uint32_t modeMem16 = 0; 22 | std::uint32_t modeIdx8 = 0; 23 | std::uint32_t modeIdx16 = 0; 24 | std::uint32_t modeRel = 0; 25 | std::uint32_t modeAbs = 0; 26 | 27 | Definition* pointerSizedType = nullptr; 28 | Definition* farPointerSizedType = nullptr; 29 | 30 | Definition* a = nullptr; 31 | Definition* aa = nullptr; 32 | Definition* x = nullptr; 33 | Definition* xx = nullptr; 34 | Definition* y = nullptr; 35 | Definition* yy = nullptr; 36 | Definition* zero = nullptr; 37 | Definition* carry = nullptr; 38 | Definition* nointerrupt = nullptr; 39 | Definition* decimal = nullptr; 40 | Definition* overflow = nullptr; 41 | Definition* negative = nullptr; 42 | 43 | Definition* cmp = nullptr; 44 | Definition* bit = nullptr; 45 | }; 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/wiz/platform/z80_platform.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_PLATFORM_Z80_H 2 | #define WIZ_PLATFORM_Z80_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | class Z80Platform : public Platform { 8 | public: 9 | Z80Platform(); 10 | ~Z80Platform() override; 11 | 12 | void reserveDefinitions(Builtins& builtins) override; 13 | Definition* getPointerSizedType() const override; 14 | Definition* getFarPointerSizedType() const override; 15 | std::unique_ptr getTestAndBranch(const Compiler& compiler, const Definition* type, BinaryOperatorKind op, const Expression* left, const Expression* right, std::size_t distanceHint) const override; 16 | Definition* getZeroFlag() const override; 17 | Int128 getPlaceholderValue() const override; 18 | 19 | private: 20 | FwdUniquePtr bitIndex7Expression; 21 | 22 | Definition* pointerSizedType = nullptr; 23 | Definition* farPointerSizedType = nullptr; 24 | 25 | Definition* a = nullptr; 26 | Definition* b = nullptr; 27 | Definition* zero = nullptr; 28 | Definition* carry = nullptr; 29 | Definition* negative = nullptr; 30 | Definition* cmp = nullptr; 31 | Definition* bit = nullptr; 32 | Definition* dec_branch_not_zero = nullptr; 33 | }; 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/wiz/utility/bitwise_overloads.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_BITWISE_OVERLOADS_H 2 | #define WIZ_UTILITY_BITWISE_OVERLOADS_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #define WIZ_BITWISE_OVERLOADS(T) \ 9 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T operator ~(T value)) { \ 10 | return static_cast(~static_cast(value)); \ 11 | } \ 12 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T operator |(T left, T right)) { \ 13 | return static_cast(static_cast(left) | static_cast(right)); \ 14 | } \ 15 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T operator &(T left, T right)) { \ 16 | return static_cast(static_cast(left) & static_cast(right)); \ 17 | } \ 18 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T operator ^(T left, T right)) { \ 19 | return static_cast(static_cast(left) ^ static_cast(right)); \ 20 | } \ 21 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T& operator |=(T& left, T right)) { return left = left | right; } \ 22 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T& operator &=(T& left, T right)) { return left = left & right; } \ 23 | WIZ_MAYBE_UNUSED_FORCE_INLINE(T& operator ^=(T& left, T right)) { return left = left ^ right; } 24 | 25 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/enable_bitwise.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_ENABLE_BITWISE_H 2 | #define WIZ_UTILITY_ENABLE_BITWISE_H 3 | 4 | #include 5 | namespace wiz { 6 | template struct EnableBitwise { static constexpr bool enabled = false; }; 7 | 8 | template 9 | std::enable_if_t::enabled, T> operator |(T left, T right) { 10 | return static_cast(static_cast>(left) | static_cast>(right)); 11 | } 12 | 13 | template 14 | std::enable_if_t::enabled, T> operator &(T left, T right) { 15 | return static_cast(static_cast>(left) & static_cast>(right)); 16 | } 17 | 18 | template 19 | std::enable_if_t::enabled, T> operator ^(T left, T right) { 20 | return static_cast(static_cast>(left) ^ static_cast>(right)); 21 | } 22 | 23 | template 24 | std::enable_if_t::enabled, T> operator ~(T operand) { 25 | return static_cast(~static_cast>(operand)); 26 | } 27 | 28 | template 29 | std::enable_if_t::enabled, T>& operator |=(T& left, T right) { 30 | left = static_cast(static_cast>(left) | static_cast>(right)); 31 | return left; 32 | } 33 | 34 | template 35 | std::enable_if_t::enabled, T>& operator &=(T& left, T right) { 36 | left = static_cast(static_cast>(left) & static_cast>(right)); 37 | return left; 38 | } 39 | 40 | template 41 | std::enable_if_t::enabled, T>& operator ^=(T& left, T right) { 42 | left = static_cast(static_cast>(left) ^ static_cast>(right)); 43 | return left; 44 | } 45 | } 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/wiz/utility/fwd_unique_ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_FWD_UNIQUE_PTR_H 2 | #define WIZ_UTILITY_FWD_UNIQUE_PTR_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace wiz { 11 | template 12 | struct FwdDeleter { 13 | void operator()(const T* ptr); 14 | }; 15 | 16 | // Unique pointer type that can use an forwarded/incomplete type declaration. 17 | // Requires the type to define an explicit full specialization of FwdDeleter to work. 18 | // 19 | // Usually this is the implementation: 20 | // template<> void FwdDeleter::operator()(const T* ptr) { delete ptr; } 21 | template 22 | using FwdUniquePtr = UniquePtr>>; 23 | //using FwdUniquePtr = std::unique_ptr>>; 24 | 25 | template 26 | FwdUniquePtr makeFwdUnique(Args&&... args) { 27 | return FwdUniquePtr(new T(std::forward(args)...)); 28 | } 29 | } 30 | 31 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/import_manager.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_IMPORT_MANAGER_H 2 | #define WIZ_UTILITY_IMPORT_MANAGER_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace wiz { 13 | class Reader; 14 | class Report; 15 | class ResourceManager; 16 | 17 | enum class ImportResult { 18 | Failed, 19 | JustImported, 20 | AlreadyImported, 21 | }; 22 | 23 | class ImportManager { 24 | public: 25 | ImportManager(StringPool* stringPool, ResourceManager* resourceManager, ArrayView importDirs); 26 | 27 | StringView getStartPath() const; 28 | void setStartPath(StringView value); 29 | 30 | StringView getCurrentPath() const; 31 | void setCurrentPath(StringView value); 32 | 33 | ImportResult attemptAbsoluteImport(StringView originalPath, StringView attemptedPath, ImportOptions importOptions, StringView& displayPath, StringView& canonicalPath, std::unique_ptr& reader); 34 | ImportResult attemptRelativeImport(StringView originalPath, ImportOptions importOptions, StringView& displayPath, StringView& canonicalPath, std::unique_ptr& reader); 35 | ImportResult importModule(StringView originalPath, ImportOptions importOptions, StringView& displayPath, StringView& canonicalPath, std::unique_ptr& reader); 36 | 37 | private: 38 | StringPool* stringPool; 39 | ResourceManager* resourceManager; 40 | ArrayView importDirs; 41 | 42 | StringView startPath; 43 | StringView currentPath; 44 | std::unordered_set alreadyImportedPaths; 45 | }; 46 | } 47 | 48 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/import_options.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_IMPORT_OPTIONS_H 2 | #define WIZ_UTILITY_IMPORT_OPTIONS_H 3 | 4 | #include 5 | 6 | namespace wiz { 7 | enum class ImportOptions { 8 | None, 9 | 10 | AppendExtension = 0x01, 11 | AllowShellResources = 0x02, 12 | }; 13 | 14 | WIZ_BITWISE_OVERLOADS(ImportOptions) 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/int128.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {low} 5 | -{(low ^ 0xFFFFFFFFFFFFFFFF) + 1} 6 | Int128({high,X}{low,Xb}) 7 | 8 | -------------------------------------------------------------------------------- /src/wiz/utility/macros.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_MACROS_H 2 | #define WIZ_UTILITY_MACROS_H 3 | 4 | #ifdef _MSC_VER 5 | #define WIZ_FORCE_INLINE __forceinline 6 | #define WIZ_MAYBE_UNUSED_FORCE_INLINE(x) __forceinline x 7 | #elif defined(__clang__) || defined(__GNUC__) 8 | #define WIZ_FORCE_INLINE inline __attribute__((always_inline)) 9 | #define WIZ_MAYBE_UNUSED_FORCE_INLINE(x) __attribute__((always_inline)) __attribute__((unused)) inline x 10 | #else 11 | #define WIZ_FORCE_INLINE inline 12 | #define WIZ_MAYBE_UNUSED_FORCE_INLINE(x) inline x 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/wiz/utility/misc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace wiz { 6 | std::size_t log2(std::size_t value) { 7 | std::size_t result = 0; 8 | while (value >>= 1) { 9 | ++result; 10 | } 11 | return result; 12 | } 13 | 14 | std::string toHexString(std::size_t value) { 15 | char buffer[std::numeric_limits::digits + 1] = {0}; 16 | std::sprintf(buffer, "%X", static_cast(value)); 17 | return std::string(buffer); 18 | } 19 | } -------------------------------------------------------------------------------- /src/wiz/utility/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_MISC_H 2 | #define WIZ_UTILITY_MISC_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace wiz { 10 | template 11 | void moveAppendAll(std::vector&) {} 12 | 13 | template 14 | void moveAppendAll(std::vector& vec, Arg&& arg, Args&&... args) { 15 | vec.push_back(std::move(arg)); 16 | moveAppendAll(vec, args...); 17 | } 18 | 19 | template 20 | std::vector makeMoveVector(T&& arg, Ts&&... args) { 21 | std::vector result; 22 | moveAppendAll(result, arg, args...); 23 | return std::move(result); 24 | } 25 | 26 | template 27 | void extendNonOwningVector(std::vector& dest, const std::vector& source) { 28 | const auto sourceSize = source.size(); 29 | dest.reserve(dest.size() + sourceSize); 30 | for (std::size_t i = 0; i != sourceSize; ++i) { 31 | dest.push_back(source[i].get()); 32 | } 33 | } 34 | 35 | template 36 | void replaceNonOwningVector(std::vector& dest, const std::vector& source) { 37 | dest.clear(); 38 | extendNonOwningVector(dest, source); 39 | } 40 | 41 | template 42 | std::vector makeNonOwningVector(const std::vector& items) { 43 | std::vector result; 44 | result.reserve(items.size()); 45 | extendNonOwningVector(result, items); 46 | return result; 47 | } 48 | 49 | std::size_t log2(std::size_t value); 50 | 51 | std::string toHexString(std::size_t value); 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/optional.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | empty 5 | {*($T1 *)&(data)} 6 | 7 | *($T1 *)&(data) 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/wiz/utility/overload.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_OVERLOAD_H 2 | #define WIZ_UTILITY_OVERLOAD_H 3 | 4 | namespace wiz { 5 | template 6 | struct Overload; 7 | 8 | template 9 | struct Overload { 10 | public: 11 | Overload(F&& f) : f(std::forward(f)) {} 12 | 13 | template 14 | auto operator()(Ts&&... args) const 15 | -> decltype(std::declval()(std::forward(args)...)) { 16 | return f(std::forward(args)...); 17 | } 18 | 19 | private: 20 | F f; 21 | }; 22 | 23 | template 24 | struct Overload : Overload, Overload { 25 | using Overload::operator(); 26 | using Overload::operator(); 27 | 28 | Overload(F&& f, Fs&&... fs) : 29 | Overload(std::forward(f)), 30 | Overload(std::forward(fs)...) {} 31 | }; 32 | 33 | template 34 | auto makeOverload(Fs... fs) { 35 | return Overload(std::forward(fs)...); 36 | } 37 | } 38 | 39 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/path.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_PATH_H 2 | #define WIZ_UTILITY_PATH_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | namespace path { 9 | std::string getCurrentWorkingDirectory(); 10 | std::string toNormalizedAbsolute(StringView path); 11 | std::string toNormalized(StringView path); 12 | std::string toRelative(StringView path, StringView origin); 13 | std::string getAbsolutePrefix(StringView path); 14 | std::size_t findCommonDirectoryPrefix(StringView path, StringView path2); 15 | StringView getDirectory(StringView path); 16 | StringView getFilename(StringView path); 17 | StringView getExtension(StringView path); 18 | StringView stripExtension(StringView path); 19 | } 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/wiz/utility/reader.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_READER_H 2 | #define WIZ_UTILITY_READER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace wiz { 12 | class Reader { 13 | public: 14 | virtual ~Reader() {} 15 | virtual bool isOpen() const = 0; 16 | virtual bool readLine(std::string& result) = 0; 17 | virtual std::string readFully() = 0; 18 | }; 19 | 20 | class FileReader : public Reader { 21 | public: 22 | FileReader(); 23 | FileReader(StringView filename); 24 | FileReader(StringView filename, std::FILE* file); 25 | FileReader(FileReader&& reader) = default; 26 | ~FileReader() override; 27 | 28 | FileReader& operator =(FileReader&& reader) = default; 29 | 30 | bool isOpen() const override; 31 | bool readLine(std::string& result) override; 32 | std::string readFully() override; 33 | 34 | private: 35 | FileReader(const FileReader&) = delete; 36 | FileReader& operator=(const FileReader&) = delete; 37 | 38 | StringView filename; 39 | std::unique_ptr file; 40 | }; 41 | 42 | class MemoryReader : public Reader { 43 | public: 44 | MemoryReader(const std::string& buffer); 45 | ~MemoryReader() override; 46 | 47 | bool isOpen() const override; 48 | bool readLine(std::string& result) override; 49 | std::string readFully() override; 50 | private: 51 | std::string buffer; 52 | std::size_t offset; 53 | }; 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/wiz/utility/report.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_REPORT_H 2 | #define WIZ_UTILITY_REPORT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace wiz { 12 | class Logger; 13 | class SourceLocation; 14 | 15 | class Report { 16 | public: 17 | static const std::size_t MaxErrors = 64; 18 | 19 | Report(std::unique_ptr logger); 20 | ~Report(); 21 | 22 | void error(const std::string& message, const SourceLocation& location, ReportErrorFlags flags = ReportErrorFlags()); 23 | void notice(const std::string& message); 24 | void log(const std::string& message); 25 | 26 | bool validate(); 27 | bool alive() const; 28 | 29 | Logger* getLogger() const; 30 | 31 | private: 32 | Report(const Report&) = delete; 33 | Report& operator =(const Report&) = delete; 34 | 35 | void abort(); 36 | 37 | std::unique_ptr logger; 38 | bool aborted; 39 | std::size_t errors; 40 | ReportErrorFlags previousFlags; 41 | }; 42 | } 43 | #endif 44 | -------------------------------------------------------------------------------- /src/wiz/utility/report_error_flags.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace wiz { 4 | StringView getReportErrorSeverityName(ReportErrorSeverity severity) { 5 | switch (severity) { 6 | case ReportErrorSeverity::Fatal: return "fatal"_sv; 7 | default: case ReportErrorSeverity::Error: return "error"_sv; 8 | case ReportErrorSeverity::InternalError: return "internal error"_sv; 9 | case ReportErrorSeverity::Note: return "note"_sv; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/wiz/utility/report_error_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_REPORT_ERROR_FLAGS_H 2 | #define WIZ_UTILITY_REPORT_ERROR_FLAGS_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wiz { 8 | enum class ReportErrorFlags { 9 | None, 10 | 11 | Fatal = 0x01, 12 | Continued = 0x02, 13 | InternalError = 0x04, 14 | }; 15 | WIZ_BITWISE_OVERLOADS(ReportErrorFlags) 16 | 17 | enum class ReportErrorSeverity { 18 | Fatal, 19 | Error, 20 | InternalError, 21 | Note, 22 | }; 23 | 24 | StringView getReportErrorSeverityName(ReportErrorSeverity severity); 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/wiz/utility/resource_manager.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_RESOURCE_SYSTEM_H 2 | #define WIZ_UTILITY_RESOURCE_SYSTEM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace wiz { 12 | class Reader; 13 | class Writer; 14 | class ResourceManager { 15 | public: 16 | virtual ~ResourceManager() {} 17 | virtual std::unique_ptr openReader(StringView filename, bool allowShellResources) = 0; 18 | virtual std::unique_ptr openWriter(StringView filename) = 0; 19 | }; 20 | 21 | class FileResourceManager : public ResourceManager { 22 | public: 23 | FileResourceManager(); 24 | virtual ~FileResourceManager() override; 25 | 26 | virtual std::unique_ptr openReader(StringView filename, bool allowShellResources) override; 27 | virtual std::unique_ptr openWriter(StringView filename) override; 28 | }; 29 | 30 | class MemoryResourceManager : public ResourceManager { 31 | public: 32 | MemoryResourceManager(); 33 | virtual ~MemoryResourceManager() override; 34 | 35 | virtual std::unique_ptr openReader(StringView filename, bool allowShellResources) override; 36 | virtual std::unique_ptr openWriter(StringView filename) override; 37 | 38 | void registerReadBuffer(StringView filename, const std::string& buffer); 39 | bool getReadBuffer(StringView filename, std::string& result); 40 | bool getWriteBuffer(StringView filename, std::vector& result); 41 | 42 | private: 43 | std::unordered_map readBuffers; 44 | std::unordered_map> writeBuffers; 45 | }; 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/wiz/utility/scope_guard.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_SCOPE_GUARD_H 2 | #define WIZ_UTILITY_SCOPE_GUARD_H 3 | 4 | namespace wiz { 5 | template 6 | class ScopeGuard { 7 | public: 8 | ScopeGuard() = delete; 9 | 10 | ScopeGuard(T finalizer) 11 | : active(true), 12 | finalizer(finalizer) {} 13 | 14 | ScopeGuard(const ScopeGuard&) = delete; 15 | 16 | ScopeGuard(ScopeGuard&& other) 17 | : active(std::move(other.active)), 18 | finalizer(std::move(other.finalizer)) {} 19 | 20 | ~ScopeGuard() { 21 | if (active) { 22 | finalizer(); 23 | } 24 | } 25 | 26 | ScopeGuard& operator=(const ScopeGuard&) = delete; 27 | 28 | ScopeGuard& operator=(ScopeGuard&& other) { 29 | if (this != &other) { 30 | if (active) { 31 | finalizer(); 32 | } 33 | active = std::move(other.active); 34 | finalizer = std::move(other.finalizer); 35 | } 36 | return *this; 37 | } 38 | 39 | operator bool() const { 40 | return true; 41 | } 42 | 43 | bool isActive() const { 44 | return active; 45 | } 46 | 47 | void activate() { 48 | active = true; 49 | } 50 | 51 | void deactivate() { 52 | active = false; 53 | } 54 | 55 | private: 56 | bool active; 57 | T finalizer; 58 | }; 59 | 60 | template 61 | ScopeGuard makeScopeGuard(T&& finalizer) { 62 | return ScopeGuard(std::forward(finalizer)); 63 | } 64 | } 65 | 66 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/source_location.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace wiz { 4 | SourceLocation::SourceLocation() 5 | : line(0), 6 | displayPath(), 7 | canonicalPath() {} 8 | 9 | SourceLocation::SourceLocation( 10 | StringView path) 11 | : line(0), 12 | displayPath(path), 13 | canonicalPath(path) {} 14 | 15 | SourceLocation::SourceLocation( 16 | StringView path, 17 | std::size_t line) 18 | : line(line), 19 | displayPath(path), 20 | canonicalPath(path) {} 21 | 22 | SourceLocation::SourceLocation( 23 | StringView originalPath, 24 | StringView expandedPath, 25 | std::size_t line) 26 | : line(line), 27 | displayPath(originalPath), 28 | canonicalPath(expandedPath) {} 29 | 30 | std::string SourceLocation::toString() const { 31 | return displayPath.getLength() != 0 32 | ? displayPath.toString() + (line > 0 ? ":" + std::to_string(line) : "") 33 | : ""; 34 | } 35 | } -------------------------------------------------------------------------------- /src/wiz/utility/source_location.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_SOURCE_LOCATION_H 2 | #define WIZ_UTILITY_SOURCE_LOCATION_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace wiz { 9 | class SourceLocation { 10 | public: 11 | SourceLocation(); 12 | SourceLocation(StringView path); 13 | SourceLocation(StringView path, std::size_t line); 14 | SourceLocation(StringView displayPath, StringView canonicalPath, std::size_t line); 15 | 16 | std::string toString() const; 17 | 18 | std::size_t line; 19 | StringView displayPath; 20 | StringView canonicalPath; 21 | }; 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/wiz/utility/source_location.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | empty location 5 | {displayPath,s8b}:{line,d} 6 | 7 | -------------------------------------------------------------------------------- /src/wiz/utility/string_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_STRING_POOL_H 2 | #define WIZ_UTILITY_STRING_POOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace wiz { 14 | class StringPool { 15 | public: 16 | WIZ_FORCE_INLINE StringView intern(const char* source) { 17 | return intern(StringView(source)); 18 | } 19 | 20 | WIZ_FORCE_INLINE StringView intern(const std::string& source) { 21 | return intern(StringView(source)); 22 | } 23 | 24 | StringView intern(StringView source) { 25 | const auto match = views.find(source); 26 | 27 | if (match != views.end()) { 28 | return *match; 29 | } else { 30 | strings.push_back(std::make_unique(source.getData(), source.getLength())); 31 | 32 | const auto view = StringView(*strings.back()); 33 | views.insert(view); 34 | return view; 35 | } 36 | } 37 | 38 | private: 39 | std::vector> strings; 40 | std::unordered_set views; 41 | }; 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/wiz/utility/string_view.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {data,[length]s8} 5 | data,[length]s8 6 | 7 | length 8 | 9 | length 10 | data 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/wiz/utility/tty.cpp: -------------------------------------------------------------------------------- 1 | #define WIZ_TTY_INCLUDE_LOWLEVEL 2 | #include 3 | 4 | namespace wiz { 5 | bool canReceiveEOF(std::FILE* file) { 6 | #ifdef _WIN32 7 | if (const auto handle = getStdHandleForFile(file)) { 8 | if (isMinTTY(handle)) { 9 | return false; 10 | } 11 | } 12 | #endif 13 | static_cast(file); 14 | return true; 15 | } 16 | 17 | bool isTTY(std::FILE* file) { 18 | #ifdef WIZ_ISATTY 19 | if (WIZ_ISATTY(WIZ_FILENO(file))) { 20 | return true; 21 | } 22 | #endif 23 | static_cast(file); 24 | return false; 25 | } 26 | 27 | bool isAnsiTTY(std::FILE* file) { 28 | #ifdef _WIN32 29 | if (const auto handle = getStdHandleForFile(file)) { 30 | return isMinTTY(handle); 31 | } else { 32 | return false; 33 | } 34 | #else 35 | return isTTY(file); 36 | #endif 37 | } 38 | } -------------------------------------------------------------------------------- /src/wiz/utility/tty.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_TTY_H 2 | #define WIZ_UTILITY_TTY_H 3 | 4 | #include 5 | 6 | #ifdef WIZ_TTY_INCLUDE_LOWLEVEL 7 | #ifdef _WIN32 8 | #include 9 | #include 10 | #define WIZ_ISATTY _isatty 11 | #define WIZ_FILENO _fileno 12 | #elif (defined(__APPLE__) || defined(__unix__)) && !defined(__EMSCRIPTEN__) && defined(_POSIX_SOURCE) 13 | #include 14 | #include 15 | 16 | #define WIZ_ISATTY isatty 17 | #define WIZ_FILENO fileno 18 | #endif 19 | #endif 20 | 21 | namespace wiz { 22 | bool canReceiveEOF(std::FILE* file); 23 | bool isTTY(FILE* file); 24 | bool isAnsiTTY(FILE* file); 25 | } 26 | 27 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/unique_ptr.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ptr 5 | empty 6 | {ptr} 7 | 8 | ptr 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/wiz/utility/win32.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_WIN32_H 2 | #define WIZ_UTILITY_WIN32_H 3 | 4 | #ifdef _WIN32 5 | 6 | #include 7 | 8 | #define WIN32_LEAN_AND_MEAN 9 | #include 10 | 11 | namespace wiz { 12 | bool isMinTTY(HANDLE handle); 13 | HANDLE getStdHandleForFile(std::FILE* file); 14 | } 15 | 16 | #endif 17 | 18 | #endif -------------------------------------------------------------------------------- /src/wiz/utility/writer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace wiz { 5 | FileWriter::FileWriter( 6 | StringView filename) 7 | : filename(filename), 8 | file(nullptr, [](std::FILE*) { return 0; }) { 9 | if (const auto f = std::fopen(filename.getData(), "wb")) { 10 | file = std::unique_ptr(f, std::fclose); 11 | } 12 | } 13 | 14 | FileWriter::~FileWriter() {} 15 | 16 | bool FileWriter::isOpen() const { 17 | return file != nullptr; 18 | } 19 | 20 | bool FileWriter::write(const std::vector& data) { 21 | if (!isOpen()) { 22 | return false; 23 | } 24 | if (data.size() == 0) { 25 | return true; 26 | } 27 | return std::fwrite(&data[0], data.size(), 1, file.get()) == 1; 28 | } 29 | 30 | bool FileWriter::write(StringView data) { 31 | if (!isOpen()) { 32 | return false; 33 | } 34 | if (data.size() == 0) { 35 | return true; 36 | } 37 | return std::fwrite(&data[0], data.getLength(), 1, file.get()) == 1; 38 | } 39 | 40 | bool FileWriter::writeLine(StringView data) { 41 | if (!isOpen()) { 42 | return false; 43 | } 44 | return write(data) 45 | && write(text::OsNewLine); 46 | } 47 | 48 | 49 | MemoryWriter::MemoryWriter(std::vector& buffer) 50 | : buffer(buffer) {} 51 | 52 | MemoryWriter::~MemoryWriter() {} 53 | 54 | bool MemoryWriter::isOpen() const { 55 | return true; 56 | } 57 | 58 | bool MemoryWriter::write(const std::vector& data) { 59 | buffer.insert(buffer.end(), data.begin(), data.end()); 60 | return true; 61 | } 62 | 63 | bool MemoryWriter::write(StringView data) { 64 | buffer.insert(buffer.end(), data.begin(), data.end()); 65 | return true; 66 | } 67 | 68 | bool MemoryWriter::writeLine(StringView data) { 69 | return write(data) 70 | && write(text::OsNewLine); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/wiz/utility/writer.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZ_UTILITY_WRITER_H 2 | #define WIZ_UTILITY_WRITER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace wiz { 12 | enum class WriterMode { 13 | Text, 14 | Binary, 15 | }; 16 | 17 | class Writer { 18 | public: 19 | virtual ~Writer() {} 20 | virtual bool isOpen() const = 0; 21 | virtual bool write(const std::vector& data) = 0; 22 | virtual bool write(StringView data) = 0; 23 | virtual bool writeLine(StringView data) = 0; 24 | }; 25 | 26 | class FileWriter : public Writer { 27 | public: 28 | FileWriter(StringView filename); 29 | ~FileWriter() override; 30 | 31 | bool isOpen() const override; 32 | bool write(const std::vector& data) override; 33 | bool write(StringView data) override; 34 | bool writeLine(StringView data) override; 35 | 36 | private: 37 | FileWriter(const FileWriter&) = delete; 38 | FileWriter& operator=(const FileWriter&) = delete; 39 | 40 | StringView filename; 41 | std::unique_ptr file; 42 | }; 43 | 44 | class MemoryWriter : public Writer { 45 | public: 46 | MemoryWriter(std::vector& buffer); 47 | ~MemoryWriter() override; 48 | 49 | bool isOpen() const override; 50 | bool write(const std::vector& data) override; 51 | bool write(StringView data) override; 52 | bool writeLine(StringView data) override; 53 | 54 | private: 55 | std::vector& buffer; 56 | }; 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /tests/block/6502_flags.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // 3 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 4 | // 5 | // Disassembly created using radare2 6 | // 7 | // `--> r2 -a6502 -m0x8000 6502_flags.6502.bin 8 | // [0x00008000]> e asm.bytespace=true 9 | // [0x00008000]> pd 10 | // 11 | 12 | import "_6502_memmap.wiz"; 13 | 14 | // BLOCK 000000 15 | in prg { 16 | 17 | func set_clear_flags { 18 | // BLOCK 18 clc 19 | // BLOCK 38 sec 20 | carry = false; 21 | carry = true; 22 | 23 | // BLOCK d8 cld 24 | // BLOCK f8 sed 25 | decimal = false; 26 | decimal = true; 27 | 28 | // BLOCK 58 cli 29 | // BLOCK 78 sei 30 | nointerrupt = false; 31 | nointerrupt = true; 32 | 33 | // BLOCK b8 clv 34 | overflow = false; 35 | 36 | // BLOCK 60 rts 37 | } 38 | 39 | // BLOCK ff 40 | } 41 | 42 | -------------------------------------------------------------------------------- /tests/block/6502_func_fallthrough.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // 3 | // NOTE: does not use zero-page instructions so huc6280 can be tested 4 | // 5 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 6 | // 7 | // Disassembly created using radare2 8 | // 9 | // `--> r2 -a6502 -m0x8000 6502_func_fallthrough.6502.bin 10 | // [0x00008000]> e asm.bytespace=true 11 | // [0x00008000]> pd 12 | // 13 | 14 | import "_6502_memmap.wiz"; 15 | 16 | // BLOCK 000000 17 | in prg { 18 | 19 | 20 | #[fallthrough] 21 | func fallthrough_test_1() { 22 | // BLOCK 000000 ad 00 02 lda 0x0200 23 | a = ram_u8_200; 24 | } 25 | func fallthrough_test_1_a(value : u8 in a) { 26 | // BLOCK 000003 8d 06 02 sta 0x0206 27 | // BLOCK 60 rts 28 | ram_block_206[0] = value; 29 | } 30 | 31 | 32 | 33 | func fallthrough_test_2() { 34 | // BLOCK 000007 ad 01 02 lda 0x0201 35 | return fallthrough_test_2_a(a = ram_u8_201); 36 | } 37 | func fallthrough_test_2_a(value : u8 in a) { 38 | // BLOCK 00000a 8d 07 02 sta 0x0207 39 | // BLOCK 60 rts 40 | ram_block_206[1] = value; 41 | } 42 | 43 | 44 | func call_test() { 45 | // BLOCK 00000e 20 00 80 jsr 0x8000 46 | fallthrough_test_1(); 47 | 48 | // BLOCK a9 01 lda #0x01 49 | // BLOCK 20 03 80 jsr 0x8003 50 | fallthrough_test_1_a(1); 51 | 52 | // BLOCK 20 07 80 jsr 0x8007 53 | fallthrough_test_2(); 54 | 55 | // BLOCK a9 02 lda #0x02 56 | // BLOCK 20 0a 80 jsr 0x800a 57 | fallthrough_test_2_a(2); 58 | 59 | // BLOCK 60 rts 60 | } 61 | 62 | // BLOCK ff 63 | } 64 | 65 | -------------------------------------------------------------------------------- /tests/block/6502_func_inline.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 2 | // 3 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 4 | // 5 | // Disassembly created using radare2 6 | // 7 | // `--> r2 -a6502 -m0x8000 6502_func_inline.6502.bin 8 | // [0x00008000]> e asm.bytespace=true 9 | // [0x00008000]> pd 10 | // 11 | 12 | import "_6502_memmap.wiz"; 13 | 14 | // BLOCK 000000 15 | in prg { 16 | 17 | 18 | // BLOCK 000000 ae 00 02 ldx 0x0200 19 | // BLOCK e0 2a cpx #0x2a 20 | // BLOCK b0 04 bcs 0x00800b 21 | // BLOCK e8 inx 22 | // BLOCK 4c 0c 80 jmp 0x800c 23 | // BLOCK 00000b ca dex 24 | // BLOCK 00000c ea nop 25 | // BLOCK 60 rts 26 | inline func inline_return(x : u8 in x) { 27 | if x < 42 { 28 | x++; 29 | return; 30 | } 31 | x--; 32 | } 33 | func inline_return_call() { 34 | inline_return(ram_u8_200); 35 | 36 | nop(); 37 | } 38 | 39 | 40 | // BLOCK 00000e ad 01 02 lda 0x0201 41 | // BLOCK 18 clc 42 | // BLOCK 69 0f adc #0x0f 43 | // BLOCK 18 clc 44 | // BLOCK 7d 06 02 adc 0x0206,x 45 | // BLOCK 18 clc 46 | // BLOCK 69 0f adc #0x0f 47 | // BLOCK 60 rts 48 | inline func inline_func1(a : u8 in a, x : u8 in x) : u8 in a { 49 | return a + ram_block_206[x]; 50 | } 51 | inline func inline_func2(a : u8 in a) : u8 in a { 52 | return a + 15; 53 | } 54 | func call_inline_func() { 55 | a = ram_u8_201; 56 | a = inline_func2(a); 57 | a = inline_func1(a, x); 58 | a = inline_func2(a); 59 | } 60 | 61 | 62 | // BLOCK ff 63 | } 64 | 65 | -------------------------------------------------------------------------------- /tests/block/6502_func_tail_call.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 wdc65816 2 | // 3 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 4 | // 5 | // Disassembly created using radare2 6 | // 7 | // `--> r2 -a6502 -m0x8000 6502_func_tail_call.6502.bin 8 | // [0x00008000]> e asm.bytespace=true 9 | // [0x00008000]> pd 10 | // 11 | 12 | import "_6502_memmap.wiz"; 13 | 14 | // BLOCK 000000 15 | in prg { 16 | 17 | func first_function { 18 | // BLOCK 000000 60 rts 19 | } 20 | 21 | 22 | const blank_bytes : [u8] = [0 ; 0xff]; 23 | 24 | 25 | func tail_call_test() { 26 | // BLOCK 000100 4c 00 80 jmp 0x8000 27 | ^return first_function(); 28 | } 29 | 30 | func tail_call_test2() { 31 | // BLOCK 000103 20 00 80 jsr 0x8000 32 | first_function(); 33 | // BLOCK 000106 60 rts 34 | } 35 | 36 | // BLOCK ff 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tests/block/6502_goto_and2.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_goto_and2.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | in prg { 16 | 17 | func goto_and2_test { 18 | 19 | // BLOCK 000000 c9 64 cmp #0x64 20 | // BLOCK d0 04 bne 0x008008 21 | // BLOCK c9 2a cmp #0x2a 22 | // BLOCK f0 f8 beq 0x008000 23 | LogicalAndTestLabel: 24 | goto LogicalAndTestLabel if 25 | a == 100 26 | && a == 42; 27 | 28 | // BLOCK 000008 60 rts 29 | } 30 | 31 | // BLOCK ff 32 | } -------------------------------------------------------------------------------- /tests/block/6502_goto_and3.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_goto_and3.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | in prg { 16 | 17 | func goto_and3_test { 18 | 19 | // BLOCK 000000 c9 64 cmp #0x64 20 | // BLOCK d0 08 bne 0x00800C 21 | // BLOCK c9 2a cmp #0x2a 22 | // BLOCK d0 04 bne 0x00800C 23 | // BLOCK c9 1f cmp #0x1f 24 | // BLOCK f0 f4 beq 0x008000 25 | LogicalAndTestLabel: 26 | // (((a == 100) && (a != 42)) && a != 31) 27 | goto LogicalAndTestLabel if 28 | a == 100 29 | && a == 42 30 | && a == 31; 31 | 32 | // BLOCK 00000C 60 rts 33 | } 34 | 35 | // BLOCK ff 36 | } -------------------------------------------------------------------------------- /tests/block/6502_goto_not_and2.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_goto_and2.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | in prg { 16 | 17 | func goto_not_and2_test { 18 | // De Morgan's Laws (applied to negation of &&): 19 | // !(a && b) = !a || !b 20 | // 21 | // Expands to the following branch sequence: 22 | // goto label if !a; 23 | // goto label if !b; 24 | 25 | // BLOCK 000000 c9 64 cmp #0x64 26 | // BLOCK d0 fc bne 0x008000 27 | // BLOCK c9 2a cmp #0x2a 28 | // BLOCK d0 f8 bne 0x008000 29 | LogicalOrOfNotTestLabel: 30 | goto LogicalOrOfNotTestLabel if 31 | a != 100 32 | || a != 42; 33 | 34 | // BLOCK 000008 c9 64 cmp #0x64 35 | // BLOCK d0 fc bne 0x008008 36 | // BLOCK c9 2a cmp #0x2a 37 | // BLOCK d0 f8 bne 0x008008 38 | LogicalNotOfAndTestLabel: 39 | goto LogicalNotOfAndTestLabel if 40 | !(a == 100 41 | && a == 42); 42 | 43 | // BLOCK 000010 60 rts 44 | } 45 | 46 | // BLOCK ff 47 | } -------------------------------------------------------------------------------- /tests/block/6502_goto_not_or2.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_goto_and2.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | in prg { 16 | 17 | func goto_not_or2_test { 18 | 19 | // De Morgan's Laws (applied to negation of ||): 20 | // !(a || b) = !a && !b 21 | // 22 | // Expands to the following branch sequence: 23 | // goto skip if a; 24 | // goto label if !b; 25 | // skip: 26 | 27 | // BLOCK 000000 c9 64 cmp #0x64 28 | // BLOCK f0 04 beq 0x008008 29 | // BLOCK c9 2a cmp #0x2a 30 | // BLOCK d0 f8 bne 0x008000 31 | LogicalAndOfNotTestLabel: 32 | goto LogicalAndOfNotTestLabel if 33 | a != 100 34 | && a != 42; 35 | 36 | // BLOCK 000008 c9 64 cmp #0x64 37 | // BLOCK f0 04 beq 0x008008 38 | // BLOCK c9 2a cmp #0x2a 39 | // BLOCK d0 f8 bne 0x008008 40 | LogicalNotOfOrTestLabel: 41 | goto LogicalNotOfOrTestLabel if 42 | !(a == 100 43 | || a == 42); 44 | 45 | // BLOCK 000010 60 rts 46 | } 47 | 48 | // BLOCK ff 49 | } -------------------------------------------------------------------------------- /tests/block/6502_goto_or2.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_goto_and2.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | in prg { 16 | 17 | func goto_or2_test { 18 | 19 | // BLOCK 000000 c9 64 cmp #0x64 20 | // BLOCK f0 fc beq 0x008000 21 | // BLOCK c9 2a cmp #0x2a 22 | // BLOCK f0 f8 beq 0x008000 23 | LogicalOrTestLabel: 24 | goto LogicalOrTestLabel if 25 | a == 100 26 | || a == 42; 27 | 28 | // BLOCK 000008 60 rts 29 | } 30 | 31 | // BLOCK ff 32 | } -------------------------------------------------------------------------------- /tests/block/6502_goto_or3.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_goto_and2.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | in prg { 16 | 17 | func goto_or3_test { 18 | 19 | // BLOCK 000000 c9 64 cmp #0x64 20 | // BLOCK f0 fc beq 0x008000 21 | // BLOCK c9 2a cmp #0x2a 22 | // BLOCK f0 f8 beq 0x008000 23 | // BLOCK c9 1f cmp #0x1f 24 | // BLOCK f0 f4 beq 0x008000 25 | LogicalOrTestLabel: 26 | goto LogicalOrTestLabel if 27 | a == 100 28 | || a == 42 29 | || a == 31; 30 | 31 | // BLOCK 00000c 60 rts 32 | } 33 | 34 | // BLOCK ff 35 | } -------------------------------------------------------------------------------- /tests/block/6502_interrupts.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // 3 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 4 | // 5 | // Disassembly created using radare2 6 | // 7 | // `--> r2 -a6502 -m0x8000 6502_interrupts.6502.bin 8 | // [0x00008000]> e asm.bytespace=true 9 | // [0x00008000]> pd 10 | // 11 | 12 | import "_6502_memmap.wiz"; 13 | 14 | // BLOCK 000000 15 | in prg { 16 | 17 | #[nmi] 18 | func nmi_test { 19 | // BLOCK 40 rti 20 | return; 21 | 22 | // BLOCK ea nop 23 | nop(); 24 | 25 | // BLOCK 40 rti 26 | } 27 | 28 | 29 | 30 | #[irq] 31 | func irq_test { 32 | // BLOCK 40 rti 33 | return; 34 | 35 | // BLOCK ea nop 36 | nop(); 37 | 38 | // BLOCK 40 rti 39 | } 40 | 41 | 42 | 43 | func irqcall_test { 44 | // BLOCK 00 42 brk #42 45 | irqcall(0x42); 46 | 47 | // BLOCK 60 rts 48 | } 49 | 50 | 51 | 52 | func rti_test { 53 | // BLOCK 40 rti 54 | // BLOCK 40 rti 55 | irqreturn; 56 | nmireturn; 57 | 58 | // BLOCK ea nop 59 | nop(); 60 | 61 | // BLOCK 60 rts 62 | } 63 | 64 | // BLOCK ff 65 | } 66 | 67 | -------------------------------------------------------------------------------- /tests/block/6502_push_pop.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 2 | // ::TODO other systems:: 3 | // 4 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 5 | // 6 | // Disassembly created using radare2 7 | // 8 | // `--> r2 -a6502 -m0x8000 6502_push_pop.6502.bin 9 | // [0x00008000]> e asm.bytespace=true 10 | // [0x00008000]> pd 11 | // 12 | 13 | import "_6502_memmap.wiz"; 14 | 15 | // BLOCK 0x000000 16 | in prg { 17 | 18 | func push_pop { 19 | // BLOCK 08 php 20 | // BLOCK 48 pha 21 | push(p); 22 | push(a); 23 | 24 | // BLOCK 68 pla 25 | // BLOCK 28 plp 26 | a = pop(); 27 | p = pop(); 28 | 29 | // BLOCK 60 rts 30 | } 31 | 32 | // BLOCK ff 33 | } 34 | 35 | -------------------------------------------------------------------------------- /tests/block/6502_return_if.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 wdc65816 2 | // 3 | // Disassembly created using radare2 4 | // 5 | // `--> r2 -a6502 -m0x8000 6502_return_if.6502.bin 6 | // [0x00008000]> e asm.bytespace=true 7 | // [0x00008000]> pd 8 | // 9 | 10 | import "_6502_memmap.wiz"; 11 | 12 | // BLOCK 000000 13 | in prg { 14 | 15 | func return_if_test { 16 | // BLOCK 000000 d0 01 bne 0x008003 17 | // BLOCK 60 rts 18 | return if zero; 19 | // BLOCK 000003 f0 01 beq 0x008006 20 | // BLOCK 60 rts 21 | return if !zero; 22 | // BLOCK 000006 90 01 bcc 0x008009 23 | // BLOCK 60 rts 24 | return if carry; 25 | // BLOCK 000009 b0 01 bcs 0x00800C 26 | // BLOCK 60 rts 27 | return if !carry; 28 | // BLOCK 00000C 10 01 bpl 0x00800F 29 | // BLOCK 60 rts 30 | return if negative; 31 | // BLOCK 00000F 30 01 bmi 0x008012 32 | // BLOCK 60 rts 33 | return if !negative; 34 | // BLOCK 000012 50 01 bvc 0x008015 35 | // BLOCK 60 rts 36 | return if overflow; 37 | // BLOCK 000015 70 01 bvs 0x008018 38 | // BLOCK 60 rts 39 | return if !overflow; 40 | // BLOCK 000018 ea nop 41 | nop(); 42 | // BLOCK 60 rts 43 | } 44 | 45 | // BLOCK ff 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /tests/block/6502_return_on_if_else_path.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | // 4 | // Disassembly created using radare2 5 | // 6 | // `--> r2 -a6502 -m0x8000 6502_return_on_if_else_path.6502.bin 7 | // [0x00008000]> e asm.bytespace=true 8 | // [0x00008000]> pd 9 | // 10 | 11 | import "_6502_memmap.wiz"; 12 | 13 | // BLOCK 000000 14 | in prg { 15 | 16 | func test_return_on_if_else_path(arg : u8 in a, index1 : u8 in x, index2 : u8 in y) : u8 in a { 17 | // BLOCK c9 80 cmp #0x80 18 | // BLOCK b0 04 bcs 0x008008 19 | // BLOCK bd 06 02 lda 0x0206,x 20 | // BLOCK 60 rts 21 | // BLOCK b9 06 02 lda 0x0206,y 22 | // BLOCK 60 rts 23 | if arg < 0x80 { 24 | return ram_block_206[x]; 25 | } 26 | else { 27 | return ram_block_206[y]; 28 | } 29 | } 30 | 31 | // BLOCK ff 32 | } 33 | 34 | -------------------------------------------------------------------------------- /tests/block/65c02_func_inline.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 65c02 wdc65c02 rockwell65c02 huc6280 2 | // 3 | // NOTE: does not use zero-page instructions so huc6280 can be tested 4 | // 5 | // Disassembly created using radare2 6 | // 7 | // `--> r2 -asnes -m0x8000 65c02_func_inline.65c02.bin 8 | // [0x00008000]> e asm.bytespace=true 9 | // [0x00008000]> pd 10 | // 11 | 12 | import "_6502_memmap.wiz"; 13 | 14 | in prg { 15 | 16 | // ANNOY radare2 does not have a 65c02 disassembler 17 | // the following line forces the radare2 65816 disassembler to use 8 bit A/X. 18 | const mem8idx8 : [u8] = [0xe2, 0x30]; 19 | 20 | 21 | // BLOCK 000002 ae 00 02 ldx 0x0200 22 | // BLOCK e0 2a cpx #0x2a 23 | // BLOCK b0 03 bcs 0x00800c 24 | // BLOCK e8 inx 25 | // BLOCK 80 01 bra 0x00800d 26 | // BLOCK 00000c ca dex 27 | // BLOCK 00000d ea nop 28 | // BLOCK 60 rts 29 | inline func inline_return(x : u8 in x) { 30 | if x < 42 { 31 | x++; 32 | return; 33 | } 34 | x--; 35 | } 36 | func inline_return_call() { 37 | inline_return(ram_u8_200); 38 | 39 | nop(); 40 | } 41 | 42 | 43 | 44 | // BLOCK 00000f ad 01 02 lda 0x0201 45 | // BLOCK 18 clc 46 | // BLOCK 69 0f adc #0x0f 47 | // BLOCK 18 clc 48 | // BLOCK 7d 06 02 adc 0x0206,x 49 | // BLOCK 18 clc 50 | // BLOCK 69 0f adc #0x0f 51 | // BLOCK 60 rts 52 | inline func inline_func1(a : u8 in a, x : u8 in x) : u8 in a { 53 | return a + ram_block_206[x]; 54 | } 55 | inline func inline_func2(a : u8 in a) : u8 in a { 56 | return a + 15; 57 | } 58 | func call_inline_func() { 59 | a = ram_u8_201; 60 | a = inline_func2(a); 61 | a = inline_func1(a, x); 62 | a = inline_func2(a); 63 | } 64 | 65 | // BLOCK ff 66 | } 67 | 68 | -------------------------------------------------------------------------------- /tests/block/65c02_push_pop.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 65c02 wdc65c02 rockwell65c02 huc6280 2 | // 3 | // Opcodes tested from site: http://6502.org/tutorials/6502opcodes.html 4 | // 5 | // Disassembly created using radare2 6 | // 7 | // `--> r2 -asnes -m0x8000 6502_push_pop.6502.bin 8 | // [0x00008000]> e asm.bytespace=true 9 | // [0x00008000]> pd 10 | // 11 | 12 | import "_6502_memmap.wiz"; 13 | 14 | // BLOCK 0x000000 15 | in prg { 16 | 17 | func push_pop { 18 | // BLOCK 08 php 19 | // BLOCK 48 pha 20 | // BLOCK da phx 21 | // BLOCK 5a phy 22 | push(p); 23 | push(a); 24 | push(x); 25 | push(y); 26 | 27 | // BLOCK 7a ply 28 | // BLOCK fa plx 29 | // BLOCK 68 pla 30 | // BLOCK 28 plp 31 | y = pop(); 32 | x = pop(); 33 | a = pop(); 34 | p = pop(); 35 | 36 | // BLOCK 60 rts 37 | } 38 | 39 | // BLOCK ff 40 | } 41 | 42 | -------------------------------------------------------------------------------- /tests/block/_6502_memmap.wiz: -------------------------------------------------------------------------------- 1 | 2 | #[compile_if(__has("__cpu_huc6280"))] let __ZP = 0x2000; 3 | #[compile_if(!__has("__cpu_huc6280"))] let __ZP = 0x00; 4 | 5 | bank zeropage @ __ZP : [vardata; 0x100]; 6 | bank stack @ 0x100 : [vardata; 0x100]; 7 | bank ram @ 0x200 : [vardata; 0x600]; 8 | bank prg @ 0x8000 : [constdata; 0x8000]; 9 | 10 | in zeropage { 11 | var zp_u8_00 : u8; // address 0x00 12 | var zp_u8_01 : u8; // address 0x00 13 | var zp_u16_02 : u16; // address 0x02 14 | var zp_ptr_04 : *u8; // address 0x04 15 | var zp_ptr_u16_06 : *u16; // address 0x06 (pointer to a u16) 16 | 17 | var zp_block_08 : [u8 ; 8]; // address 0x08-0x0f 18 | var zp_wblock_10 : [u16 ; 8]; // address 0x10-0x1f 19 | 20 | var zp_array_ptr_20 : [*u8 ; 2]; // address 0x20 - 0x24 21 | } 22 | 23 | in ram { 24 | var ram_u8_200 : u8; // address 0x200 25 | var ram_u8_201 : u8; // address 0x201 26 | var ram_u16_202 : u16; // address 0x202 27 | var ram_u16_204 : u16; // address 0x204 28 | 29 | var ram_block_206 : [u8 ; 10]; // addresses 0x206 - 0x20f 30 | var ram_wblock_210 : [u16 ; 8]; // addresses 0x210 - 0x21f 31 | 32 | var ram_func_ptr_220: func; 33 | } 34 | 35 | extern writeonly wo_register @ 0xf000 : u8; 36 | extern const ro_register @ 0xf001 : u8; 37 | 38 | -------------------------------------------------------------------------------- /tests/block/_gb_memmap.wiz: -------------------------------------------------------------------------------- 1 | bank prg @ 0x0000 : [constdata; 0x8000]; 2 | bank ram @ 0xC000 : [vardata; 0x1000]; 3 | bank stack @ 0xD000 : [vardata; 0x1000]; 4 | bank hram @ 0xFF80 : [vardata; 0x7F]; 5 | 6 | in ram { 7 | var ram_u8_C000 : u8; // address 0xC000 8 | var ram_u8_C001 : u8; // address 0xC001 9 | var ram_u16_C002 : u16; // address 0xC002 10 | var ram_u16_C004 : u16; // address 0xC004 11 | 12 | var ram_block_C006 : [u8 ; 10]; // addresses 0xC006 - 0xC00f 13 | var ram_wblock_C010 : [u16 ; 8]; // addresses 0xC010 - 0xC01f 14 | 15 | var ram_func_ptr_C020: func; 16 | } 17 | 18 | in hram { 19 | var hram_u8_ff80 : u8; // address 0xFF80 20 | } 21 | 22 | extern writeonly wo_register @ 0xff00 : u8; 23 | extern const ro_register @ 0xff01 : u8; 24 | 25 | -------------------------------------------------------------------------------- /tests/block/_z80_memmap.wiz: -------------------------------------------------------------------------------- 1 | bank prg @ 0x0000 : [constdata; 0x8000]; 2 | bank ram @ 0xC000 : [vardata; 0x1000]; 3 | bank stack @ 0xD000 : [vardata; 0x1000]; 4 | 5 | in ram { 6 | var ram_u8_C000 : u8; // address 0xC000 7 | var ram_u8_C001 : u8; // address 0xC001 8 | var ram_u16_C002 : u16; // address 0xC002 9 | var ram_u16_C004 : u16; // address 0xC004 10 | 11 | var ram_block_C006 : [u8 ; 10]; // addresses 0xC006 - 0xC00f 12 | var ram_wblock_C010 : [u16 ; 8]; // addresses 0xC010 - 0xC01f 13 | 14 | var ram_func_ptr_C020: func; 15 | } 16 | 17 | extern writeonly wo_register @ 0xf000 : u8; 18 | extern const ro_register @ 0xf001 : u8; 19 | 20 | -------------------------------------------------------------------------------- /tests/block/gb_load_highpage.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM gb 2 | // 3 | // Disassembly created using radare2 4 | // 5 | // `--> r2 -agb -m0x0000 gb_highpage_load.gb.bin 6 | // [0x00008000]> e asm.bytespace=true 7 | // [0x00008000]> pd 8 | // 9 | 10 | import "_gb_memmap.wiz"; 11 | 12 | // BLOCK 000000 13 | in prg { 14 | 15 | func load_highpage_test { 16 | // BLOCK f2 ld a, (ff00+c) 17 | a = (0xFF00 as *u8)[c]; 18 | // BLOCK e2 ld (ff00+c), a 19 | (0xFF00 as *u8)[c] = a; 20 | // BLOCK f0 01 ld a, (ff00+01) 21 | a = ro_register; 22 | // BLOCK e0 00 ld (ff00+01), a 23 | wo_register = a; 24 | // BLOCK f0 80 ld a, (ff00+80) 25 | a = hram_u8_ff80; 26 | // BLOCK e0 80 ld (ff00+80), a 27 | hram_u8_ff80 = a; 28 | // BLOCK c9 ret 29 | } 30 | 31 | // BLOCK ff 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /tests/block/spc700_16_bit.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank zeropage @ 0x000 : [vardata; 0x100]; 6 | bank code @ 0x200 : [constdata; 0x100]; 7 | 8 | in zeropage { 9 | var _padding1 : [u8; 0x80]; 10 | 11 | var zp_u16_80 : u16; // address = 0x80 12 | } 13 | 14 | 15 | // BLOCK 0000 16 | in code { 17 | 18 | 19 | func test() { 20 | // BLOCK DA 80 stw $80 21 | zp_u16_80 = ya; 22 | 23 | // BLOCK BA 80 ldw $80 24 | ya = zp_u16_80; 25 | 26 | // BLOCK 3A 80 inw $80 27 | // BLOCK 3A 80 inw $80 28 | zp_u16_80++; 29 | ++zp_u16_80; 30 | 31 | // BLOCK 1A 80 dew $80 32 | // BLOCK 1A 80 dew $80 33 | zp_u16_80--; 34 | --zp_u16_80; 35 | 36 | // BLOCK 7A 80 adw $80 37 | ya += zp_u16_80; 38 | 39 | // BLOCK 9A 80 sbw $80 40 | ya -= zp_u16_80; 41 | 42 | // BLOCK 5A 80 cpw $80 43 | cmp(ya, zp_u16_80); 44 | 45 | // BLOCK 6F rts 46 | } 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/block/spc700_cbne_dbnz.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | 6 | bank zeropage @ 0x000 : [vardata; 0x100]; 7 | bank padding @ 0x000 : [constdata; 0x200]; 8 | bank code @ 0x200 : [constdata; 0x100]; 9 | 10 | 11 | in zeropage { 12 | var _padding : [u8; 0x40]; 13 | 14 | var zp_u8_40 : u8; // address = 0x40 15 | var zp_array_41 : [u8; 5]; // address = 0x41 16 | } 17 | 18 | 19 | in code { 20 | 21 | func test() { 22 | 23 | // BLOCK 0200 C4 40 sta $40 24 | // BLOCK 0202 2E 40 01 cbne $40,$0206 25 | // BLOCK 0205 00 nop 26 | zp_u8_40 = a; 27 | if a == zp_u8_40 { 28 | nop(); 29 | } 30 | 31 | 32 | // BLOCK 0206 00 nop 33 | // BLOCK 0207 2E 40 FC cbne $40,$0206 34 | do { 35 | nop(); 36 | } while a != zp_u8_40; 37 | 38 | 39 | // BLOCK 020A D4 41 sta $41,x 40 | // BLOCK 020C DE 41 01 cbne $41,x, $0210 41 | // BLOCK 020F 00 nop 42 | zp_array_41[x] = a; 43 | if a == zp_array_41[x] { 44 | nop(); 45 | } 46 | 47 | 48 | // BLOCK 0210 00 nop 49 | // BLOCK 0211 DE 41 FC cbne $41,x, $0210 50 | do { 51 | nop(); 52 | } while a != zp_array_41[x]; 53 | 54 | 55 | // BLOCK 0214 8D 01 ldy #$01 56 | // BLOCK 0216 FE 01 dbnz y,$0219 57 | // BLOCK 0218 00 nop 58 | y = 1; 59 | if --y == 0 { 60 | nop(); 61 | } 62 | 63 | 64 | // BLOCK 0219 8D 01 ldy #$01 65 | // BLOCK 021B FE FC dbnz y,$0219 66 | do { 67 | y = 1; 68 | } while --y != 0; 69 | 70 | 71 | // BLOCK 021D 8F 01 40 mov $40,#$01 72 | // BLOCK 0220 6E 40 01 dbnz $40,$0224 73 | // BLOCK 0223 00 nop 74 | zp_u8_40 = 1; 75 | if --zp_u8_40 == 0 { 76 | nop(); 77 | } 78 | 79 | 80 | // BLOCK 0224 8F 01 40 mov $40,#$01 81 | // BLOCK 0227 6E 40 FA dbnz $40,$0224 82 | do { 83 | zp_u8_40 = 1; 84 | } while --zp_u8_40 != 0; 85 | 86 | 87 | // BLOCK 022A 6F rts 88 | } 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /tests/block/spc700_divmod.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | 8 | // BLOCK 0000 9 | in code { 10 | 11 | func test() { 12 | 13 | // BLOCK 9E div ya,x 14 | divmod(ya, x); 15 | 16 | // BLOCK 6F rts 17 | } 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/block/spc700_dp_imm.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank zeropage @ 0x00 : [vardata; 0x100]; 6 | bank code @ 0x200 : [constdata; 0x100]; 7 | 8 | 9 | in zeropage { 10 | var _padding : [u8; 0x24]; 11 | 12 | var zp_u8_24 : u8; // address 0x24 13 | } 14 | 15 | 16 | // BLOCK 0000 17 | in code { 18 | 19 | func test() { 20 | // BLOCK 8F 01 24 mov $24,#$01 21 | zp_u8_24 = 1; 22 | 23 | // BLOCK 60 clc 24 | // BLOCK 98 02 24 adc $24,#$02 25 | zp_u8_24 += 2; 26 | 27 | // BLOCK 98 03 24 adc $24,#$03 28 | zp_u8_24 +#= 3; 29 | 30 | // BLOCK 80 sec 31 | // BLOCK B8 04 24 sbc $24,#$04 32 | zp_u8_24 -= 4; 33 | 34 | // BLOCK B8 05 24 sbc $24,#$05 35 | zp_u8_24 -#= 5; 36 | 37 | // BLOCK 38 06 24 and $24,#$06 38 | zp_u8_24 &= 6; 39 | 40 | // BLOCK 18 07 24 or $24,#$07 41 | zp_u8_24 |= 7; 42 | 43 | // BLOCK 58 08 24 eor $24,#$08 44 | zp_u8_24 ^= 8; 45 | 46 | // BLOCK 78 09 24 cmp $24,#$09 47 | cmp(zp_u8_24, 9); 48 | 49 | // BLOCK 78 0A 24 cmp $24,#$0a 50 | // BLOCK D0 01 bne $0223 51 | // BLOCK 00 nop 52 | if zp_u8_24 == 10 { 53 | nop(); 54 | } 55 | 56 | // BLOCK 78 0B 24 cmp $24,#$0b 57 | // BLOCK F0 01 beq $0229 58 | // BLOCK 00 nop 59 | if zp_u8_24 != 11 { 60 | nop(); 61 | } 62 | 63 | // BLOCK 78 0C 24 cmp $24,#$0c 64 | // BLOCK B0 01 bcs $022f 65 | // BLOCK 00 nop 66 | if zp_u8_24 < 12 { 67 | nop(); 68 | } 69 | 70 | // BLOCK 78 0D 24 cmp $24,#$0d 71 | // BLOCK 90 01 bcc $0235 72 | // BLOCK 00 nop 73 | if zp_u8_24 >= 13 { 74 | nop(); 75 | } 76 | 77 | // BLOCK 6F rts 78 | } 79 | 80 | } 81 | 82 | -------------------------------------------------------------------------------- /tests/block/spc700_indirect_x_y.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | 8 | // BLOCK 0000 9 | in code { 10 | 11 | func test() { 12 | 13 | // BLOCK 60 clc 14 | // BLOCK 99 adc (x),(y) 15 | *(x as *u8) += *(y as *u8); 16 | 17 | // BLOCK 99 adc (x),(y) 18 | *(x as *u8) +#= *(y as *u8); 19 | 20 | // BLOCK 80 sec 21 | // BLOCK B9 sbc (x),(y) 22 | *(x as *u8) -= *(y as *u8); 23 | 24 | // BLOCK B9 sbc (x),(y) 25 | *(x as *u8) -#= *(y as *u8); 26 | 27 | // BLOCK 39 and (x),(y) 28 | *(x as *u8) &= *(y as *u8); 29 | 30 | // BLOCK 19 or (x),(y) 31 | *(x as *u8) |= *(y as *u8); 32 | 33 | // BLOCK 59 eor (x),(y) 34 | *(x as *u8) ^= *(y as *u8); 35 | 36 | // BLOCK 79 cmp (x),(y) 37 | cmp(*(x as *u8), *(y as *u8)); 38 | 39 | // BLOCK 6F rts 40 | } 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /tests/block/spc700_jump_indirect.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly manually created 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | 8 | // BLOCK 0000 9 | in code { 10 | 11 | // BLOCK 04 02 12 | // BLOCK 04 02 13 | const func_table = [ 14 | test, 15 | test, 16 | ]; 17 | 18 | func test() { 19 | 20 | // BLOCK 1F 00 02 JMP [!abs+X] 21 | goto *((&func_table as u16 + x as u16) as *func); 22 | 23 | // BLOCK 1F 00 02 JMP [!abs+X] 24 | // BLOCK 1F 00 02 JMP [!abs+X] 25 | goto func_table[unaligned x]; 26 | ^goto func_table[unaligned x]; 27 | 28 | // BLOCK 1F 00 02 JMP [!abs+X] 29 | // BLOCK 1F 00 02 JMP [!abs+X] 30 | return func_table[unaligned x](); 31 | ^return func_table[unaligned x](); 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /tests/block/spc700_misc.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | 8 | // BLOCK 0000 9 | in code { 10 | 11 | func test() { 12 | // BLOCK DF daa a 13 | decimal_adjust_add(); 14 | 15 | // BLOCK BE das a 16 | decimal_adjust_sub(); 17 | 18 | // BLOCK 00 nop 19 | nop(); 20 | 21 | // BLOCK EF wai 22 | sleep(); 23 | 24 | // BLOCK FF stp 25 | stop(); 26 | 27 | // BLOCK 6F rts 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /tests/block/spc700_shift.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank zeropage @ 0x000 : [vardata; 0x100]; 6 | bank abs @ 0x100 : [vardata; 0x100]; 7 | bank code @ 0x200 : [constdata; 0x100]; 8 | 9 | in zeropage { 10 | var _padding1 : [u8; 0x40]; 11 | 12 | var zp_u8_40 : u8; // address = 0x40 13 | var zp_array_41 : [u8; 0x10]; // ... 14 | } 15 | 16 | in abs { 17 | var _padding2 : [u8; 0x50]; 18 | 19 | var abs_u8_150 : u8; 20 | } 21 | 22 | 23 | // BLOCK 0000 24 | in code { 25 | 26 | func test() { 27 | 28 | // BLOCK 1C asl a 29 | // BLOCK 1C asl a 30 | // BLOCK 1C asl a 31 | a <<= 3; 32 | 33 | // BLOCK 00 nop 34 | nop(); 35 | 36 | // BLOCK 1C asl a 37 | // BLOCK 0B 40 asl $40 38 | // BLOCK 1B 41 asl $41,x 39 | // BLOCK 0C 50 01 asl $0150 40 | a <<= 1; 41 | zp_u8_40 <<= 1; 42 | zp_array_41[x] <<= 1; 43 | abs_u8_150 <<= 1; 44 | 45 | // BLOCK 1C asl a 46 | // BLOCK 0B 40 asl $40 47 | // BLOCK 1B 41 asl $41,x 48 | // BLOCK 0C 50 01 asl $0150 49 | a <<<= 1; 50 | zp_u8_40 <<<= 1; 51 | zp_array_41[x] <<<= 1; 52 | abs_u8_150 <<<= 1; 53 | 54 | // BLOCK 5C lsr a 55 | // BLOCK 4B 40 lsr $40 56 | // BLOCK 5B 41 lsr $41,x 57 | // BLOCK 4C 50 01 lsr $0150 58 | a >>>= 1; 59 | zp_u8_40 >>>= 1; 60 | zp_array_41[x] >>>= 1; 61 | abs_u8_150 >>>= 1; 62 | 63 | // BLOCK 3C rol a 64 | // BLOCK 2B 40 rol $40 65 | // BLOCK 3B 41 rol $41,x 66 | // BLOCK 2C 50 01 rol $0150 67 | a <<<<#= 1; 68 | zp_u8_40 <<<<#= 1; 69 | zp_array_41[x] <<<<#= 1; 70 | abs_u8_150 <<<<#= 1; 71 | 72 | // BLOCK 7C ror a 73 | // BLOCK 6B 40 ror $40 74 | // BLOCK 7B 41 ror $41,x 75 | // BLOCK 6C 50 01 ror $0150 76 | a >>>>#= 1; 77 | zp_u8_40 >>>>#= 1; 78 | zp_array_41[x] >>>>#= 1; 79 | abs_u8_150 >>>>#= 1; 80 | 81 | // BLOCK 9F xcn a 82 | swap_digits(a); 83 | 84 | // BLOCK 6F rts 85 | } 86 | 87 | } 88 | 89 | -------------------------------------------------------------------------------- /tests/block/spc700_stack.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | 8 | // BLOCK 0000 9 | in code { 10 | 11 | func test() { 12 | 13 | // BLOCK 9D tsx 14 | x = sp; 15 | 16 | // BLOCK BD txs 17 | sp = x; 18 | 19 | // BLOCK 2D pha 20 | // BLOCK 4D phx 21 | // BLOCK 6D phy 22 | // BLOCK 0D php 23 | push(a); 24 | push(x); 25 | push(y); 26 | push(psw); 27 | 28 | // BLOCK AE pla 29 | // BLOCK CE plx 30 | // BLOCK EE ply 31 | // BLOCK 8E plp 32 | a = pop(); 33 | x = pop(); 34 | y = pop(); 35 | psw = pop(); 36 | 37 | // BLOCK 6F rts 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /tests/block/spc700_status_flags.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | 8 | // BLOCK 0000 9 | in code { 10 | 11 | 12 | func test() { 13 | // BLOCK 60 clc 14 | carry = false; 15 | 16 | // BLOCK 80 sec 17 | carry = true; 18 | 19 | // BLOCK ED notc 20 | carry = !carry; 21 | 22 | // BLOCK E0 clv 23 | overflow = false; 24 | 25 | // BLOCK 20 clp 26 | direct_page = false; 27 | 28 | // BLOCK 40 sep 29 | direct_page = true; 30 | 31 | // BLOCK C0 sei 32 | interrupt = false; 33 | 34 | // BLOCK A0 cli 35 | interrupt = true; 36 | 37 | // BLOCK 6F rts 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /tests/block/spc700_subroutines.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger and Mesen-S's SPC Debugger 4 | 5 | bank code @ 0x200 : [constdata; 0x100]; 6 | 7 | let func_ff20 = 0xff20 as func(); 8 | let func_ff40 = 0xff40 as func(); 9 | 10 | extern const func_table_ffc0 @ 0xffc0 : [func(); 16]; 11 | 12 | 13 | // BLOCK 0000 14 | in code { 15 | 16 | func test() { 17 | // BLOCK 2F FE bra $0200 18 | // BLOCK 2F FC bra $0200 19 | goto test; 20 | return test(); 21 | 22 | // BLOCK 5F 00 02 jmp $0200 23 | // BLOCK 5F 00 02 jmp $0200 24 | ^goto test; 25 | ^return test(); 26 | 27 | // BLOCK 3F 00 02 jsr $0200 28 | test(); 29 | 30 | // BLOCK 4F 20 jsp u 31 | // BLOCK 4F 40 jsp u 32 | func_ff20(); 33 | func_ff40(); 34 | 35 | // BLOCK F1 jstf 36 | // BLOCK 71 jst7 37 | // BLOCK 01 jst0 38 | func_table_ffc0[0](); 39 | func_table_ffc0[8](); 40 | func_table_ffc0[15](); 41 | 42 | // BLOCK 0F brk 43 | irqcall(); 44 | 45 | // BLOCK 6F rts 46 | } 47 | 48 | 49 | #[irq] 50 | func irq_handler() { 51 | // BLOCK 7F rti 52 | } 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /tests/block/spc700_tset1_tclr1.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM spc700 2 | // 3 | // Disassembly created using Mesen-S's Trace Logger 4 | 5 | bank abs @ 0x100 : [vardata; 0x100]; 6 | bank code @ 0x200 : [constdata; 0x100]; 7 | 8 | in abs { 9 | var abs_u8_100 : u8; // address = 0x100 10 | } 11 | 12 | 13 | // BLOCK 0000 14 | in code { 15 | 16 | func test() { 17 | // BLOCK 0E 00 01 set1 $0100 18 | test_and_set(a, abs_u8_100); 19 | 20 | // BLOCK 4E 00 01 clr1 $0100 21 | test_and_clear(a, abs_u8_100); 22 | 23 | // BLOCK 6F rts 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /tests/block/z80_func_call.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM z80 2 | 3 | import "_z80_memmap.wiz"; 4 | 5 | // BLOCK 000000 6 | in prg { 7 | 8 | func first_function() { 9 | // BLOCK c9 ret 10 | } 11 | 12 | func call_test { 13 | // BLOCK cd 00 00 call 0x0000 14 | first_function(); 15 | // BLOCK c4 00 00 call nz, 0x0000 16 | first_function() if !zero; 17 | // BLOCK cc 00 00 call z, 0x0000 18 | first_function() if zero; 19 | // BLOCK d4 00 00 call nc, 0x0000 20 | first_function() if !carry; 21 | // BLOCK dc 00 00 call c, 0x0000 22 | first_function() if carry; 23 | // BLOCK c9 ret 24 | } 25 | 26 | // BLOCK ff 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tests/block/z80_func_tail_call.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM z80 2 | 3 | import "_z80_memmap.wiz"; 4 | 5 | // BLOCK 000000 6 | in prg { 7 | 8 | func first_function() { 9 | // BLOCK c9 ret 10 | } 11 | 12 | func tailcall_test { 13 | // BLOCK 18 fd jr 0x0000 14 | return first_function(); 15 | // BLOCK 20 fb jr nz, 0x0000 16 | return first_function() if !zero; 17 | // BLOCK 28 f9 jr z, 0x0000 18 | return first_function() if zero; 19 | // BLOCK 30 f7 jr nc, 0x0000 20 | return first_function() if !carry; 21 | // BLOCK 38 f5 jr c, 0x0000 22 | return first_function() if carry; 23 | 24 | // BLOCK c3 00 00 jp 0x0000 25 | ^return first_function(); 26 | // BLOCK c2 00 00 jp nz, 0x0000 27 | ^return first_function() if !zero; 28 | // BLOCK ca 00 00 jp z, 0x0000 29 | ^return first_function() if zero; 30 | // BLOCK d2 00 00 jp nc, 0x0000 31 | ^return first_function() if !carry; 32 | // BLOCK da 00 00 jp c, 0x0000 33 | ^return first_function() if carry; 34 | // BLOCK c9 ret 35 | } 36 | 37 | // BLOCK ff 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /tests/block/z80_return_if.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM z80 2 | // 3 | // Disassembly created using radare2 4 | // 5 | // `--> r2 -az80 -m0x0000 z80_return_if.z80.bin 6 | // [0x00008000]> e asm.bytespace=true 7 | // [0x00008000]> pd 8 | // 9 | 10 | import "_z80_memmap.wiz"; 11 | 12 | // BLOCK 000000 13 | in prg { 14 | 15 | func return_if_test { 16 | // BLOCK c8 ret z 17 | return if zero; 18 | // BLOCK c0 ret nz 19 | return if !zero; 20 | // BLOCK d8 ret c 21 | return if carry; 22 | // BLOCK d0 ret nc 23 | return if !carry; 24 | // BLOCK f8 ret m 25 | return if negative; 26 | // BLOCK f0 ret p 27 | return if !negative; 28 | // BLOCK e8 ret pe 29 | return if overflow; 30 | // BLOCK e0 ret po 31 | return if !overflow; 32 | // BLOCK 00 nop 33 | nop(); 34 | // BLOCK c9 ret 35 | } 36 | 37 | // BLOCK ff 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /tests/failure/bank.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [vardata; 0x100]; 4 | bank stack @ -0x100 : [vardata; 0x100]; // ERROR 5 | bank ram @ 0x200 : [vardata; -0x100]; // ERROR 6 | bank prg @ MISSING : [constdata; 0x8000]; // ERROR 7 | bank rom1 @ 0x018000 : [constdata; 0x8000]; 8 | bank rom2 @ 0x028000 : [constdata; MISSING]; // ERROR 9 | 10 | -------------------------------------------------------------------------------- /tests/failure/duplicate_bank_name.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [vardata; 0x100]; // REFERENCE 4 | bank stack @ 0x100 : [vardata; 0x100]; 5 | bank ram @ 0x200 : [vardata; 0x600]; 6 | bank prg @ 0x8000 : [constdata; 0x8000]; 7 | bank rom1 @ 0x018000 : [constdata; 0x8000]; // REFERENCE 8 | bank rom2 @ 0x028000 : [constdata; 0x8000]; 9 | 10 | bank zeropage @ 0x00 : [vardata; 0x100]; // ERROR 11 | bank rom1 @ 0x8000 : [constdata; 0x8000]; // ERROR 12 | 13 | -------------------------------------------------------------------------------- /tests/failure/duplicate_func_args.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | #[compile_if(__has("__cpu_z80") || __has("__cpu_gb"))] let x = b; 6 | #[compile_if(__has("__cpu_z80") || __has("__cpu_gb"))] let y = c; 7 | 8 | in code { 9 | 10 | func f(arg0 : u8 in a, arg1 : u8 in x, arg2 : u8 in y) { } 11 | func g(arg0 : u8 in a, arg1 : u8 in x, dupe : u8 in a) { } // ERROR // REFERENCE 12 | func h(dupe : u8 in a, arg2 : u8 in x, dupe : u8 in y) { } // ERROR // REFERENCE 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/failure/duplicate_func_args_vars.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [vardata; 0x100]; 4 | bank code @ 0x8000 : [constdata; 0x8000]; 5 | 6 | in zeropage { 7 | var tmp1, tmp2, tmp3 : u8; 8 | } 9 | 10 | in code { 11 | 12 | func f(arg0 : u8 in tmp1, arg1 : u8 in tmp2, arg2 : u8 in tmp3) { } 13 | func g(arg0 : u8 in tmp1, arg1 : u8 in tmp2, dupe : u8 in tmp2) { } // ERROR // REFERENCE 14 | func h(dupe : u8 in tmp1, arg2 : u8 in tmp2, dupe : u8 in tmp3) { } // ERROR // REFERENCE 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/failure/duplicate_func_name.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | func fun0() { } 8 | func dupe() { } // REFERENCE 9 | func fun1() { } 10 | func dupe() { } // ERROR 11 | func fun2() { } 12 | 13 | } 14 | 15 | -------------------------------------------------------------------------------- /tests/failure/duplicate_func_name_namespace.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | func dupe() { } 8 | func fun0() { } 9 | func fun1() { } 10 | func fun2() { } 11 | 12 | namespace n { 13 | func fun0() { } 14 | func dupe() { } // REFERENCE 15 | func fun1() { } 16 | func dupe() { } // ERROR 17 | func fun2() { } 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/failure/duplicate_let_inline_for.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | func test() { 8 | inline for let dupe in 1 .. 3 { // REFERENCE 9 | let constant0 = 1; 10 | let dupe = 0; // ERROR 11 | let constant1 = 1; 12 | 13 | a = dupe; 14 | } 15 | } 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/failure/duplicate_let_name.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | let constant0 = 1; 4 | let dupe = 0; // REFERENCE 5 | let constant1 = 1; 6 | let dupe = 0; // ERROR 7 | let constant2 = 1; 8 | 9 | -------------------------------------------------------------------------------- /tests/failure/duplicate_let_name_namespace.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | let dupe = 0; 4 | let constant0 = 1; 5 | let constant1 = 1; 6 | let constant2 = 1; 7 | 8 | namespace n { 9 | let constant0 = 1; 10 | let dupe = 0; // REFERENCE 11 | let constant1 = 1; 12 | let dupe = 0; // ERROR 13 | let constant2 = 1; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/failure/duplicate_var_name.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [vardata; 0x100]; 4 | 5 | in zeropage { 6 | var var0 : u8; 7 | var dupe : u8; // REFERENCE 8 | var var1 : u8; 9 | var dupe : u16; // ERROR 10 | var var2 : u8; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/failure/duplicate_var_name_namespace.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [vardata; 0x100]; 4 | 5 | in zeropage { 6 | var dupe : u8; 7 | var var0 : u8; 8 | var var1 : u8; 9 | var var2 : u8; 10 | 11 | namespace n { 12 | var var0 : u8; 13 | var dupe : u8; // REFERENCE 14 | var var1 : u8; 15 | var dupe : u16; // ERROR 16 | var var2 : u8; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tests/failure/func_call_incompatible_assignment.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | bank zeropage @ 0x0000 : [vardata; 0x100]; 5 | 6 | in code { 7 | func call() : bool in carry { 8 | return true; 9 | } 10 | 11 | func caller() { 12 | a = call(); // ERROR 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/failure/func_call_wrong_order.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | #[compile_if(__has("__cpu_z80") || __has("__cpu_gb"))] let x = b; 8 | #[compile_if(__has("__cpu_z80") || __has("__cpu_gb"))] let y = c; 9 | 10 | 11 | func call(arg0 : u8 in a, arg1 : u8 in x, arg2 : u8 in y) { } 12 | 13 | func caller() { 14 | call(a, x, y); 15 | call(a, y, x); // ERROR 16 | call(x, y, a); // ERROR 17 | call(y, x, a); // ERROR 18 | call(x, a, y); // ERROR 19 | call(y, a, x); // ERROR 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /tests/failure/func_call_wrong_order_vars.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | bank zp @ 0x0000 : [constdata; 0x0010]; 5 | 6 | in zp { 7 | var zTmp0 : u8; 8 | var zTmp1 : u8; 9 | var zTmp2 : u8; 10 | } 11 | 12 | in code { 13 | 14 | func call(a1 : u8 in zTmp0, a2 : u8 in zTmp1, a3 : u8 in zTmp2) { } 15 | 16 | func caller() { 17 | call(zTmp0, zTmp1, zTmp2); 18 | call(zTmp0, zTmp2, zTmp1); // ERROR 19 | call(zTmp1, zTmp2, zTmp0); // ERROR 20 | call(zTmp2, zTmp1, zTmp0); // ERROR 21 | call(zTmp1, zTmp0, zTmp2); // ERROR 22 | call(zTmp2, zTmp0, zTmp1); // ERROR 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/failure/in_inside_func.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x0000 : [constdata; 0x100]; 4 | bank code @ 0x8000 : [constdata; 0x8000]; 5 | 6 | in code { 7 | 8 | // in statements are allowed inside in statements 9 | in zeropage { 10 | var var0 : u8; 11 | var var1 : u8; 12 | var var2 : u8; 13 | } 14 | 15 | func f() { 16 | in zeropage { // ERROR 17 | var var0 : u8; 18 | var var1 : u8; 19 | var var2 : u8; 20 | } 21 | a = var0; 22 | a = var1; 23 | a = var2; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /tests/failure/inline_for_not_iterable.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | func test() { 8 | inline for let i in 0 .. 4 { 9 | a = i; 10 | } 11 | 12 | inline for let i in 3 { // ERROR 13 | a = i; 14 | } 15 | 16 | inline for let i in [1, 3, 5, 7, 9] { 17 | a = i; 18 | } 19 | } 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/failure/inline_func_break.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | inline func inline_break() { 8 | break; // ERROR 9 | } 10 | 11 | func caller() { 12 | while true { 13 | inline_break(); 14 | } 15 | do { 16 | inline_break(); 17 | } while true; 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/failure/inline_func_continue.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | 7 | inline func inline_continue() { 8 | continue; // ERROR 9 | } 10 | 11 | func caller() { 12 | while true { 13 | inline_continue(); 14 | } 15 | do { 16 | inline_continue(); 17 | } while true; 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/failure/invalid_attributes.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | #[__INVALID__] // ERROR 6 | in code { 7 | 8 | #[__INVALID__] // ERROR 9 | func test() { 10 | #[__INVALID__] { // ERROR 11 | a = 0; 12 | } 13 | } 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /tests/failure/invalid_type.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [vardata; 0x100]; 4 | 5 | in zeropage { 6 | var var0 : bool; 7 | var var1 : u8; 8 | var var2 : u16; 9 | var var3 : u24; 10 | var var4 : u32; 11 | var var5 : u64; 12 | var inv0 : unknown_type; // ERROR 13 | var var6 : i8; 14 | var var7 : i16; 15 | var var8 : i24; 16 | var var9 : i32; 17 | var var10 : i64; 18 | var inv1 : unknown_type; // ERROR 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/failure/invalid_type_func.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { 6 | func valid_0(arg : u8 in a) { } 7 | func valid_1(arg : i8 in a) { } 8 | func valid_2(arg : bool in a) { } 9 | func invalid_0(arg : u16 in a) { } // ERROR 10 | func invalid_1(arg : u24 in a) { } // ERROR 11 | func invalid_2(arg : u32 in a) { } // ERROR 12 | func invalid_3(arg : u64 in a) { } // ERROR 13 | func invalid_4(arg : unknown_type in a) { } // ERROR 14 | func invalid_5(arg : i16 in a) { } // ERROR 15 | func invalid_6(arg : i24 in a) { } // ERROR 16 | func invalid_7(arg : i32 in a) { } // ERROR 17 | func invalid_8(arg : i64 in a) { } // ERROR 18 | func invalid_9(arg : iexpr in a) { } // ERROR 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/failure/invalid_type_iexpr.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | // Have to test this one in a separate test as wiz exits on a 4 | // `could not resolve identifier` error before displaying the 5 | // `type iexpr has unknown storage size` error. 6 | 7 | bank zeropage @ 0x00 : [vardata; 0x100]; 8 | 9 | in zeropage { 10 | var inv1 : iexpr; // ERROR 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/failure/missing_brace_0.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { // REFERENCE 6 | func f() { } 7 | 8 | // ERROR 9 | -------------------------------------------------------------------------------- /tests/failure/missing_brace_1.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { // REFERENCE 6 | func f() { // REFERENCE 7 | 8 | // ERROR 9 | -------------------------------------------------------------------------------- /tests/failure/missing_brace_2.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank code @ 0x8000 : [constdata; 0x8000]; 4 | 5 | in code { // REFERENCE 6 | func f() { 7 | 8 | func g() { 9 | } 10 | } 11 | 12 | // ERROR 13 | -------------------------------------------------------------------------------- /tests/failure/missing_brace_3.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | bank zeropage @ 0x00 : [constdata; 0x100]; 4 | bank code @ 0x8000 : [constdata; 0x8000]; 5 | 6 | in zeropage { // REFERENCE 7 | 8 | // in statements are allowed inside in statements 9 | in code { 10 | } 11 | 12 | // ERROR 13 | -------------------------------------------------------------------------------- /tests/failure/missing_brace_4.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM all 2 | 3 | namespace n { // REFERENCE 4 | namespace m { // REFERENCE 5 | 6 | // ERROR 7 | -------------------------------------------------------------------------------- /tests/failure/write_only_read_modify_write.wiz: -------------------------------------------------------------------------------- 1 | // SYSTEM 6502 65c02 wdc65c02 rockwell65c02 huc6280 2 | // ::TODO wdc65816:: 3 | 4 | // https://github.com/wiz-lang/wiz/issues/41 5 | 6 | bank code @ 0x8000 : [constdata; 0x8000]; 7 | 8 | extern writeonly wo_register @ 0x4300 : u8; 9 | 10 | in code { 11 | 12 | func broken() { 13 | wo_register = a << 1; // ERROR 14 | } 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/wiztests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TEST_DIR=$( dirname "${BASH_SOURCE[0]}" ) 4 | 5 | if [[ $(command -v python) ]]; then 6 | if [[ $(python --version) == "Python 3."* ]]; then 7 | python $TEST_DIR/wiztests.py $@ 8 | else 9 | if [[ $(command -v python3) ]]; then 10 | python3 $TEST_DIR/wiztests.py $@ 11 | else 12 | echo Incompatible Python interpreter. Please install a Python 3 interpreter that is version Python 3.6 or greater, and put it on your PATH. 13 | exit 1 14 | fi 15 | fi 16 | elif [[ $(command -v python) ]]; then 17 | python3 $TEST_DIR/wiztests.py $@ 18 | else 19 | echo No python installation was found. Please install a Python 3 interpreter that is version Python 3.6 or greater, and put it on your PATH. 20 | exit 1 21 | fi 22 | 23 | -------------------------------------------------------------------------------- /try-in-browser/build.bat: -------------------------------------------------------------------------------- 1 | copy ..\bin\wiz.js wiz.js 2 | pause -------------------------------------------------------------------------------- /try-in-browser/style.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | body { 7 | background: #F8F8F8; 8 | padding: 0; 9 | } 10 | 11 | .wiz-main-container { 12 | color: #000000; 13 | font-family: sans-serif; 14 | padding: 64px; 15 | } 16 | 17 | .wiz-main-container h1 { 18 | font-family: sans-serif; 19 | font-size: 48px; 20 | font-weight: bold; 21 | margin: 0; 22 | margin-bottom: 36px; 23 | text-align: left; 24 | } 25 | 26 | .wiz-source-file h2:hover { 27 | cursor: pointer; 28 | opacity: 0.3; 29 | } 30 | 31 | textarea.wiz-source-editor { 32 | font-family: monospace; 33 | font-size: 12px; 34 | display: block; 35 | border: 0; 36 | outline: none; 37 | resize: none; 38 | width: 100%; 39 | height: 400px; 40 | margin: 16px 0px; 41 | } 42 | 43 | .wiz-source-file.wiz-source-collapsed .wiz-source-editor { 44 | display: none; 45 | } 46 | 47 | .wiz-build-button { 48 | display: inline-block; 49 | background: #FFFFFF; 50 | border: 4px solid #CCCCFF; 51 | font-family: sans-serif; 52 | font-size: 32px; 53 | margin-top: 32px; 54 | margin-bottom: 32px; 55 | outline: none; 56 | resize: none; 57 | } 58 | 59 | .wiz-build-button:active { 60 | border: 4px solid #CCCCCC; 61 | } 62 | 63 | .wiz-build-report { 64 | font-family: monospace; 65 | font-size: 12px; 66 | white-space: pre; 67 | } 68 | 69 | .wiz-build-report .message { 70 | } 71 | 72 | .wiz-build-report .message.notice { 73 | font-weight: bold; 74 | } 75 | 76 | .wiz-build-report .message.note { 77 | color: #FF00FF; 78 | } 79 | 80 | .wiz-build-report .message.error { 81 | color: #FF0000; 82 | } 83 | 84 | .nes-canvas-wrapper-hidden { 85 | display: none; 86 | } -------------------------------------------------------------------------------- /vc/wiz.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 16 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wiz", "wiz.vcxproj", "{EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Optimized Debug|Win32 = Optimized Debug|Win32 13 | Optimized Debug|x64 = Optimized Debug|x64 14 | Release|Win32 = Release|Win32 15 | Release|x64 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Debug|Win32.Build.0 = Debug|Win32 20 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Debug|x64.ActiveCfg = Debug|x64 21 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Debug|x64.Build.0 = Debug|x64 22 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Optimized Debug|Win32.ActiveCfg = Optimized Debug|Win32 23 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Optimized Debug|Win32.Build.0 = Optimized Debug|Win32 24 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Optimized Debug|x64.ActiveCfg = Optimized Debug|x64 25 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Optimized Debug|x64.Build.0 = Optimized Debug|x64 26 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Release|Win32.ActiveCfg = Release|Win32 27 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Release|Win32.Build.0 = Release|Win32 28 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Release|x64.ActiveCfg = Release|x64 29 | {EB138DE3-5F23-4CC7-ABAE-E5813495A0AF}.Release|x64.Build.0 = Release|x64 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | --------------------------------------------------------------------------------