├── .clang-format
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENCE.txt
├── README.md
├── README.nfo
├── appveyor.yml
├── cd.c
├── cd.h
├── cli
├── etripator.c
├── options.c
└── options.h
├── cmake
└── FindJansson.cmake
├── comment.c
├── comment.h
├── comment
├── load.c
└── save.c
├── config.h
├── decode.c
├── decode.h
├── doxyfile.in
├── examples
├── maerchen_maze
│ ├── gfx_unpack.json
│ └── labels.json
├── monster_puroresu
│ ├── README.md
│ ├── labels.json
│ └── monster.json
├── sf2
│ ├── joypad.json
│ └── labels.json
├── syscard
│ ├── bank0.asm
│ ├── bank0.json
│ ├── labels.json
│ └── syscard.inc
├── tadaima
│ ├── README.md
│ ├── labels.json
│ └── mb128.json
└── youkai_douchuuki
│ ├── comments.json
│ ├── labels.json
│ ├── password.c
│ └── password.json
├── externals
└── CMakeLists.txt
├── ipl.c
├── ipl.h
├── irq.c
├── irq.h
├── jsonhelpers.c
├── jsonhelpers.h
├── label.c
├── label.h
├── label
├── load.c
└── save.c
├── logo.png
├── memory.c
├── memory.h
├── memory_map.c
├── memory_map.h
├── message.c
├── message.h
├── message
├── console.c
├── console.h
├── file.c
└── file.h
├── opcodes.c
├── opcodes.h
├── rom.c
├── rom.h
├── section.c
├── section.h
├── section
├── load.c
└── save.c
└── test
├── CMakeLists.txt
├── cd.c
├── comment.c
├── data
├── bank0_0.json
├── bank0_1.json
├── comment_0.json
├── comment_1.json
├── label_0.json
└── label_1.json
├── ipl.c
├── label.c
├── memory.c
├── memory_map.c
├── message.c
├── opcodes.c
├── rom.c
└── section.c
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | ColumnLimit: '120'
3 | IndentWidth: '4'
4 | TabWidth: '4'
5 | UseTab: Never
6 |
7 | ...
8 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: CMake
2 |
3 | on: [push]
4 |
5 | env:
6 | BUILD_TYPE: Release
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v4
14 | with:
15 | submodules: 'recursive'
16 |
17 | - name: Setup Dependencies
18 | run: |
19 | sudo apt install -y -qq libjansson-dev
20 |
21 | - name: Configure
22 | shell: bash
23 | working-directory: ${{github.workspace}}
24 | run: cmake -Bbuild -S . -DCMAKE_BUILD_TYPE=$BUILD_TYPE
25 |
26 | - name: Build
27 | working-directory: ${{github.workspace}}
28 | shell: bash
29 | run: cmake --build ./build --config $BUILD_TYPE
30 |
31 | - name: Test
32 | working-directory: ${{github.workspace}}
33 | shell: bash
34 | run: cmake --build ./build --target test
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.o
3 | *.obj
4 | ijunk
5 | .svn
6 | build
7 | *.ncb
8 | *.suo
9 | *.user
10 | ipch
11 | *.sdf
12 | *.opensdf
13 | .DS_Store
14 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "externals/argparse"]
2 | path = externals/argparse
3 | url = https://github.com/cofyc/argparse.git
4 | [submodule "externals/munit"]
5 | path = externals/munit
6 | url = https://github.com/nemequ/munit.git
7 | [submodule "externals/cwalk"]
8 | path = externals/cwalk
9 | url = https://github.com/likle/cwalk.git
10 | branch=v1.2.9
11 | [submodule "externals/fff"]
12 | path = externals/fff
13 | url = https://github.com/meekrosoft/fff.git
14 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 3.30)
2 |
3 | project(etripator
4 | VERSION 0.9.0
5 | LANGUAGES C)
6 |
7 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
8 | add_compile_definitions(_XOPEN_SOURCE=700)
9 | endif()
10 |
11 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
12 |
13 | enable_testing()
14 |
15 | include(CheckSymbolExists)
16 |
17 | check_symbol_exists(strdup "string.h" HAVE_STRDUP)
18 |
19 | if(NOT CMAKE_BUILD_TYPE)
20 | message(STATUS, "No build type specified. Force build type to Debug.")
21 | set(CMAKE_BUILD_TYPE "Debug")
22 | endif()
23 |
24 | find_package(Doxygen)
25 | find_package(Jansson)
26 |
27 | set(CMAKE_C_STANDARDS 11)
28 |
29 | add_subdirectory(externals EXCLUDE_FROM_ALL)
30 |
31 | set(etripator_SRC
32 | message.c
33 | message/file.c
34 | message/console.c
35 | jsonhelpers.c
36 | decode.c
37 | section.c
38 | section/load.c
39 | section/save.c
40 | opcodes.c
41 | comment.c
42 | comment/load.c
43 | comment/save.c
44 | label.c
45 | label/load.c
46 | label/save.c
47 | irq.c
48 | memory.c
49 | memory_map.c
50 | rom.c
51 | cd.c
52 | ipl.c
53 | )
54 |
55 | set(etripator_HDR
56 | config.h
57 | message.h
58 | message/file.h
59 | message/console.h
60 | jsonhelpers.h
61 | decode.h
62 | section.h
63 | opcodes.h
64 | comment.h
65 | label.h
66 | irq.h
67 | memory.h
68 | memory_map.h
69 | rom.h
70 | cd.h
71 | ipl.h
72 | )
73 |
74 | add_library(etripator STATIC ${etripator_SRC} ${etripator_HDR})
75 | set_target_properties(etripator PROPERTIES C_STANDARD 11)
76 | target_compile_definitions(etripator PRIVATE _POSIX_C_SOURCE)
77 | target_link_libraries(etripator PUBLIC jansson cwalk)
78 |
79 | add_executable(etripator_cli cli/etripator.c cli/options.c)
80 | set_target_properties(etripator_cli
81 | PROPERTIES
82 | OUTPUT_NAME etripator
83 | C_STANDARD 11
84 | )
85 | target_include_directories(etripator_cli PRIVATE ${CMAKE_SOURCE_DIR})
86 | target_include_directories(etripator_cli PUBLIC externals)
87 | target_link_libraries(etripator_cli etripator argparse)
88 |
89 | set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxyfile.in)
90 | set(DOXYFILE ${CMAKE_CURRENT_BINARY_DIR}/doxyfile)
91 |
92 | configure_file(${DOXYFILE_IN} ${DOXYFILE} @ONLY IMMEDIATE)
93 |
94 | add_custom_target(doc
95 | COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE}
96 | SOURCES ${DOXYFILE}
97 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
98 | COMMENT "Generating API documentation with Doxygen"
99 | VERBATIM
100 | )
101 |
102 | add_subdirectory(test)
103 |
104 | install(TARGETS etripator_cli DESTINATION bin)
105 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | os: Visual Studio 2017
2 | configuration: Release
3 | skip_tags: true
4 |
5 | environment:
6 | matrix:
7 | - compiler: msvc-15-seh
8 | build_system: cmake
9 | CMAKE_GENERATOR: Visual Studio 15 2017 Win64
10 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
11 | MSVC_PLATFORM: amd64
12 | BITS: 64
13 |
14 | - compiler: msvc-15-seh
15 | build_system: cmake
16 | CMAKE_GENERATOR: Visual Studio 15 2017
17 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
18 | MSVC_PLATFORM: x86
19 | BITS: 32
20 |
21 | install:
22 | - cd ..
23 | - ps: Invoke-WebRequest "https://github.com/akheron/jansson/archive/v2.12.zip" -OutFile "jansson.zip"
24 | - ps: Expand-Archive jansson.zip -DestinationPath .
25 | - cd jansson-2.12
26 | - md install
27 | - md build
28 | - cd build
29 | - cmake -DJANSSON_BUILD_DOCS=OFF -DJANSSON_WITHOUT_TESTS=ON -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX=../install ..
30 | - cmake --build . --config Release
31 | - cmake --build . --config Release --target install
32 | - cd ../../Etripator
33 | - git submodule update --init --recursive
34 |
35 | before_build:
36 | - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars%BITS%.bat"
37 | - mkdir install
38 | - mkdir build
39 | - cd build
40 | - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX=../install -DJANSSON_INCLUDE_DIR=../../jansson-2.12/install/include -DJANSSON_LIBRARY=../../jansson-2.12/install/lib/jansson.lib ..
41 |
42 | build_script:
43 | - cmake --build . --config Release
44 | - cmake --build . --config Release --target install
45 |
46 | after_build:
47 | - cd ../install
48 | - 7z a ../etripator.zip * -tzip
49 |
50 | artifacts:
51 | - path: etripator.zip
52 | name: etripator-v${appveyor_build_version}-%MSVC_PLATFORM%.zip
53 |
54 | deploy:
55 | release: etripator-v${appveyor_build_version}
56 | description: 'Etripator msvc15 %MSVC_PLATFORM% build'
57 | provider: GitHub
58 | auth_token:
59 | secure: 0Y6wz7NBuwl3+kPo4qFhU0Hh99m+8WWn3/wMk6NnbR284XTjG3Hg4BnnZont+24u
60 | artifact: /etripator.*\.zip/
61 | draft: false
62 | prerelease: false
63 | on:
64 | branch: master
65 | appveyor_repo_tag: true
66 |
67 |
--------------------------------------------------------------------------------
/cd.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "cd.h"
37 | #include "message.h"
38 |
39 | /// Adds CD RAM to memory map.
40 | bool cd_memory_map(MemoryMap *map) {
41 | int i;
42 | bool ret = false;
43 | // Allocate CD RAM
44 | if(!memory_create(&map->memory[PCE_MEMORY_CD_RAM], PCE_CD_RAM_BANK_COUNT * PCE_BANK_SIZE)) {
45 | ERROR_MSG("Failed to allocate cd memory!");
46 | // Allocate System Card RAM
47 | } else if (!memory_create(&map->memory[PCE_MEMORY_SYSCARD_RAM], PCE_SYSCARD_RAM_BANK_COUNT * PCE_BANK_SIZE)) {
48 | ERROR_MSG("Failed to allocate system card memory!");
49 | } else {
50 | // CD RAM is mapped to pages 0x80-0x88 (included).
51 | for (i = 0; i <= PCE_CD_RAM_BANK_COUNT; i++) {
52 | map->page[PCE_CD_RAM_FIRST_PAGE + i].id = PCE_MEMORY_CD_RAM;
53 | map->page[PCE_CD_RAM_FIRST_PAGE + i].bank = i;
54 | }
55 | // System Card RAM is mapped to pages 0x68-0x86.
56 | for (i = 0; i < PCE_SYSCARD_RAM_BANK_COUNT; i++) {
57 | map->page[PCE_SYSCARD_RAM_FIRST_PAGE + i].id = PCE_MEMORY_SYSCARD_RAM;
58 | map->page[PCE_SYSCARD_RAM_FIRST_PAGE + i].bank = i;
59 | }
60 | ret = true;
61 | }
62 |
63 | if(ret == false) {
64 | memory_map_destroy(map);
65 | }
66 | return ret;
67 | }
68 |
69 | /// Load CDROM data from file.
70 | bool cd_load(const char* filename, size_t start, size_t len, size_t sector_size, uint8_t page, size_t offset, MemoryMap* map) {
71 | bool ret = false;
72 | FILE *in = fopen(filename, "rb");
73 | if(in == NULL) {
74 | ERROR_MSG("Unable to open %s : %s", filename, strerror(errno));
75 | } else {
76 | size_t remaining = len;
77 | size_t physical = (offset & 0x1FFFU) | (page << 0x0D);
78 | for(ret=true; ret && remaining; ) {
79 | size_t count = 2048 - (start % 2048);
80 | if(count > remaining) {
81 | count = remaining;
82 | }
83 |
84 | size_t sector_id = start / 2048;
85 | size_t sector_offset = start % 2048;
86 |
87 | size_t file_offset = (sector_id * sector_size) + sector_offset;
88 |
89 | size_t current_page = physical >> 0x0D;
90 | size_t current_addr = physical & 0x1FFF;
91 |
92 | size_t bank_offset = current_addr + (map->page[current_page].bank * PCE_BANK_SIZE);
93 |
94 | // [todo] test that map->page[current_page].id != PCE_MEMORY_NONE
95 |
96 | ret = false;
97 | if(fseek(in, (long int)file_offset, SEEK_SET) < 0) {
98 | ERROR_MSG("Offset out of bound : %s", strerror(errno));
99 | } else if(fread(map->memory[map->page[current_page].id].data+bank_offset, 1, count, in) != count) {
100 | ERROR_MSG("Failed to read %d bytes : %s", count, strerror(errno));
101 | } else {
102 | ret = true;
103 | }
104 | start += count;
105 | physical += count;
106 | remaining -= count;
107 | }
108 |
109 | }
110 | if(in) {
111 | fclose(in);
112 | }
113 | return ret;
114 | }
115 |
--------------------------------------------------------------------------------
/cd.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_CD_H
37 | #define ETRIPATOR_CD_H
38 |
39 | #include "config.h"
40 | #include "memory_map.h"
41 |
42 | #define PCE_CD_RAM_BANK_COUNT 8U
43 | #define PCE_SYSCARD_RAM_BANK_COUNT 24U
44 |
45 | #define PCE_CD_RAM_FIRST_PAGE 0x80U
46 | #define PCE_SYSCARD_RAM_FIRST_PAGE 0x68U
47 |
48 | /// Adds CD RAM to memory map.
49 | /// \param map Memory map.
50 | /// \return true if the CD RAM and SYSCARD RAM memory areas were successfully created.
51 | /// \return false if an error occured.
52 | bool cd_memory_map(MemoryMap *map);
53 |
54 | /// Load CDROM data from file.
55 | /// \param [in] filename CDROM data filename.
56 | /// \param [in] start CDROM data offset.
57 | /// \param [in] len CDROM data length (in bytes).
58 | /// \param [in] sector_size CD sector size.
59 | /// \param [in] page Memory page.
60 | /// \param [in] offset Memory page offset.
61 | /// \param [out] map Memory map.
62 | /// \return true
63 | /// \return false
64 | bool cd_load(const char* filename, size_t start, size_t len, size_t sector_size, uint8_t page, size_t offset, MemoryMap* map);
65 |
66 | #endif // ETRIPATOR_CD_H
67 |
--------------------------------------------------------------------------------
/cli/options.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "options.h"
37 |
38 | #include
39 |
40 | #include
41 |
42 | struct payload_t {
43 | size_t capacity;
44 | size_t size;
45 | const char ***array;
46 | };
47 |
48 | static int opt_callback(struct argparse *self, const struct argparse_option *options) {
49 | struct payload_t *payload = (struct payload_t*)options->data;
50 | size_t last = payload->size++;
51 | if(payload->capacity <= payload->size) {
52 | payload->capacity += 4;
53 | const char **tmp = (const char**)realloc(*payload->array, payload->capacity*sizeof(const char*));
54 | if(tmp == NULL) {
55 | return 0;
56 | }
57 | memset(tmp+last, 0, 4*sizeof(const char*));
58 | *payload->array = tmp;
59 | }
60 | (*payload->array)[last] = *(char**)options->value;
61 | return 1;
62 | }
63 |
64 | // Extract command line options
65 | bool cli_opt_get(CommandLineOptions *options, int argc, const char** argv) {
66 | static const char *const usages[] = {
67 | "etripator [options] [--] ",
68 | NULL
69 | };
70 |
71 | bool ret = false;
72 |
73 | char *dummy;
74 | struct payload_t labels_payload = { 0, 0, &options->labels_in };
75 | struct payload_t comments_payload = {0, 0, &options->comments_in};
76 |
77 | struct argparse_option arg_opt[] = {
78 | OPT_HELP(),
79 | OPT_BOOLEAN('i', "irq-detect", &options->extract_irq, "automatically detect and extract irq vectors when disassembling a ROM, or extract opening code and gfx from CDROM IPL data", NULL, 0, 0),
80 | OPT_BOOLEAN('c', "cd", &options->cdrom, "cdrom image disassembly. Irq detection and rom. Header jump is not performed", NULL, 0, 0),
81 | OPT_STRING('o', "out", &options->main_filename, "main asm file containing includes for all sections as long the irq vector table if the irq-detect option is enabled", NULL, 0, 0),
82 | OPT_STRING('l', "labels", &dummy, "labels definition filename", opt_callback, (intptr_t)&labels_payload, 0),
83 | OPT_STRING(0, "labels-out", &options->labels_out, "extracted labels output filename. Otherwise the labels will be written to .YYMMDDhhmmss.lbl", NULL, 0, 0),
84 | OPT_STRING(0, "comments", &dummy, "comments description filename", opt_callback, (intptr_t)&comments_payload, 0),
85 | OPT_BOOLEAN(0, "address", &options->address, "print statement address as comment", NULL, 0, 0),
86 | OPT_INTEGER(0, "sector_size", &options->sector_size, "2352 bytes sectors (cd only)", NULL, 0, 0),
87 | OPT_END(),
88 | };
89 |
90 | struct argparse argparse;
91 |
92 | options->extract_irq = 0;
93 | options->cdrom = 0;
94 | options->cfg_filename = NULL;
95 | options->rom_filename = NULL;
96 | options->main_filename = "main.asm";
97 | options->labels_in = NULL;
98 | options->labels_out = NULL;
99 | options->comments_in = NULL;
100 | options->address = 0;
101 | options->sector_size = 2048;
102 |
103 | argparse_init(&argparse, arg_opt, usages, 0);
104 | argparse_describe(&argparse, "\nEtripator : a PC Engine disassembler", " ");
105 | argc = argparse_parse(&argparse, argc, argv);
106 | if(!argc) {
107 | // ...
108 | } else if((options->sector_size != 2048) && (options->sector_size != 2352)) {
109 | ERROR_MSG("invalid sector size (must be 2048 or 2352).");
110 | } else if(argc != 2) {
111 | if((options->extract_irq) && (argc == 1)) {
112 | /* Config file is optional with automatic irq vector extraction. */
113 | options->cfg_filename = NULL;
114 | options->rom_filename = argv[0];
115 | ret = true;
116 | }
117 | else {
118 | // ...
119 | }
120 | }
121 | else {
122 | options->cfg_filename = argv[0];
123 | options->rom_filename = argv[1];
124 | ret = true;
125 | }
126 |
127 | if(!ret) {
128 | argparse_usage(&argparse);
129 | }
130 |
131 | return ret;
132 | }
133 |
134 | // Release allocated resources during command line parsing
135 | void cli_opt_release(CommandLineOptions *options) {
136 | if(options->comments_in) {
137 | free(options->comments_in);
138 | }
139 | if(options->labels_in) {
140 | free(options->labels_in);
141 | }
142 | memset(options, 0, sizeof(CommandLineOptions));
143 | }
144 |
--------------------------------------------------------------------------------
/cli/options.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_OPTIONS_H
37 | #define ETRIPATOR_OPTIONS_H
38 |
39 | #include
40 |
41 | /* Command line options */
42 | typedef struct {
43 | int extract_irq;
44 | int cdrom;
45 | int sector_size;
46 | int address;
47 | const char *cfg_filename;
48 | const char *rom_filename;
49 | const char *main_filename;
50 | const char *labels_out;
51 | const char **labels_in;
52 | const char **comments_in;
53 | } CommandLineOptions;
54 |
55 | /// Extract command line options
56 | bool cli_opt_get(CommandLineOptions *options, int argc, const char** argv);
57 |
58 | /// Release allocated resources during command line parsing
59 | void cli_opt_release(CommandLineOptions *options);
60 |
61 | #endif // ETRIPATOR_OPTIONS_H
62 |
--------------------------------------------------------------------------------
/cmake/FindJansson.cmake:
--------------------------------------------------------------------------------
1 | # - Try to find Jansson
2 | # Once done this will define
3 | #
4 | # JANSSON_FOUND - system has Jansson
5 | # JANSSON_INCLUDE_DIRS - the Jansson include directory
6 | # JANSSON_LIBRARIES - Link these to use Jansson
7 | #
8 | # Copyright (c) 2011 Lee Hambley
9 | #
10 | # Redistribution and use is allowed according to the terms of the New
11 | # BSD license.
12 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
13 | #
14 |
15 | if (JANSSON_LIBRARIES AND JANSSON_INCLUDE_DIRS)
16 | # in cache already
17 | set(JANSSON_FOUND TRUE)
18 | else (JANSSON_LIBRARIES AND JANSSON_INCLUDE_DIRS)
19 | find_path(JANSSON_INCLUDE_DIR
20 | NAMES
21 | jansson.h
22 | PATHS
23 | /usr/include
24 | /usr/local/include
25 | /opt/local/include
26 | /sw/include
27 | )
28 |
29 | find_library(JANSSON_LIBRARY
30 | NAMES
31 | jansson
32 | PATHS
33 | /usr/lib
34 | /usr/local/lib
35 | /opt/local/lib
36 | /sw/lib
37 | )
38 |
39 | set(JANSSON_INCLUDE_DIRS
40 | ${JANSSON_INCLUDE_DIR}
41 | )
42 |
43 | if (JANSSON_LIBRARY)
44 | set(JANSSON_LIBRARIES
45 | ${JANSSON_LIBRARIES}
46 | ${JANSSON_LIBRARY}
47 | )
48 | endif (JANSSON_LIBRARY)
49 | endif (JANSSON_LIBRARIES AND JANSSON_INCLUDE_DIRS)
50 |
51 | include(FindPackageHandleStandardArgs)
52 | find_package_handle_standard_args(Jansson DEFAULT_MSG
53 | JANSSON_LIBRARIES JANSSON_INCLUDE_DIRS)
54 |
55 | if(JANSSON_FOUND)
56 | add_library(jansson UNKNOWN IMPORTED)
57 | set_target_properties(jansson
58 | PROPERTIES
59 | IMPORTED_LOCATION "${JANSSON_LIBRARIES}"
60 | INTERFACE_INCLUDE_DIRECTORIES "${JANSSON_INCLUDE_DIRS}"
61 | )
62 | endif()
63 |
64 | # show the JANSSON_INCLUDE_DIRS and JANSSON_LIBRARIES variables only in the advanced view
65 | mark_as_advanced(JANSSON_INCLUDE_DIRS JANSSON_LIBRARIES)
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/comment.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "comment.h"
37 | #include "message.h"
38 |
39 | #include
40 | #include "jsonhelpers.h"
41 |
42 | #define COMMENT_ARRAY_INC 16
43 |
44 | /// Get comment index by its address.
45 | /// \param [in] repository Coment repository.
46 | /// \param [in] logical Logical address.
47 | /// \param [in] page Memory page.
48 | /// \return comment index.
49 | /// \return -1 if the label was not found.
50 | static int comment_repository_index(CommentRepository* repository, uint16_t logical, uint8_t page) {
51 | size_t i;
52 | for(i=0; ilast; i++) {
53 | if( (repository->comments[i].page == page) &&
54 | (repository->comments[i].logical == logical) ) {
55 | return (int)i;
56 | }
57 | }
58 | return -1;
59 | }
60 |
61 | // Create comment repository.
62 | bool comment_repository_create(CommentRepository *repository) {
63 | assert(repository != NULL);
64 | bool ret = true;
65 |
66 | repository->last = 0;
67 | repository->comments = NULL;
68 |
69 | repository->size = COMMENT_ARRAY_INC;
70 | repository->comments = (Comment*)malloc(repository->size * sizeof(Comment));
71 | if(repository->comments == NULL) {
72 | ERROR_MSG("Failed to create comments: %s", strerror(errno));
73 | comment_repository_destroy(repository);
74 | ret = false;
75 | }
76 | return ret;
77 | }
78 |
79 | // Release comment repository resources.
80 | void comment_repository_destroy(CommentRepository* repository) {
81 | assert(repository != NULL);
82 |
83 | repository->size = 0;
84 | repository->last = 0;
85 |
86 | if(repository->comments != NULL) {
87 | for(size_t i=0; ilast; i++) {
88 | free(repository->comments[i].text);
89 | }
90 | free(repository->comments);
91 | repository->comments = NULL;
92 | }
93 | }
94 |
95 | // Add comment to repository.
96 | bool comment_repository_add(CommentRepository* repository, uint16_t logical, uint8_t page, const char *text) {
97 | assert(repository != NULL);
98 | assert(text != NULL);
99 |
100 | bool ret = true;
101 | int index = comment_repository_index(repository, logical, page);
102 | if(index >= 0) {
103 | WARNING_MSG("Duplicate comment for logical address $%04x in page $%02x", logical, page);
104 | } else {
105 | // Expand arrays if necessary.
106 | if(repository->last >= repository->size) {
107 | Comment *ptr;
108 | size_t new_size = repository->size + COMMENT_ARRAY_INC;
109 | ptr = (Comment*)realloc(repository->comments, new_size * sizeof(Comment));
110 | if(ptr == NULL) {
111 | ERROR_MSG("Failed to expand comment buffer: %s", strerror(errno));
112 | comment_repository_destroy(repository);
113 | ret = false;
114 | } else {
115 | repository->comments = ptr;
116 | repository->size = new_size;
117 | }
118 | }
119 | if(ret) {
120 | // Push addresses & text.
121 | repository->comments[repository->last].logical = logical;
122 | repository->comments[repository->last].page = page;
123 | repository->comments[repository->last].text = strdup(text);
124 |
125 | ++repository->last;
126 | }
127 | }
128 | return ret;
129 | }
130 |
131 | // Find a comment by its address.
132 | bool comment_repository_find(CommentRepository* repository, uint16_t logical, uint8_t page, Comment *out) {
133 | assert(repository != NULL);
134 | assert(out != NULL);
135 |
136 | int index = comment_repository_index(repository, logical, page);
137 | bool ret = (index >= 0);
138 | if(ret) {
139 | memcpy(out, &repository->comments[index], sizeof(Comment));
140 | } else {
141 | memset(out, 0, sizeof(Comment));
142 | }
143 | return ret;
144 | }
145 |
146 | // Get the number of comments stored in the repository.
147 | int comment_repository_size(CommentRepository* repository) {
148 | assert(repository != NULL);
149 | return (int)repository->last;
150 | }
151 |
152 | // Retrieve the comment at the specified index.
153 | bool comment_repository_get(CommentRepository* repository, int index, Comment *out) {
154 | assert(repository != NULL);
155 | assert(out != NULL);
156 |
157 | bool ret = false;
158 | if((index >= 0) && (index < (int)repository->last)) {
159 | memcpy(out, &repository->comments[index], sizeof(Comment));
160 | ret = true;
161 | } else {
162 | memset(out, 0, sizeof(Comment));
163 | }
164 | return ret;
165 | }
166 |
167 | // Delete comments.
168 | void comment_repository_delete(CommentRepository* repository, uint16_t first, uint16_t end, uint8_t page) {
169 | assert(repository != NULL);
170 |
171 | for(size_t i=0; ilast; i++) {
172 | if( (repository->comments[i].page == page) &&
173 | (repository->comments[i].logical >= first) &&
174 | (repository->comments[i].logical < end) ) {
175 | if(repository->last) {
176 | repository->last--;
177 | if(repository->comments[i].text) {
178 | free(repository->comments[i].text);
179 | }
180 | memcpy(&repository->comments[i], &repository->comments[repository->last], sizeof(Comment));
181 | i--;
182 | }
183 | }
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/comment.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_COMMENT_H
37 | #define ETRIPATOR_COMMENT_H
38 |
39 | #include "config.h"
40 |
41 | /// Comment.
42 | typedef struct {
43 | uint16_t logical; //< Logical address.
44 | uint8_t page; //< Memory page.
45 | char* text; //< Comment text.
46 | } Comment;
47 |
48 | /// Comment repository.
49 | typedef struct {
50 | size_t size; //< Size of comment repository.
51 | size_t last; //< Last element in the repository.
52 | Comment *comments; //< Comments.
53 | } CommentRepository;
54 |
55 | /// Create comment repository.
56 | /// \param [in out] repository Comment repository.
57 | /// \return true if the repository was succesfully initialized
58 | /// \return false if an error occured
59 | bool comment_repository_create(CommentRepository* repository);
60 |
61 | /// Release comment repository resources.
62 | /// \param [in,out] repository Comment repository.
63 | void comment_repository_destroy(CommentRepository* repository);
64 |
65 | /// Add comment to repository.
66 | /// \param [in,out] repository Comment repository.
67 | /// \param [in] logical Logical address.
68 | /// \param [in] page Memory page.
69 | /// \param [in] text Comment text.
70 | /// \return true if the comment was successfully added to the repository.
71 | /// \return false if an error occured.
72 | bool comment_repository_add(CommentRepository* repository, uint16_t logical, uint8_t page, const char *text);
73 |
74 | /// Find a comment by its address.
75 | /// \param [in] repository Comment repository.
76 | /// \param [in] logical Logical address.
77 | /// \param [in] page Memory page.
78 | /// \param [out] out Associated comment (if any).
79 | /// \return true if a comment was found.
80 | /// \return 0 otherwise.
81 | bool comment_repository_find(CommentRepository* repository, uint16_t logical, uint8_t page, Comment *out);
82 |
83 | /// Get the number of comments stored in the repository.
84 | /// \param [in] repository Comment repository.
85 | /// \return Comment count.
86 | int comment_repository_size(CommentRepository* repository);
87 |
88 | /// Retrieve the comment at the specified index.
89 | /// \param [in] repository Comment repository.
90 | /// \param [in] index Comment index.
91 | /// \param [out] out Comment (if any).
92 | /// \return true if a comment exists for the specified index.
93 | /// \return false otherwise.
94 | bool comment_repository_get(CommentRepository* repository, int index, Comment *out);
95 |
96 | /// Delete comments.
97 | /// \param [in] repository Comment repository.
98 | /// \param [in] first Start of the logical address range.
99 | /// \param [in] end End of the logical address range.
100 | /// \param [in] page Memory page.
101 | void comment_repository_delete(CommentRepository* repository, uint16_t first, uint16_t end, uint8_t page);
102 |
103 | /// Load comments from file.
104 | /// \param [in, out] repository Comment repository.
105 | /// \param [in] filename Input filename.
106 | /// \return true if the comments contained in the file was succesfully added to the repository.
107 | /// \return false if an error occured.
108 | bool comment_repository_load(CommentRepository* repository, const char* filename);
109 |
110 | /// Save comments to file.
111 | /// \param [in] repository Comment repository.
112 | /// \param [in] filename Output filename.
113 | /// \return true if the comments were succesfully saved.
114 | /// \return false if an error occured.
115 | bool comment_repository_save(CommentRepository* repository, const char* filename);
116 |
117 | #endif // ETRIPATOR_COMMENT_H
--------------------------------------------------------------------------------
/comment/load.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 | #include "../message.h"
38 | #include "../jsonhelpers.h"
39 | #include "../comment.h"
40 |
41 | // Load comments from file.
42 | bool comment_repository_load(CommentRepository* repository, const char* filename) {
43 | assert(filename != NULL);
44 | assert(repository != NULL);
45 |
46 | bool ret = false;
47 |
48 | json_t* root;
49 | json_error_t err;
50 | json_t* value;
51 | int index = 0;
52 | root = json_load_file(filename, 0, &err);
53 | if(!root) {
54 | ERROR_MSG("Failed to parse %s:%d:%d: %s", filename, err.line, err.column, err.text);
55 | } else {
56 | if(!json_is_array(root)) {
57 | ERROR_MSG("Array expected.");
58 | } else for (index = 0, ret = true; ret && (index < json_array_size(root)) && (value = json_array_get(root, index)); index++) {
59 | ret = false;
60 | if(!json_is_object(value)) {
61 | ERROR_MSG("Expected object.");
62 | } else {
63 | int num;
64 | // logical
65 | json_t *tmp = json_object_get(value, "logical");
66 | if(!json_validate_int(tmp, &num)) {
67 | ERROR_MSG("Invalid or missing logical address.");
68 | } else if((num < 0) || (num > 0xffff)) {
69 | ERROR_MSG("Logical address out of range.");
70 | } else {
71 | uint16_t logical = (uint16_t)num;
72 | // page
73 | tmp = json_object_get(value, "page");
74 | if(!json_validate_int(tmp, &num)) {
75 | ERROR_MSG("Invalid or missing page.");
76 | } else {
77 | // text (same format as section/label description)
78 | char* text = NULL;
79 | if(json_load_description (value, "text", &text) != true) {
80 | ERROR_MSG("Faile to retrieve text.");
81 | } else if(text == NULL) {
82 | ERROR_MSG("Empty text string");
83 | } else if((num < 0) || (num > 0xFF)) {
84 | ERROR_MSG("Page value out of range.");
85 | } else if(comment_repository_add(repository, logical, (uint8_t)num, text)) {
86 | ret = true;
87 | }
88 | free(text);
89 | }
90 | }
91 | }
92 | }
93 | json_decref(root);
94 | }
95 | return ret;
96 | }
97 |
--------------------------------------------------------------------------------
/comment/save.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 | #include
38 |
39 | #include "../message.h"
40 | #include "../jsonhelpers.h"
41 | #include "../comment.h"
42 |
43 | // Save comments to file.
44 | bool comment_repository_save(CommentRepository* repository, const char* filename) {
45 | assert(filename != NULL);
46 | assert(repository != NULL);
47 |
48 | bool ret = false;
49 |
50 | FILE *stream = fopen(filename, "wb");
51 | if(stream == NULL) {
52 | ERROR_MSG("Failed to open %s: %s", filename, strerror(errno));
53 | } else {
54 | int count = comment_repository_size(repository);
55 | fprintf(stream, "[\n");
56 | for(int i=0; i ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_CONFIG_H
37 | #define ETRIPATOR_CONFIG_H
38 |
39 | #define _GNU_SOURCE
40 |
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 |
47 | #include
48 | #include
49 |
50 | #include
51 |
52 | #include
53 | #include
54 |
55 | #include
56 | #include
57 | #include
58 | #include
59 |
60 | #if defined(__linux__) || defined(__APPLE__)
61 | # include
62 | # include
63 | #endif
64 |
65 | #if defined(_MSC_VER)
66 | # define strncasecmp _strnicmp
67 | # define strcasecmp _stricmp
68 | # define snprintf _snprintf
69 | # define access _access
70 | #endif
71 |
72 | #endif // ETRIPATOR_CONFIG_H
73 |
--------------------------------------------------------------------------------
/decode.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_DECODE_H
37 | #define ETRIPATOR_DECODE_H
38 |
39 | #include "config.h"
40 | #include "label.h"
41 | #include "section.h"
42 | #include "memory_map.h"
43 | #include "comment.h"
44 |
45 | /// Finds any jump address from the current section.
46 | /// \param [in] section Current section.
47 | /// \param [in] map Memory map.
48 | /// \param [in out] repository Label repository.
49 | /// \return true upon success.
50 | /// \return false if an error occured.
51 | bool label_extract(Section *section, MemoryMap *map, LabelRepository *repository);
52 |
53 | /// Process data section. The result will be output has a binary file or an asm file containing hex values or strings.
54 | /// \param [out] out File output.
55 | /// \param [in] section Current section.
56 | /// \param [in] map Memory map.
57 | /// \param [in] repository Label repository.
58 | /// \param [in] comments Comments repository.
59 | /// \param [in] extra_infos Display extra informations as comments (if none set).
60 | /// \return true upon success.
61 | /// \return false if an error occured.
62 | bool data_extract(FILE *out, Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments, int extra_infos);
63 |
64 | /// Process code section.
65 | /// \param [out] out File output.
66 | /// \param [in out] logical Current logical address.
67 | /// \param [in] section Current section.
68 | /// \param [in] map Memory map.
69 | /// \param [in] repository Label repository.
70 | /// \param [in] comments Comments repository.
71 | /// \param [in] extra_infos Display extra informations as comments (if none set).
72 | /// \return true if rts, rti or brk instruction was decoded.
73 | /// \return false otherwise.
74 | int decode(FILE *out, uint16_t *logical, Section *section, MemoryMap *map, LabelRepository *repository, CommentRepository *comments, int extra_infos);
75 |
76 | /// Computes section size.
77 | /// \param [in] sections Section array.
78 | /// \param [in] index Index of the current section.
79 | /// \param [in] count Number of sections.
80 | /// \param [in] map Memory map.
81 | /// \return Section size.
82 | int32_t compute_size(SectionArray *sections, int index, int count, MemoryMap *map);
83 |
84 | /// Output hardware IO port and RAM labels.
85 | /// \param [out] out File output.
86 | /// \param [in] map Memory map.
87 | /// \param [in] repository Label repository.
88 | void label_dump(FILE *out, MemoryMap *map, LabelRepository *repository);
89 |
90 | #endif // ETRIPATOR_DECODE_H
91 |
--------------------------------------------------------------------------------
/doxyfile.in:
--------------------------------------------------------------------------------
1 | PROJECT_NAME = "@CMAKE_PROJECT_NAME@"
2 | PROJECT_NUMBER = @ETRIPATOR_VERSION@
3 | STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@ \
4 | @PROJECT_BINARY_DIR@ \
5 | @CMAKE_SOURCE_DIR@
6 | INPUT = @PROJECT_SOURCE_DIR@
7 | INPUT += @PROJECT_SOURCE_DIR@/README.md
8 | FILE_PATTERNS = *.h \
9 | *.c
10 | GENERATE_LATEX = NO
11 | RECURSIVE = YES
12 | USE_MDFILE_AS_MAINPAGE = README.md
13 | OPTIMIZE_OUTPUT_FOR_C = YES
14 | OPTIMIZE_OUTPUT_JAVA = NO
15 | SUBGROUPING = YES
16 | EXTRACT_ALL = YES
17 | OUTPUT_DIRECTORY = doc
18 | EXCLUDE_PATTERNS = */.git/*
19 | EXCLUDE_PATTERNS += */build/*
20 | EXCLUDE_PATTERNS += */cmake/*
21 | EXCLUDE_PATTERNS += */doc/*
22 | EXCLUDE_PATTERNS += */data/*
23 | EXCLUDE_PATTERNS += */test/*
24 | EXCLUDE_PATTERNS += */examples/*
25 | EXCLUDE = *.in
26 | JAVADOC_AUTOBRIEF = YES
27 | MARKDOWN_SUPPORT = YES
28 | SUBGROUPING = YES
29 | EXTRACT_STATIC = YES
30 | SHOW_INCLUDE_FILES = YES
31 |
32 |
--------------------------------------------------------------------------------
/examples/maerchen_maze/gfx_unpack.json:
--------------------------------------------------------------------------------
1 | {
2 | "gfx_unpack": {
3 | "filename": "gfx.asm",
4 | "type": "code",
5 | "page": "0",
6 | "logical": "f71c",
7 | "size": "1ac",
8 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
9 | }
10 | }
--------------------------------------------------------------------------------
/examples/maerchen_maze/labels.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "gfx_unpack.loop", "logical": "f796", "page": "00" },
3 | { "name": "gfx_unpack.next", "logical": "f7f6", "page": "00" },
4 | { "name": ".rle", "logical": "f7ac", "page": "00" },
5 | { "name": ".rle_xor", "logical": "f7bc", "page": "00" },
6 | { "name": ".copy", "logical": "f7cf", "page": "00" },
7 | { "name": ".loop", "logical": "f7d2", "page": "00" },
8 | { "name": "gfx_unpack.map_data", "logical": "f8a6", "page": "00" },
9 | { "name": "gfx_unpack.remap_data", "logical": "f7e1", "page": "00" },
10 | { "name": "gfx_unpack.rle", "logical": "f817", "page": "00" },
11 | { "name": ".rle.loop", "logical": "f828", "page": "00" },
12 | { "name": ".rle.unroll", "logical": "f83a", "page": "00" },
13 | { "name": ".rle.copy", "logical": "f849", "page": "00" },
14 | { "name": "gfx_unpack.xor", "logical": "f857", "page": "00" },
15 | { "name": ".xor.loop", "logical": "f85c", "page": "00" },
16 | { "name": "gfx_unpack.get_type", "logical": "f888", "page": "00" },
17 | { "name": "gfx_unpack.copy", "logical": "f803", "page": "00" },
18 | { "name": ".copy.loop", "logical": "f804", "page": "00" },
19 | { "name": ".incw", "logical": "f894", "page": "00" },
20 | { "name": ".l0", "logical": "f897", "page": "00" },
21 | { "name": ".shift", "logical": "f899", "page": "00" },
22 | { "name": ".end", "logical": "f8a1", "page": "00"}
23 | ]
--------------------------------------------------------------------------------
/examples/monster_puroresu/labels.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "soft_reset", "logical": "e001", "page": "00" },
3 | { "name": "clear_zp_sp", "logical": "e029", "page": "00" },
4 | { "name": ".mute_channels", "logical": "e033", "page": "00" },
5 | { "name": ".loop", "logical": "e055", "page": "00" },
6 | { "name": ".vblank", "logical": "e068", "page": "00" },
7 | { "name": ".hblank", "logical": "e07d", "page": "00" },
8 | { "name": ".next_joypad", "logical": "e4d5", "page": "00" },
9 | { "name": ".read_joy_end", "logical": "e51d", "page": "00" }
10 | ]
--------------------------------------------------------------------------------
/examples/monster_puroresu/monster.json:
--------------------------------------------------------------------------------
1 | {
2 | "irq_reset": {
3 | "filename": "startup.asm",
4 | "type": "code",
5 | "page": "0",
6 | "logical": "e000",
7 | "size": "58",
8 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
9 | },
10 |
11 | "irq_1": {
12 | "filename": "startup.asm",
13 | "type": "code",
14 | "page": "0",
15 | "logical": "e058",
16 | "size": "55",
17 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
18 | },
19 |
20 | "unknown0": {
21 | "filename": "startup.asm",
22 | "type": "code",
23 | "page": "0",
24 | "logical": "e138",
25 | "size": "1d",
26 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
27 | },
28 |
29 | "update_satb": {
30 | "filename": "startup.asm",
31 | "type": "code",
32 | "page": "0",
33 | "logical": "e0cc",
34 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
35 | },
36 |
37 | "set_vdc_ctrl": {
38 | "filename": "startup.asm",
39 | "type": "code",
40 | "page": "0",
41 | "logical": "e4b5",
42 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
43 | },
44 |
45 | "update_scroll": {
46 | "filename": "startup.asm",
47 | "type": "code",
48 | "page": "0",
49 | "logical": "e0ad",
50 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
51 | },
52 |
53 | "read_joy": {
54 | "filename": "startup.asm",
55 | "type": "code",
56 | "page": "0",
57 | "logical": "e4ca",
58 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
59 | },
60 |
61 | "update_sound": {
62 | "filename": "startup.asm",
63 | "type": "code",
64 | "page": "0",
65 | "logical": "fbc2",
66 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
67 | },
68 |
69 | "update_channel": {
70 | "filename": "startup.asm",
71 | "type": "code",
72 | "page": "0",
73 | "logical": "fcac",
74 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
75 | },
76 |
77 | "unknown7": {
78 | "filename": "startup.asm",
79 | "type": "code",
80 | "page": "0",
81 | "logical": "fd36",
82 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
83 | },
84 |
85 | "unknown8": {
86 | "filename": "page2.asm",
87 | "type": "code",
88 | "page": "2",
89 | "logical": "a0b6",
90 | "size": "27",
91 | "mpr": ["ff", "f8", 0, 0, 0, 2, 0, 0 ]
92 | },
93 |
94 | "irq_dummy": {
95 | "filename": "startup.asm",
96 | "type": "code",
97 | "page": "0",
98 | "logical": "fff0",
99 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
100 | },
101 |
102 | "irq_vectors": {
103 | "filename": "startup.asm",
104 | "type": "data",
105 | "page": "0",
106 | "logical": "fff6",
107 | "size": "a",
108 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
109 | "data": { "type":"hex", "element_size": 2, "elements_per_line": 1 }
110 | }
111 | }
--------------------------------------------------------------------------------
/examples/sf2/joypad.json:
--------------------------------------------------------------------------------
1 | {
2 | "joydetect": {
3 | "filename": "joypad.asm",
4 | "type": "code",
5 | "logical": "6c80",
6 | "page": "15",
7 | "size": "f4",
8 | "mpr": ["ff","f8","38","15","3c","3a","04","00"]
9 | },
10 | "joyread": {
11 | "filename": "joypad.asm",
12 | "type": "code",
13 | "logical": "7d98",
14 | "page": "0d",
15 | "size": "f1",
16 | "mpr": ["ff","f8","38","0d","40","3a","04","00"]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/sf2/labels.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name":"joyread", "logical":"7d98", "page":"0d" },
3 | { "name":"first_scan", "logical":"7da3", "page":"0d" },
4 | { "name":"second_scan", "logical":"7dde", "page":"0d" },
5 | { "name":"detect_6btn", "logical":"7e0f", "page":"0d" },
6 | { "name":"is_6btn", "logical":"7e3b", "page":"0d" },
7 | { "name":"not_6btn", "logical":"7e40", "page":"0d" },
8 | { "name":"trg_6btn", "logical":"7e2b", "page":"0d" },
9 | { "name":"trg_2btn", "logical":"7e44", "page":"0d" },
10 | { "name":"check_soft_reset", "logical":"7e59", "page":"0d" },
11 | { "name":"check_sel_run", "logical":"7e72", "page":"0d" },
12 | { "name":"next_pad", "logical":"7e80", "page":"0d" },
13 | { "name":"soft_reset", "logical":"7e86", "page":"0d" },
14 | { "name":"joypad", "logical":"2c74", "page":"f8" },
15 | { "name":"joyold", "logical":"2c7a", "page":"f8" },
16 | { "name":"joytrg", "logical":"2c80", "page":"f8" },
17 | { "name":"joypad_6", "logical":"2c77", "page":"f8" },
18 | { "name":"joyold_6", "logical":"2c7d", "page":"f8" },
19 | { "name":"joytrg_6", "logical":"2c83", "page":"f8" },
20 | { "name":"joyport", "logical":"1000", "page":"ff" }
21 | ]
22 |
--------------------------------------------------------------------------------
/examples/syscard/bank0.json:
--------------------------------------------------------------------------------
1 | {
2 | "cdbios_functions": {
3 | "filename": "syscard.asm",
4 | "type": "code",
5 | "page": "0",
6 | "logical" : "e000",
7 | "size": "505",
8 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
9 | },
10 |
11 | "unknown.0": {
12 | "filename": "syscard.asm",
13 | "type": "data",
14 | "page": "0",
15 | "logical" : "e504",
16 | "size": "5",
17 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
18 | "data": { "type": "hex", "element_size": 1, "elements_per_line": 32 }
19 | },
20 |
21 | "ex_colorcmd.impl": {
22 | "filename": "syscard.asm",
23 | "type": "code",
24 | "page": "0",
25 | "logical" : "e509",
26 | "size": "ce",
27 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
28 | },
29 |
30 | "unknown.1": {
31 | "filename": "syscard.asm",
32 | "type": "data",
33 | "page": "0",
34 | "logical" : "e5d7",
35 | "size": "3",
36 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
37 | "data": { "type": "hex", "element_size": 1, "elements_per_line": 32 }
38 | },
39 |
40 | "ex_satclr.impl": {
41 | "filename": "syscard.asm",
42 | "type": "code",
43 | "page": "0",
44 | "logical" : "e5da",
45 | "size": "26",
46 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
47 | },
48 |
49 | "unknown.2": {
50 | "filename": "syscard.asm",
51 | "type": "data",
52 | "page": "0",
53 | "logical" : "f8a9",
54 | "size": "f",
55 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
56 | "data": { "type": "hex", "element_size": 1, "elements_per_line": 32 }
57 | },
58 |
59 | "bm_free.impl": {
60 | "filename": "syscard.asm",
61 | "type": "code",
62 | "page": "0",
63 | "logical" : "f8b8",
64 | "size": "575",
65 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
66 | },
67 |
68 | "grp_bios.impl": {
69 | "filename": "syscard.asm",
70 | "type": "code",
71 | "page": "0",
72 | "logical" : "fe57",
73 | "size": "18",
74 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
75 | },
76 |
77 | "jump_table.0": {
78 | "filename": "syscard.asm",
79 | "type": "data",
80 | "page": "0",
81 | "logical" : "fe2d",
82 | "size": "2a",
83 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
84 | "data": { "type": "hex", "element_size": 2, "elements_per_line": 1 }
85 | },
86 |
87 | "jump_table.1": {
88 | "filename": "syscard.asm",
89 | "type": "data",
90 | "page": "0",
91 | "logical" : "fe70",
92 | "size": "22",
93 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
94 | "data": { "type": "hex", "element_size": 2, "elements_per_line": 1 }
95 | },
96 |
97 | "ex_memopen.impl": {
98 | "filename": "syscard.asm",
99 | "type": "code",
100 | "page": "0",
101 | "logical" : "fe92",
102 | "size": "30",
103 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
104 | },
105 |
106 | "unknown.3": {
107 | "filename": "syscard.asm",
108 | "type": "data",
109 | "page": "0",
110 | "logical" : "fec2",
111 | "size": "134",
112 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
113 | "data": { "type": "hex", "element_size": 1, "elements_per_line": 32 }
114 | },
115 |
116 | "irq_vectors": {
117 | "filename": "syscard.asm",
118 | "type": "data",
119 | "page": "0",
120 | "logical": "fff6",
121 | "size": "a",
122 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
123 | "data": { "type": "hex", "element_size": 2, "elements_per_line": 1 }
124 | }
125 | }
--------------------------------------------------------------------------------
/examples/syscard/syscard.inc:
--------------------------------------------------------------------------------
1 | video_reg_l = $0000
2 | video_reg_h = $0001
3 | video_data_l = $0002
4 | video_data_h = $0003
5 | color_ctrl = $0400
6 | color_reg_l = $0402
7 | color_reg_h = $0403
8 | color_data_l = $0404
9 | color_data_h = $0405
10 | psg_ch = $0800
11 | psg_mainvol = $0801
12 | psg_freq.lo = $0802
13 | psg_freq.hi = $0803
14 | psg_ctrl = $0804
15 | psg_pan = $0805
16 | psg_wavebuf = $0806
17 | psg_noise = $0807
18 | psg_lfoctrl = $0809
19 | psg_lfofreq = $0808
20 | timer_cnt = $0C00
21 | timer_ctrl = $0C01
22 | joyport = $1000
23 | irqport = $1400
24 | irq_disable = $1402
25 | irq_status = $1403
26 | cd_port = $1800
27 | bram_lock = $1803
28 | bram_unlock = $1807
29 | vi_bitpat = $20dc
30 | vi_rvbitpat = $20dd
31 | vi_padrs = $20de
32 |
33 | vi_porg = $20e0
34 | vi_ft_back = $20e1
35 |
36 | vi_stack = $20e4
37 |
38 | time_sw = $20e6
39 | main_sw = $20e7
40 | si = $20e8
41 |
42 | r0 = $20ea
43 |
44 | zl0 = $20ec
45 | zh0 = $20ed
46 | zl1 = $20ee
47 | zh1 = $20ef
48 | zl2 = $20f0
49 | zh2 = $20f1
50 | cdi_b = $20f2
51 | crl_m = $20f3
52 | crh_m = $20f4
53 | irq_m = $20f5
54 | str_b = $20f6
55 | reg_box = $20f7
56 | _al = $20f8
57 | _ah = $20f9
58 | _bl = $20fa
59 | _bh = $20fb
60 | _cl = $20fc
61 | _ch = $20fd
62 | _dl = $20fe
63 | _dh = $20ff
64 | irq2_jmp = $2200
65 |
66 | irq_jmp = $2202
67 |
68 | tim_jmp = $2204
69 |
70 | nmi_jmp = $2206
71 |
72 | sync_jmp = $2208
73 |
74 | rcr_jmp = $220a
75 |
76 | bgx1 = $220c
77 |
78 | bgx2 = $220e
79 |
80 | bgy1 = $2210
81 |
82 | bgy2 = $2212
83 |
84 | sat_addr = $2214
85 |
86 | spr_ptr = $2216
87 | spr_yl = $2217
88 | spr_yh = $2218
89 | spr_xl = $2219
90 | spr_xh = $221a
91 | spr_nl = $221b
92 | spr_nh = $221c
93 | spr_al = $221d
94 | spr_ah = $221e
95 | color_cmd = $221f
96 | bgc_ptr = $2220
97 |
98 | bgc_len = $2222
99 | sprc_ptr = $2223
100 |
101 | sprc_len = $2225
102 | joykeyflg = $2226
103 | joyena = $2227
104 | joy = $2228
105 | joytrg = $222d
106 | joyold = $2232
107 | irq_cnt = $2241
108 | notrdyflg = $2247
109 | rndl = $2249
110 | rndh = $224a
111 | rndm = $224b
112 | tnomin = $226a
113 | outmin = $226c
114 | outsec = $226d
115 | outfrm = $226e
116 | vdtin_flg = $2272
117 | recbase0_h = $2274
118 | recbase0_m = $2275
119 | recbase0_l = $2276
120 | recbase1_h = $2277
121 | recbase1_m = $2278
122 | recbase1_l = $2279
123 | scsists = $227b
124 | suberrc = $227c
125 | sibcode = $227e
126 | psg_work_top = $22d0
127 | graph_work_top = $2616
128 | key_work_top = $2649
129 | user_work_top = $267f
130 |
--------------------------------------------------------------------------------
/examples/tadaima/README.md:
--------------------------------------------------------------------------------
1 | # Memory base 128 detection routine
2 |
3 | ## Command
4 | ```bash
5 | ./etripator --cd -l labels.json mb128.json Track02.iso
6 | ```
7 |
8 | ## Console
9 | ```
10 | mb128_detect
11 | 782a long jump to 7770 (82)
12 | 782e long jump to 7754 (82)
13 | 783c long jump to 7754 (82)
14 | 7848 short jump to 784f (82)
15 | 784d short jump to 785c (82)
16 | 7852 short jump to 7858 (82)
17 | 7854 short jump to 7828 (82)
18 | 7856 short jump to 785c (82)
19 | 785e long jump to 7754 (82)
20 | ```
21 |
22 | ## Output
23 | ```
24 | .code
25 | .bank 82
26 | .org $7826
27 | mb128_detect:
28 | phx
29 | clx
30 | mb128_detect.loop:
31 | lda #$a8
32 | jsr mb128_write_byte
33 | cla
34 | jsr mb128_write_bit
35 | lda $1000
36 | asl A
37 | asl A
38 | asl A
39 | asl A
40 | sta <$fe
41 | lda #$01
42 | jsr mb128_write_bit
43 | lda $1000
44 | and #$0f
45 | ora <$fe
46 | cmp #$04
47 | bne mb128_detect.retry
48 | cla
49 | plx
50 | rts
51 | bra mb128_detect.bit0
52 | mb128_detect.retry:
53 | inx
54 | cpx #$03
55 | bcs mb128_detect.failed
56 | bra mb128_detect.loop
57 | bra mb128_detect.bit0
58 | mb128_detect.failed:
59 | lda #$ff
60 | plx
61 | rts
62 | mb128_detect.bit0:
63 | pha
64 | cla
65 | jsr mb128_write_bit
66 | pla
67 | rts
68 | ```
69 |
--------------------------------------------------------------------------------
/examples/tadaima/labels.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "mb128_write_bit", "logical": "7754", "page": "82" },
3 | { "name": "mb128_write_byte", "logical": "7770", "page": "82" },
4 | { "name": "mb128_detect.loop", "logical": "7828", "page": "82" },
5 | { "name": "mb128_detect.retry", "logical": "784f", "page": "82" },
6 | { "name": "mb128_detect.failed", "logical": "7858", "page": "82" },
7 | { "name": "mb128_detect.bit0", "logical": "785c", "page": "82" }
8 | ]
9 |
--------------------------------------------------------------------------------
/examples/tadaima/mb128.json:
--------------------------------------------------------------------------------
1 | {
2 | "mb128_detect": {
3 | "filename": "mb128.asm",
4 | "type": "code",
5 | "page": "82",
6 | "logical" : "76e4",
7 | "offset": "4ee4",
8 | "size": "330",
9 | "mpr": ["ff", "f8", 0, "82", 0, 0, 0, 0 ]
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/youkai_douchuuki/comments.json:
--------------------------------------------------------------------------------
1 | [
2 | {"logical":"d6a1" , "page":"01f", "text":"compute vram address"},
3 | {"logical":"d6b4" , "page":"01f", "text":"set VRAM write address"},
4 | {"logical":"d6bc" , "page":"01f", "text":"set VRAM read address"},
5 | {"logical":"d736" , "page":"01f", "text":"set source pointer"},
6 | {"logical":"d73c" , "page":"01f", "text":"check if we reached of password list"},
7 | {"logical":"d73f" , "page":"01f", "text":"compare with input"},
8 | {"logical":"d757" , "page":"01f", "text":"move pointer to the next password"},
9 |
10 | {"logical":"d76c" , "page":"01f", "text":"backup source pointer"},
11 |
12 | {"logical" : "d750", "page": "1f", "text": "find end of string"}
13 | ]
--------------------------------------------------------------------------------
/examples/youkai_douchuuki/labels.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "password.str", "logical": "31dc", "page": "f8" },
3 | { "name": "password.len", "logical": "31f6", "page": "f8" },
4 |
5 | { "name": "@loop", "logical" : "d738", "page": "1f"},
6 | { "name": "@search", "logical" : "d73f", "page": "1f"},
7 | { "name": "@next", "logical" : "d74e", "page": "1f"},
8 | { "name": "@eos", "logical" : "d750", "page": "1f"},
9 | { "name": "@end", "logical" : "d765", "page": "1f"},
10 |
11 | { "name": "password.store", "logical" : "d6f7", "page": "1f",
12 | "description": [
13 | "-----------------------------------------------------------------",
14 | "store password",
15 | "-----------------------------------------------------------------"
16 | ]
17 | }
18 | ]
19 |
--------------------------------------------------------------------------------
/examples/youkai_douchuuki/password.json:
--------------------------------------------------------------------------------
1 | {
2 | "password.vram.addr": {
3 | "filename": "password.asm",
4 | "type": "code",
5 | "page": "1f",
6 | "logical" : "d6a1",
7 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ],
8 | "description": [
9 | "-----------------------------------------------------------------",
10 | "set VRAM write and read addresses",
11 | "-----------------------------------------------------------------"
12 | ]
13 | },
14 | "ld6c8": {
15 | "filename": "password.asm",
16 | "type": "code",
17 | "page": "1f",
18 | "logical" : "d6c8",
19 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ]
20 | },
21 | "password.store.end": {
22 | "filename": "password.asm",
23 | "type": "code",
24 | "page": "1f",
25 | "logical" : "d6f6",
26 | "size": "3a",
27 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ]
28 | },
29 | "ld766": {
30 | "filename": "password.asm",
31 | "type": "code",
32 | "page": "1f",
33 | "logical" : "d766",
34 | "size": "0f",
35 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ]
36 | },
37 | "password.encode": {
38 | "filename": "password.asm",
39 | "type": "code",
40 | "page": "1f",
41 | "logical" : "d853",
42 | "size": "93",
43 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ],
44 | "description": [
45 | "-----------------------------------------------------------------",
46 | "encode password",
47 | "Have fun decoding them...",
48 | "-----------------------------------------------------------------"
49 | ]
50 | },
51 | "password.check": {
52 | "filename": "password.asm",
53 | "type": "code",
54 | "page": "1f",
55 | "logical" : "d730",
56 | "size": "36",
57 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ],
58 | "description": [
59 | "-----------------------------------------------------------------",
60 | "check password",
61 | "-----------------------------------------------------------------"
62 | ]
63 | },
64 | "passwords": {
65 | "filename": "password.asm",
66 | "type": "data",
67 | "page": "1f",
68 | "logical": "d198",
69 | "size": "3de",
70 | "mpr": ["ff", "f8", "1b", "1c", "1d", "1e", "1f", 0 ],
71 | "data": { "type":"hex", "element_size": 1, "elements_per_line": 8 },
72 | "description": [
73 | "-----------------------------------------------------------------",
74 | "passwords",
75 | "",
76 | "Only the first 8 bytes of the password string are checked.",
77 | "Note that the strings can be longer. They are separated by $2a.",
78 | "The password list ends with $00.",
79 | "-----------------------------------------------------------------"
80 | ]
81 | }
82 | }
--------------------------------------------------------------------------------
/externals/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library(argparse STATIC argparse/argparse.c argparse/argparse.h)
2 |
3 | add_subdirectory(cwalk)
4 |
5 | add_library(munit STATIC ${CMAKE_CURRENT_LIST_DIR}/munit/munit.c)
6 | target_include_directories(munit PUBLIC $)
7 | set_property(TARGET munit PROPERTY INTERFACE_INCLUDE_DIRECTORIES $)
8 |
9 | add_subdirectory(fff)
10 |
--------------------------------------------------------------------------------
/ipl.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef IPL_H
37 | #define IPL_H
38 |
39 | #include "config.h"
40 | #include "section.h"
41 |
42 | /// IPL Information block data format
43 | typedef struct {
44 | /// IPLBLK - load start record no. of CD (3 bytes high/medium/low)
45 | /// this is where the program is stored.
46 | uint8_t load_start_record[3];
47 | /// IPLBLN - load block length of CD (1 byte)
48 | /// number of sectors to read.
49 | uint8_t load_sector_count;
50 | /// IPLSTA - program load address (2 bytes low/high)
51 | /// main memory address for program read.
52 | uint8_t load_store_address[2];
53 | /// IPLJMP - program execute address (2 bytes low/high)
54 | /// starting address of execution after program read.
55 | uint8_t load_exec_address[2];
56 | /// IPLMPR - ipl set mpr2-6 (5 bytes)
57 | uint8_t mpr[5];
58 | /// OPENMODE - opening mode
59 | /// bit 0: data read to vram (0: not read, 1: read)
60 | /// bit 1: data read to adpcm buffer (0: not read, 1: read)
61 | /// bit 5: bg display (0: display on, 1: display off)
62 | /// bit 6: adpcm play (0: play, 1: not play)
63 | /// bit 7: adpcm play mode (0: single, 1: repeat)
64 | uint8_t opening_mode;
65 | /// GRPBLK - opening graphic data record no. (3 bytes high/medium/low)
66 | uint8_t opening_gfx_record[3];
67 | /// GRPBLN - opening graphic data length (1 byte)
68 | uint8_t opening_gfx_sector_count;
69 | /// GRPADR - opening graphic data read address (2 bytes low/high)
70 | uint8_t opening_gfx_read_address[2];
71 | /// ADPBLK - opening ADPCM data record no. (3 bytes high/medium/low)
72 | uint8_t opening_adpcm_record[3];
73 | /// ADPBLN - opening ADPCM data length (1 byte)
74 | uint8_t opening_adpcm_sector_count;
75 | /// ADPRATE - opening ADPCM sampling rate (1 byte)
76 | uint8_t opening_adpcm_sampling_rate;
77 | /// RESERVED (7 bytes)
78 | uint8_t reserved[7];
79 | /// ID STR - "PC Engine CD-ROM SYSTEM", 0
80 | uint8_t id[24];
81 | /// LEGAL - "Copyright HUDSON SOFT / NEC Home Electronics, Ltd.", 0
82 | uint8_t legal[50];
83 | /// PROGRAM NAME - program name (16 bytes)
84 | uint8_t program_name[16];
85 | /// EXTRA - (6 bytes)
86 | uint8_t extra[6];
87 | } IPL;
88 | /* [todo]
89 | IPL graphic block
90 | color palette - 1 record
91 | BAT data - 1 record
92 | BG font data - GRPBLN - 2 records
93 | */
94 |
95 | /// Display IPL infos.
96 | /// \param [in] in IPL infos.
97 | void ipl_print(IPL *in);
98 |
99 | /// Read IPL data from file.
100 | /// \param [out] out IPL infos.
101 | /// \param [in] filename Input filename.
102 | /// \return 0 on error, 1 otherwise.
103 | bool ipl_read(IPL *out, const char *filename);
104 |
105 | /// Get irq code offsets from IPL.
106 | /// \param [in] in IPL infos.
107 | /// \param [out] out Sections.
108 | /// \return 0 on error, 1 otherwise.
109 | bool ipl_sections(IPL *in, SectionArray *out);
110 |
111 | #endif // IPL_H
112 |
--------------------------------------------------------------------------------
/irq.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "irq.h"
37 | #include "message.h"
38 |
39 | #define PCE_IRQ_TABLE 0xFFF6U
40 | #define PCE_IRQ_COUNT 5
41 |
42 | static char* g_irq_names[PCE_IRQ_COUNT] = {
43 | "irq_2",
44 | "irq_1",
45 | "irq_timer",
46 | "irq_nmi",
47 | "irq_reset"
48 | };
49 |
50 | // Get irq code offsets from rom.
51 | bool irq_read(MemoryMap* map, SectionArray *out) {
52 | assert(map != NULL);
53 | assert(out != NULL);
54 |
55 | bool ret = false;
56 | if(map->memory[PCE_MEMORY_ROM].data == NULL) {
57 | ERROR_MSG("No ROM in memory map.");
58 | } else if(map->memory[PCE_MEMORY_ROM].length < (PCE_IRQ_TABLE + PCE_IRQ_COUNT)) {
59 | ERROR_MSG("ROM is abnormally small.");
60 | } else {
61 | uint16_t offset = PCE_IRQ_TABLE;
62 | map->mpr[7] = 0;
63 |
64 | ret = true;
65 |
66 | for(size_t i=0; ret && (i ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_IRQ_H
37 | #define ETRIPATOR_IRQ_H
38 |
39 | #include "config.h"
40 | #include "memory_map.h"
41 | #include "section.h"
42 |
43 | /// Get irq code offsets from rom.
44 | /// \param [in] map Memory map.
45 | /// \param [out] out Section list.
46 | /// \return true if the IRQ vectors where successfully extradcted.
47 | /// \return false otherwise (missing ROM, or offsets out of range).
48 | bool irq_read(MemoryMap* map, SectionArray *out);
49 |
50 | #endif // ETRIPATOR_IRQ_H
51 |
--------------------------------------------------------------------------------
/jsonhelpers.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "jsonhelpers.h"
37 |
38 | #include
39 | #include
40 |
41 | bool json_validate_int(const json_t* obj, int* out) {
42 | assert(obj != NULL);
43 | assert(out != NULL);
44 | bool ret = false;
45 | if(json_is_string(obj)) {
46 | const char *str = json_string_value(obj);
47 | for(; (*str!='\0') && isspace(*str); str++) {
48 | }
49 | if(*str=='$') {
50 | str++;
51 | }
52 | errno = 0;
53 | *out = strtoul(str, NULL, 16);
54 | if(errno == 0) {
55 | ret = true;
56 | }
57 | } else if(json_is_integer(obj)) {
58 | *out = (int)json_integer_value(obj);
59 | ret = true;
60 | }
61 | return ret;
62 | }
63 |
64 | bool json_load_description(const json_t* obj, const char *key, char **out) {
65 | assert(out != NULL);
66 | assert(out && (*out == NULL));
67 |
68 | bool ret = false;
69 | char *buffer = NULL;
70 | json_t *tmp = json_object_get(obj, key);
71 |
72 | if(tmp == NULL) {
73 | ret = true;
74 | } else {
75 | if(json_is_string(tmp)) {
76 | buffer = strdup(json_string_value(tmp));
77 | } else if (json_is_array(tmp)) {
78 | int index;
79 | json_t* value;
80 | size_t len = 0;
81 | json_array_foreach(tmp, index, value) {
82 | if(json_is_string(value)) {
83 | const char *str = json_string_value(value);
84 | if(buffer != NULL) {
85 | buffer[len-1] = '\n';
86 | }
87 | size_t n = len + strlen(str) + 1;
88 | char *ptr = realloc(buffer, n);
89 | if(ptr == NULL) {
90 | free(buffer);
91 | buffer = NULL;
92 | break;
93 | }
94 | memcpy(ptr+len, str, strlen(str));
95 | ptr[n-1] = '\0';
96 | buffer = ptr;
97 | len = n;
98 | }
99 | }
100 | }
101 | ret = (buffer != NULL);
102 | }
103 | *out = buffer;
104 | return ret;
105 | }
106 |
107 | void json_print_description(FILE *out, const char *key, const char *str) {
108 | assert(out != NULL);
109 | assert(key != NULL);
110 | assert(str != NULL);
111 | fprintf(out, "\"%s\":[", key);
112 | while(*str) {
113 | fprintf(out, "\n\t\t\t\"");
114 | for(;*str && (*str != '\n'); str++) {
115 | fputc(*str, out);
116 | }
117 | fprintf(out, "\"%c", *str ? ',' : ' ');
118 | if(*str) str++;
119 | }
120 | fprintf(out, "\n\t]");
121 | }
122 |
--------------------------------------------------------------------------------
/jsonhelpers.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_JSON_HELPERS_H
37 | #define ETRIPATOR_JSON_HELPERS_H
38 |
39 | #include "config.h"
40 |
41 | #include
42 |
43 | bool json_validate_int(const json_t* obj, int* out);
44 | bool json_load_description(const json_t* obj, const char *key, char **out);
45 | void json_print_description(FILE *out, const char *key, const char *str);
46 |
47 | #endif // ETRIPATOR_JSON_HELPERS_H
--------------------------------------------------------------------------------
/label.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "label.h"
37 | #include "message.h"
38 |
39 | #include
40 |
41 | #define LABEL_ARRAY_INC 16
42 |
43 | /// Get label index by its address.
44 | /// \param [in] repository Label repository.
45 | /// \param [in] logical Logical address.
46 | /// \param [in] page Memory page.
47 | /// \return label index.
48 | /// \return -1 if the label was not found.
49 | static int label_repository_index(LabelRepository *repository, uint16_t logical, uint8_t page) {
50 | size_t i;
51 | for(i=0; ilast; i++) {
52 | if( (repository->labels[i].page == page) &&
53 | (repository->labels[i].logical == logical) ) {
54 | return (int)i;
55 | }
56 | }
57 | return -1;
58 | }
59 |
60 | // Create label repository.
61 | bool label_repository_create(LabelRepository* repository) {
62 | assert(repository != NULL);
63 | bool ret = true;
64 | repository->last = 0;
65 | repository->labels = NULL;
66 | repository->size = LABEL_ARRAY_INC;
67 | repository->labels = (Label*)malloc(repository->size * sizeof(Label));
68 | if(repository->labels == NULL) {
69 | ERROR_MSG("Failed to create label: %s", strerror(errno));
70 | label_repository_destroy(repository);
71 | ret = false;
72 | }
73 | return ret;
74 | }
75 |
76 | // Delete label repository.
77 | void label_repository_destroy(LabelRepository* repository) {
78 | repository->size = 0;
79 | repository->last = 0;
80 |
81 | if(repository->labels != NULL) {
82 | for(size_t i=0; ilast; i++) {
83 | free(repository->labels[i].name);
84 | free(repository->labels[i].description);
85 | }
86 | free(repository->labels);
87 | repository->labels = NULL;
88 | }
89 | }
90 |
91 | // Add label to repository.
92 | bool label_repository_add(LabelRepository* repository, const char* name, uint16_t logical, uint8_t page, const char *description) {
93 | assert(repository != NULL);
94 | bool ret = true;
95 | int index = label_repository_index(repository, logical, page);
96 | if(index >= 0) {
97 | #if 0
98 | if(strcmp(name, repository->labels[index].name)) {
99 | // return 0;
100 | }
101 | #endif
102 | if(description && !repository->labels[index].description) {
103 | repository->labels[index].description = strdup(description);
104 | }
105 | } else {
106 | /* Expand arrays if necessary */
107 | if(repository->last >= repository->size) {
108 | Label *ptr;
109 | repository->size += LABEL_ARRAY_INC;
110 | ptr = (Label*)realloc(repository->labels, repository->size * sizeof(Label));
111 | if(ptr == NULL) {
112 | label_repository_destroy(repository);
113 | ret = false;
114 | } else {
115 | repository->labels = ptr;
116 | }
117 | }
118 | if(ret != 0) {
119 | /* Push addresses */
120 | repository->labels[repository->last].logical = logical;
121 | repository->labels[repository->last].page = page;
122 |
123 | /* Push name and description */
124 | repository->labels[repository->last].name = strdup(name);
125 | repository->labels[repository->last].description = (description != NULL) ? strdup(description) : NULL;
126 |
127 | ++repository->last;
128 | }
129 | }
130 | return ret;
131 | }
132 |
133 | // Find a label by its address.
134 | bool label_repository_find(LabelRepository* repository, uint16_t logical, uint8_t page, Label *out) {
135 | int index = label_repository_index(repository, logical, page);
136 | bool ret = (index >= 0);
137 | if(ret) {
138 | memcpy(out, &repository->labels[index], sizeof(Label));
139 | } else {
140 | memset(out, 0, sizeof(Label));
141 | }
142 | return ret;
143 | }
144 |
145 | // Get the number of labels stored in the repository.
146 | int label_repository_size(LabelRepository* repository) {
147 | assert(repository != NULL);
148 | return (int)repository->last;
149 | }
150 |
151 | // Retrieve the label at the specified index.
152 | bool label_repository_get(LabelRepository* repository, int index, Label *out) {
153 | bool ret = false;
154 | if((repository != NULL) && ((index >= 0) && (index < (int)repository->last))) {
155 | ret = true;
156 | memcpy(out, &repository->labels[index], sizeof(Label));
157 | } else {
158 | memset(out, 0, sizeof(Label));
159 | }
160 | return ret;
161 | }
162 |
163 | // Delete labels.
164 | void label_repository_delete(LabelRepository* repository, uint16_t first, uint16_t end, uint8_t page) {
165 | size_t i;
166 | for(i=0; ilast; i++) {
167 | if( (repository->labels[i].page == page) &&
168 | (repository->labels[i].logical >= first) &&
169 | (repository->labels[i].logical < end) ) {
170 | if(repository->last) {
171 | repository->last--;
172 | if(repository->labels[i].name) {
173 | free(repository->labels[i].name);
174 | }
175 | if(repository->labels[i].description) {
176 | free(repository->labels[i].description);
177 | }
178 | memcpy(&repository->labels[i], &repository->labels[repository->last], sizeof(Label));
179 | i--;
180 | }
181 | }
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/label.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_LABEL_H
37 | #define ETRIPATOR_LABEL_H
38 |
39 | #include "config.h"
40 |
41 | /// Label.
42 | typedef struct {
43 | char* name; //< Offset in the repository name buffer
44 | uint16_t logical; //< Logical address
45 | uint8_t page; //< Memory page
46 | char* description; //< Description (optional)
47 | } Label;
48 |
49 | /// Label repository.
50 | typedef struct {
51 | size_t size; //< Size of label repository.
52 | size_t last; //< Last element in the repository.
53 | Label *labels; //< Labels.
54 | } LabelRepository;
55 |
56 | /// Create label repository.
57 | /// \param [in out] repository Label repository.
58 | /// \return true if the repository was succesfully initialized
59 | /// \return false if an error occured
60 | bool label_repository_create(LabelRepository* repository);
61 |
62 | /// Release label repository resources.
63 | /// \param [in,out] repository Label repository.
64 | void label_repository_destroy(LabelRepository* repository);
65 |
66 | /// Add label (or inline description) to repository.
67 | /// \param [in,out] repository Label repository.
68 | /// \param [in] name Name. If the name is NULL, then this label is an inline description.
69 | /// \param [in] logical Logical address.
70 | /// \param [in] page Memory page.
71 | /// \param [in] description Description (optional if name is set, mandatory otherwise).
72 | /// \return true if the entry was successfully added to the repository.
73 | /// \return false if an error occured.
74 | bool label_repository_add(LabelRepository* repository, const char* name, uint16_t logical, uint8_t page, const char *description);
75 |
76 | /// Find a label by its address.
77 | /// \param [in] repository Label repository.
78 | /// \param [in] logical Logical address.
79 | /// \param [in] page Memory page.
80 | /// \param [out] out Associated label (if any).
81 | /// \return true if a label was found.
82 | /// \return 0 otherwise.
83 | bool label_repository_find(LabelRepository* repository, uint16_t logical, uint8_t page, Label *out);
84 |
85 | /// Get the number of labels stored in the repository.
86 | /// \param [in] repository Label repository.
87 | /// \return Label count.
88 | int label_repository_size(LabelRepository* repository);
89 |
90 | /// Retrieve the label at the specified index.
91 | /// \param [in] repository Label repository.
92 | /// \param [in] index Label index.
93 | /// \param [out] out Label (if any).&
94 | /// \return true if a label exists for the specified index.
95 | /// \return false otherwise.
96 | bool label_repository_get(LabelRepository* repository, int index, Label *out);
97 |
98 | /// Delete labels
99 | /// \param [in] repository Label repository.
100 | /// \param [in] first Start of the logical address range.
101 | /// \param [in] end End of the logical address range.
102 | /// \param [in] page Memory page.
103 | void label_repository_delete(LabelRepository* repository, uint16_t first, uint16_t end, uint8_t page);
104 |
105 | /// Load labels from file.
106 | /// \param [out] repository Label repository.
107 | /// \param [in] filename Input filename.
108 | /// \return true if the labels contained in the file was succesfully added to the repository.
109 | /// \return false if an error occured.
110 | bool label_repository_load(LabelRepository* repository, const char* filename);
111 |
112 | /// Save labels to file.
113 | /// \param [in] reposity Label repository.
114 | /// \param [in] filename Configuration file.
115 | /// \return true if the labels in the repository were succesfully written to the file.
116 | /// \return false if an error occured.
117 | bool label_repository_save(LabelRepository* repository, const char* filename);
118 |
119 | #endif // ETRIPATOR_LABEL_H
120 |
--------------------------------------------------------------------------------
/label/load.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 | #include "../message.h"
38 | #include "../jsonhelpers.h"
39 | #include "../label.h"
40 |
41 | #define MAX_LABEL_NAME 128
42 |
43 | // Load labels from file.
44 | bool label_repository_load(LabelRepository* repository, const char* filename) {
45 | assert(repository != NULL);
46 | assert(filename != NULL);
47 |
48 | bool ret = false;
49 |
50 | json_error_t err;
51 | json_t* root = json_load_file(filename, 0, &err);
52 | if(!root) {
53 | ERROR_MSG("Failed to parse %s:%d:%d: %s", filename, err.line, err.column, err.text);
54 | } else {
55 | json_t* value = NULL;
56 | int index = 0;
57 | if(!json_is_array(root)) {
58 | ERROR_MSG("Array expected.");
59 | } else for (index = 0, ret = true; ret && (index < json_array_size(root)) && (value = json_array_get(root, index)); index++) {
60 | ret = 0;
61 | if(!json_is_object(value)) {
62 | ERROR_MSG("Expected object.");
63 | } else {
64 | // name
65 | json_t* tmp = json_object_get(value, "name");
66 | if (!json_is_string(tmp)) {
67 | ERROR_MSG("Missing or invalid label name.");
68 | } else {
69 | int num;
70 | const char* key = json_string_value(tmp);
71 | // logical
72 | tmp = json_object_get(value, "logical");
73 | if(!json_validate_int(tmp, &num)) {
74 | ERROR_MSG("Invalid or missing logical address.");
75 | } else if((num < 0) || (num > 0xFFFF)) {
76 | ERROR_MSG("Logical address out of range.");
77 | } else {
78 | uint16_t logical = (uint16_t)num;
79 | // page
80 | tmp = json_object_get(value, "page");
81 | if(!json_validate_int(tmp, &num)) {
82 | ERROR_MSG("Invalid or missing page.");
83 | } else {
84 | // description
85 | char* description = NULL;
86 | if(json_load_description(value, "description", &description) != true) {
87 | ERROR_MSG("Failed to load label description");
88 | } else if((num < 0) || (num > 0xff)) {
89 | ERROR_MSG("Page value out of range.");
90 | } else if(label_repository_add(repository, key, logical, (uint8_t)num, description)) {
91 | ret = true;
92 | }
93 | free(description);
94 | }
95 | }
96 | }
97 | }
98 | }
99 | json_decref(root);
100 | }
101 | return ret;
102 | }
103 |
--------------------------------------------------------------------------------
/label/save.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 | #include
38 |
39 | #include "../message.h"
40 | #include "../jsonhelpers.h"
41 | #include "../label.h"
42 |
43 | // Save labels to file
44 | bool label_repository_save(LabelRepository* repository, const char* filename) {
45 | bool ret = false;
46 | FILE *stream = fopen(filename, "wb");
47 | if(stream == NULL) {
48 | ERROR_MSG("Failed to open %s: %s", filename, strerror(errno));
49 | } else {
50 | int count = label_repository_size(repository);
51 |
52 | fprintf(stream, "[\n");
53 | for(int i=0; i ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "memory.h"
37 | #include "message.h"
38 |
39 | // Creates a new memory block.
40 | bool memory_create(Memory *memory, size_t length) {
41 | assert(memory != NULL);
42 |
43 | bool ret = false;
44 | if(length == 0) {
45 | ERROR_MSG("Invalid length");
46 | } else {
47 | uint8_t *buffer = (uint8_t*)malloc(length);
48 | if(buffer == NULL) {
49 | ERROR_MSG("Unable to allocate %zu bytes: %s.", length, strerror(errno));
50 | } else {
51 | memory->data = buffer;
52 | memory->length = length;
53 | ret = true;
54 | }
55 | }
56 | return ret;
57 | }
58 |
59 | // Releases memory block resources.
60 | void memory_destroy(Memory *memory) {
61 | assert(memory != NULL);
62 | free(memory->data);
63 | memory->data = NULL;
64 | memory->length = 0;
65 | }
66 |
67 | // Fills a memory block with a given byte value.
68 | bool memory_fill(Memory *memory, uint8_t c) {
69 | assert(memory != NULL);
70 | bool ret = false;
71 | if(memory->data != NULL) {
72 | const size_t n = memory->length;
73 | for(size_t i=0; idata[i] = c;
75 | }
76 | ret = true;
77 | }
78 | return ret;
79 | }
80 |
--------------------------------------------------------------------------------
/memory.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_MEMORY_H
37 | #define ETRIPATOR_MEMORY_H
38 |
39 | #include "config.h"
40 |
41 | /// @defgroup Memory Memory block
42 | ///@{
43 |
44 | /// Memory block.
45 | typedef struct {
46 | size_t length; ///< Byte array length.
47 | uint8_t *data; ///< Byte array.
48 | } Memory;
49 |
50 | /// Creates a new memory block.
51 | /// \param [out] memory Memory block.
52 | /// \param [in] length Memory block size (in bytes).
53 | /// \return true if the memory block was successfully created.
54 | /// \return false if an error occured.
55 | /// @note memory is left untouched if an error occured.
56 | bool memory_create(Memory *memory, size_t length);
57 |
58 | /// Releases memory block resources.
59 | /// \param [in out] mem Memory block.
60 | void memory_destroy(Memory *memory);
61 |
62 | /// Fills a memory block with a given byte value.
63 | /// \param [in out] mem Memory block.
64 | /// \param [in] c Byte value.
65 | /// \return true if the memory block was successfully filled.
66 | /// \return false if the memory block is invalid (0 size or unallocated).
67 | bool memory_fill(Memory *memory, uint8_t c);
68 |
69 | /// @}
70 |
71 | #endif // ETRIPATOR_MEMORY_H
72 |
--------------------------------------------------------------------------------
/memory_map.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "memory_map.h"
37 | #include "message.h"
38 |
39 | // Resets memory map.
40 | static void memory_map_clear(MemoryMap *map) {
41 | for(unsigned int i=0; imemory[i].length = 0;
43 | map->memory[i].data = NULL;
44 | }
45 | for(unsigned int i=0; impr[i] = 0xFFU;
47 | }
48 | for(unsigned int i=0; ipage[i].id = PCE_MEMORY_NONE;
50 | map->page[i].bank = 0;
51 | }
52 | }
53 |
54 | // Initializes memory map.
55 | bool memory_map_init(MemoryMap *map) {
56 | bool ret = false;
57 |
58 | memory_map_clear(map);
59 |
60 | // Allocate main (or work) RAM.
61 | if(!memory_create(&map->memory[PCE_MEMORY_BASE_RAM], PCE_BANK_SIZE)) {
62 | ERROR_MSG("Failed to allocate main memory!");
63 | } else {
64 | // Main RAM is mapped to pages 0xF8 to 0xFB (included).
65 | // Pages 0xF9 to 0xFB mirror page 0xF8. */
66 | for(unsigned int i=0xf8; i<=0xfb; i++) {
67 | map->page[i].id = PCE_MEMORY_BASE_RAM;
68 | map->page[i].bank = 0;
69 | }
70 |
71 | // ROM and syscard RAM will be initialized later.
72 | ret = true;
73 | }
74 | return ret;
75 | }
76 |
77 | // Releases resources used by the memory map.
78 | void memory_map_destroy(MemoryMap *map) {
79 | assert(map != NULL);
80 | for(unsigned i=0; imemory[i]);
82 | }
83 | memory_map_clear(map);
84 | }
85 |
86 | // Get the memory page associated to a logical address.
87 | uint8_t memory_map_page(MemoryMap* map, uint16_t logical) {
88 | assert(map != NULL);
89 | uint8_t id = (logical >> 13) & 0x07U;
90 | return map->mpr[id];
91 | }
92 |
93 | // Reads a single byte from memory.
94 | uint8_t memory_map_read(MemoryMap *map, size_t logical) {
95 | assert(map != NULL);
96 | const uint8_t id = memory_map_page(map, (uint16_t)logical);
97 | const Page *page = &map->page[id];
98 |
99 | uint8_t ret = 0xFFU;
100 | if(page->id != PCE_MEMORY_NONE) {
101 | const size_t offset = (logical & 0x1FFFU) + (page->bank * PCE_BANK_SIZE);
102 | const Memory *mem = &map->memory[page->id];
103 | if(offset < mem->length) {
104 | ret = mem->data[offset];
105 | }
106 | }
107 | return ret;
108 | }
109 |
110 | // Update mprs.
111 | void memory_map_mpr(MemoryMap *map, const uint8_t mpr[PCE_MPR_COUNT]) {
112 | assert(map != NULL);
113 | for(unsigned int i=0; impr[i] = mpr[i];
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/memory_map.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_MEMORY_MAP_H
37 | #define ETRIPATOR_MEMORY_MAP_H
38 |
39 | #include "memory.h"
40 |
41 | /// PC Engine memory blocks.
42 | enum {
43 | PCE_MEMORY_NONE = -1,
44 | PCE_MEMORY_ROM = 0,
45 | PCE_MEMORY_BASE_RAM,
46 | PCE_MEMORY_CD_RAM,
47 | PCE_MEMORY_SYSCARD_RAM,
48 | PCE_MEMORY_COUNT
49 | };
50 |
51 | #define PCE_PAGE_COUNT 0x100U
52 |
53 | #define PCE_MPR_COUNT 8U
54 |
55 | #define PCE_BANK_SIZE 8192U
56 |
57 | /// PC Engine memory page description.
58 | typedef struct {
59 | int id; // name the PCE_MEMORY_* enum ?
60 | size_t bank;
61 | } Page;
62 |
63 | /// PC Engine memory map.
64 | typedef struct {
65 | Memory memory[PCE_MEMORY_COUNT];
66 | Page page[PCE_PAGE_COUNT];
67 | uint8_t mpr[PCE_MPR_COUNT];
68 | } MemoryMap;
69 |
70 | /// Initializes memory map.
71 | /// \param [in out] map Memory map.
72 | /// \return true if the memory map was succesfully initialized
73 | /// \return false if an error occured
74 | bool memory_map_init(MemoryMap *map);
75 |
76 | /// Releases resources used by the memory map.
77 | /// \param [in out] map Memory map.
78 | void memory_map_destroy(MemoryMap *map);
79 |
80 | /// Get the memory page associated to a logical address.
81 | /// \param [in] map Memory map.
82 | /// \param [in] logical Logical address.
83 | /// \return Memory page.
84 | uint8_t memory_map_page(MemoryMap* map, uint16_t logical);
85 |
86 | /// Reads a single byte from memory.
87 | /// \param [in] map Memory map.
88 | /// \param [in] logical Logical address.
89 | /// \return The value stored at the specified logical address.
90 | uint8_t memory_map_read(MemoryMap *map, size_t logical);
91 |
92 | /// Update the whole mprs list
93 | /// \param [in out] map Memory map.
94 | /// \param [in] mpr Memory page registers.
95 | void memory_map_mpr(MemoryMap *map, const uint8_t mpr[PCE_MPR_COUNT]);
96 |
97 | #endif // ETRIPATOR_MEMORY_MAP_H
98 |
--------------------------------------------------------------------------------
/message.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "message.h"
37 |
38 | #include
39 |
40 | static MessagePrinter* g_message_printer_head = NULL;
41 |
42 | /* Setup global message printer list. */
43 | void message_printer_init() {
44 | g_message_printer_head = NULL;
45 | // nothing much atm...
46 | }
47 |
48 | /* Releases the resources used by message printers. */
49 | void message_printer_destroy() {
50 | for(MessagePrinter *it = g_message_printer_head; it != NULL; it = it->next) {
51 | if(it->close) {
52 | it->close();
53 | }
54 | }
55 | g_message_printer_head = NULL;
56 | }
57 |
58 | /* Adds a new message printer to the global list. */
59 | bool message_printer_add(MessagePrinter *printer) {
60 | bool ret = false;
61 | if((printer != NULL) && (printer->open != NULL)) {
62 | ret = printer->open();
63 | if(ret) {
64 | printer->next = g_message_printer_head;
65 | g_message_printer_head = printer;
66 | }
67 | }
68 | return ret;
69 | }
70 |
71 | /* Dispatch messages to printers. */
72 | void message_print(MessageType type, const char* file, size_t line, const char* function, const char* format, ...) {
73 | assert(file != NULL);
74 | assert(function != NULL);
75 | const char* filename;
76 | size_t length;
77 | cwk_path_get_basename(file, &filename, &length);
78 | if(filename == NULL) {
79 | filename = file;
80 | }
81 | for(MessagePrinter *it=g_message_printer_head; it != NULL; it = it->next) {
82 | if(it->output != NULL) {
83 | va_list args;
84 | va_start(args, format);
85 | (void)it->output(type, filename, line, function, format, args);
86 | va_end(args);
87 | }
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/message.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_MESSAGE_H
37 | #define ETRIPATOR_MESSAGE_H
38 |
39 | #include "config.h"
40 |
41 | /// @defgroup Message Message printing
42 | ///@{
43 |
44 | // Message types.
45 | typedef enum {
46 | MESSAGE_TYPE_ERROR = 0,
47 | MESSAGE_TYPE_WARNING,
48 | MESSAGE_TYPE_INFO,
49 | MESSAGE_TYPE_DEBUG,
50 | MESSAGE_TYPE_COUNT,
51 | } MessageType;
52 |
53 | struct MessagePrinter;
54 |
55 | /// Initializes and allocates any resources necessary for the message printer.
56 | /// \return true if the message printer was successfully opened.
57 | /// \return false if an error occured.
58 | typedef bool (*MessagePrinterOpen)();
59 |
60 | /// Releases resources used by the message printer.
61 | /// \return true if the resources used by the message printer were successfully released.
62 | /// \return false if an error occured.
63 | typedef bool (*MessagePrinterClose)();
64 |
65 | /// \brief Prints message.
66 | /// \param [in] type Message type.
67 | /// \param [in] file Name of the file where the print message command was issued.
68 | /// \param [in] line Line number in the file where the print message command was issued.
69 | /// \param [in] function Function where the print message command was issued.
70 | /// \param [in] format Format string.
71 | /// \param [in] args Argument lists.
72 | /// \return true if the message was successfully formatted and printed.
73 | /// \return false if an error occured.
74 | typedef bool (*MessagePrinterOutput)(MessageType type, const char* file, size_t line, const char* function, const char* format, va_list args);
75 |
76 | /// Message printer implementation.
77 | typedef struct MessagePrinter {
78 | MessagePrinterOpen open;
79 | MessagePrinterClose close;
80 | MessagePrinterOutput output;
81 | struct MessagePrinter* next;
82 | } MessagePrinter;
83 |
84 | #define ERROR_MSG(format, ...) message_print(MESSAGE_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
85 |
86 | #define WARNING_MSG(format, ...) message_print(MESSAGE_TYPE_WARNING, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
87 |
88 | #define INFO_MSG(format, ...) message_print(MESSAGE_TYPE_INFO, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
89 |
90 | #if NDEBUG
91 | # define DEBUG_MSG(format, ...)
92 | #else
93 | # define DEBUG_MSG(format, ...) message_print(MESSAGE_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
94 | #endif
95 |
96 | /// Setup global message printer list.
97 | void message_printer_init();
98 | /// Releases resources used by message printers.
99 | void message_printer_destroy();
100 |
101 | /// Opens and adds a new message printer to the global list.
102 | /// \param [in] printer Message printer to be added to the list.
103 | /// \return true if the message printer was successfully added to the list.
104 | /// \return false if the message printer failed to open and could not be added to the message printer list.
105 | bool message_printer_add(MessagePrinter *printer);
106 |
107 | /// Dispatch message to printers.
108 | /// \param type Message type.
109 | /// \param file Name of the file where the print message command was issued.
110 | /// \param line Line number in the file where the print message command was issued.
111 | /// \param function Function where the print message command was issued.
112 | /// \param format Format string.
113 | void message_print(MessageType type, const char* file, size_t line, const char* function, const char* format, ...);
114 |
115 | /// @}
116 |
117 | #endif // ETRIPATOR_MESSAGE_H
118 |
--------------------------------------------------------------------------------
/message/console.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "../config.h"
37 | #include "console.h"
38 |
39 | static bool g_use_escape_code = false;
40 |
41 | /// Tests if the console has support for colors and other things.
42 | /// \return true always.
43 | static bool console_message_printer_open() {
44 | g_use_escape_code = isatty(fileno(stdout)) ? true : false;
45 | return true;
46 | }
47 |
48 | /// Do nothing.
49 | /// \return true always.
50 | static bool console_message_printer_close() {
51 | return true;
52 | }
53 |
54 | /// Prints message to console.
55 | /// \param [in] type Message type.
56 | /// \param [in] file Name of the file where the print message command was issued.
57 | /// \param [in] line Line number in the file where the print message command was issued.
58 | /// \param [in] function Function where the print message command was issued.
59 | /// \param [in] format Format string.
60 | /// \param [in] args Argument lists.
61 | /// \return true upon success.
62 | static bool console_message_printer_output(MessageType type, const char* file, size_t line, const char* function, const char* format, va_list args) {
63 | static const char *message_type_name[] = {
64 | "[Error]",
65 | "[Warning]",
66 | "[Info]"
67 | };
68 | static const char *message_type_prefix[] = {
69 | "\x1b[1;31m",
70 | "\x1b[1;33m",
71 | "\x1b[1;32m"
72 | };
73 |
74 | bool ret = true;
75 | if(g_use_escape_code) {
76 | fprintf(stderr, "%s%s\x1b[0m %s:%zd \x1b[0;33m %s \x1b[1;37m : "
77 | , message_type_prefix[type]
78 | , message_type_name[type]
79 | , file
80 | , line
81 | , function
82 | );
83 | } else {
84 | fprintf(stderr, "%s %s:%zd %s : "
85 | , message_type_name[type]
86 | , file
87 | , line
88 | , function
89 | );
90 | }
91 |
92 | vfprintf(stderr, format, args);
93 |
94 | if(g_use_escape_code) {
95 | fprintf(stderr, "\x1b[0m\n");
96 | } else {
97 | fputc('\n', stderr);
98 | }
99 | fflush(stderr);
100 | return ret;
101 | }
102 |
103 | static MessagePrinter g_console_message_printer = {
104 | .open = console_message_printer_open,
105 | .close = console_message_printer_close,
106 | .output = console_message_printer_output,
107 | .next = NULL,
108 | };
109 |
110 | /* Setups console message writer. */
111 | bool console_message_printer_init() {
112 | g_use_escape_code = false;
113 | return message_printer_add(&g_console_message_printer);
114 | }
115 |
116 |
--------------------------------------------------------------------------------
/message/console.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_MESSAGE_CONSOLE_H
37 | #define ETRIPATOR_MESSAGE_CONSOLE_H
38 |
39 | #include "../message.h"
40 |
41 | /// Setups file message writer.
42 | /// \return true always.
43 | bool console_message_printer_init();
44 |
45 | #endif // ETRIPATOR_MESSAGE_FILE_H
46 |
47 |
--------------------------------------------------------------------------------
/message/file.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "../config.h"
37 | #include "file.h"
38 |
39 | static const char* g_log_filename = "etripator.log";
40 |
41 | /// Check if the log file can be opened and written to.
42 | /// \return true if the log file was successfully opened.
43 | /// \return false if an error occured.
44 | static bool file_message_printer_open() {
45 | bool ret = false;
46 | int fd = open(g_log_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
47 | if(fd < 0) {
48 | fprintf(stderr, "Failed to open log file %s: %s\n", g_log_filename, strerror(errno));
49 | } else if(close(fd) < 0) {
50 | fprintf(stderr, "Failed to close log file %s: %s\n", g_log_filename, strerror(errno));
51 | } else {
52 | ret = true;
53 | }
54 | return ret;
55 | }
56 |
57 | /// Do nothing.
58 | /// \return true always.
59 | static bool file_message_printer_close() {
60 | return true;
61 | }
62 |
63 | /// Prints message to file.
64 | /// \param [in] type Message type.
65 | /// \param [in] file Name of the file where the print message command was issued.
66 | /// \param [in] line Line number in the file where the print message command was issued.
67 | /// \param [in] function Function where the print message command was issued.
68 | /// \param [in] format Format string.
69 | /// \param [in] args Argument lists.
70 | /// \return true if the message was successfully written to the log file.
71 | /// \return false if an error occured.
72 | static bool file_message_printer_output(MessageType type, const char* file, size_t line, const char* function, const char* format, va_list args) {
73 | static const char *message_type_name[MESSAGE_TYPE_COUNT] = {
74 | "[Error]",
75 | "[Warning]",
76 | "[Info]",
77 | "[Debug]"
78 | };
79 | bool ret = false;
80 | FILE *out = fopen(g_log_filename, "a+");
81 | if(out == NULL) {
82 | fprintf(stderr, "Failed to open log file %s: %s\n", g_log_filename, strerror(errno));
83 | } else {
84 | fprintf(out, "%s %s:%zd %s : ", message_type_name[type], file, line, function);
85 | vfprintf(out, format, args);
86 | fputc('\n', out);
87 | fflush(out);
88 | if(ferror(out)) {
89 | fprintf(stderr, "Failed to output log to %s: %s\n", g_log_filename, strerror(errno));
90 | } else {
91 | ret = true;
92 | }
93 | fclose(out);
94 | }
95 | return ret;
96 | }
97 |
98 | static MessagePrinter g_file_message_printer = {
99 | .open = file_message_printer_open,
100 | .close = file_message_printer_close,
101 | .output = file_message_printer_output,
102 | .next = NULL,
103 | };
104 |
105 | /* Setups file message writer. */
106 | bool file_message_printer_init() {
107 | return message_printer_add(&g_file_message_printer);
108 | }
109 |
110 |
--------------------------------------------------------------------------------
/message/file.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_MESSAGE_FILE_H
37 | #define ETRIPATOR_MESSAGE_FILE_H
38 |
39 | #include "../message.h"
40 |
41 | /// @addtogroup Message
42 | /// @{
43 |
44 | /// Setups file message writer.
45 | /// Messages will be appeneded to a file names "etripator.log".
46 | /// This file will be placed in the current working directory.
47 | /// \return true if the log file can be written to.
48 | /// \return false if an error occured.
49 | bool file_message_printer_init();
50 |
51 | /// @}
52 |
53 | #endif // ETRIPATOR_MESSAGE_FILE_H
54 |
55 |
--------------------------------------------------------------------------------
/opcodes.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_OPCODES_H
37 | #define ETRIPATOR_OPCODES_H
38 |
39 | #include "config.h"
40 |
41 | /// @defgroup Opcode Opcode
42 | ///@{
43 |
44 | /// Opcode types:
45 | /// -# `OPC`
46 | /// -# `OPC A`
47 | /// -# `OPC #nn`
48 | /// -# `OPC #nn, ZZ`
49 | /// -# `OPC #nn, ZZ, X`
50 | /// -# `OPC #nn, hhll`
51 | /// -# `OPC #nn, hhll, X`
52 | /// -# `OPC ZZ`
53 | /// -# `OPC ZZ, X`
54 | /// -# `OPC ZZ, Y`
55 | /// -# `OPC (ZZ)`
56 | /// -# `OPC (ZZ, X)`
57 | /// -# `OPC (ZZ), Y`
58 | /// -# `OPC ZZ, hhll`
59 | /// -# `OPC hhll`
60 | /// -# `OPC (hhll)`
61 | /// -# `OPC hhll, X`
62 | /// -# `OPC hhll, Y`
63 | /// -# `OPC shsl,dhdl,hhll`
64 | /// -# `OPC l_hhll` (label)
65 | /// -# `OPC ZZ, l_hhll` (label)
66 | /// -# `OPC [hhll, X]`
67 | /// -# `.db OPC` (unsupported opcode output as raw binary data)
68 | enum PCE_ADDRESSING_MODE {
69 | PCE_OP = 0,
70 | PCE_OP_A,
71 | PCE_OP_nn,
72 | PCE_OP_nn_ZZ,
73 | PCE_OP_nn_ZZ_X,
74 | PCE_OP_nn_hhll,
75 | PCE_OP_nn_hhll_X,
76 | PCE_OP_ZZ,
77 | PCE_OP_ZZ_X,
78 | PCE_OP_ZZ_Y,
79 | PCE_OP__ZZ__,
80 | PCE_OP__ZZ_X__,
81 | PCE_OP__ZZ__Y_,
82 | PCE_OP_ZZ_hhll,
83 | PCE_OP_hhll,
84 | PCE_OP__hhll__,
85 | PCE_OP_hhll_X,
86 | PCE_OP_hhll_Y,
87 | PCE_OP_shsl_dhdl_hhll,
88 | PCE_OP__lbl__,
89 | PCE_OP_ZZ_lbl,
90 | PCE_OP__hhll_X__,
91 | PCE_unknown
92 | };
93 |
94 | #define OPCODE_NAME_MAX_LEN 5U
95 |
96 | /// Opcode
97 | typedef struct {
98 | char name[OPCODE_NAME_MAX_LEN]; //< name
99 | uint8_t size; //< size in bytes
100 | uint8_t type; //< addressing type
101 | } Opcode;
102 |
103 | /// Get opcode description
104 | /// \param [in] op Opcode id
105 | /// \return Pointer to opcode description
106 | const Opcode* opcode_get(uint8_t op);
107 |
108 | /// Get opcode format string
109 | /// \param [in] op Pointer to opcode description
110 | /// \param [in] i Opcode argument id
111 | /// \return Argument format string
112 | /// \return NULL if the argument id is out of opcode argument count
113 | const char* opcode_format(const Opcode *op, int i);
114 |
115 | /// Is the instruction a local jump ?
116 | bool opcode_is_local_jump(uint8_t op);
117 |
118 | /// Is the instruction a "far" jump ?
119 | bool opcode_is_far_jump(uint8_t op);
120 |
121 | /// @}
122 |
123 | #endif // ETRIPATOR_OPCODES_H
124 |
--------------------------------------------------------------------------------
/rom.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "rom.h"
37 | #include "message.h"
38 |
39 | static bool rom_load_data(const char *filename, MemoryMap *map) {
40 | bool ret = false;
41 |
42 | size_t size = 0;
43 | FILE *in = fopen(filename, "rb");
44 | if (in == NULL) {
45 | ERROR_MSG("Unable to open %s : %s", filename, strerror(errno));
46 | } else {
47 | // Compute file size.
48 | struct stat infos;
49 | int fd = fileno(in);
50 | if (fd < 0) {
51 | ERROR_MSG("Failed to retrieve file descriptior for %s : %s", filename, strerror(errno));
52 | } else if (fstat(fd, &infos) < 0) {
53 | ERROR_MSG("Failed to retrieve file informations of %s : %s", filename, strerror(errno));
54 | } else if (infos.st_size == 0) {
55 | ERROR_MSG("Empty file: %s", filename);
56 | } else {
57 | size = infos.st_size;
58 | // Check for possible header
59 | if (size & 0x200U) {
60 | // Jump header
61 | size &= ~0x200U;
62 | if (fseek(in, 0x200U, SEEK_SET) < 0) {
63 | ERROR_MSG("Failed to jump rom header in %s: %s", filename, strerror(errno));
64 | }
65 | }
66 | }
67 | if(size) {
68 | // Allocate rom storage
69 | Memory *memory = &map->memory[PCE_MEMORY_ROM];
70 | if (!memory_create(memory, (size + 0x1FFFU) & ~0x1FFFU)) {
71 | ERROR_MSG("Failed to allocate ROM storage : %s", strerror(errno));
72 | } else {
73 | // Fill rom with 0xFF
74 | (void)memory_fill(memory, 0xFFU);
75 | // Read ROM data
76 | size_t count = (size < memory->length) ? size : memory->length;
77 | size_t nread = fread(memory->data, 1, count, in);
78 | if (nread != count) {
79 | ERROR_MSG("Failed to read ROM data from %s (expected %zu, read %zu): %s", filename, count, nread, strerror(errno));
80 | memory_destroy(memory);
81 | } else {
82 | ret = true;
83 | }
84 | }
85 | }
86 | fclose(in);
87 | }
88 | return ret;
89 | }
90 |
91 | // Load ROM from file and update memory map.
92 | bool rom_load(const char* filename, MemoryMap* map) {
93 | assert(filename != NULL);
94 | assert(map != NULL);
95 | FILE *in;
96 | bool ret = false;
97 | if(rom_load_data(filename, map)) {
98 | unsigned int i;
99 | /* Initialize ROM pages. */
100 | if (map->memory[PCE_MEMORY_ROM].length == 0x60000U) {
101 | for (i = 0; i < 64; i++) {
102 | map->page[i].id = PCE_MEMORY_ROM;
103 | map->page[i].bank = i & 0x1FU;
104 | }
105 | for (i = 64; i < 128; i++) {
106 | map->page[i].id = PCE_MEMORY_ROM;
107 | map->page[i].bank = (i & 0x0FU) + 32;
108 | }
109 | } else if (map->memory[PCE_MEMORY_ROM].length == 0x80000U) {
110 | for (i = 0; i < 64; i++) {
111 | map->page[i].id = PCE_MEMORY_ROM;
112 | map->page[i].bank = i & 0x3FU;
113 | }
114 | for (i = 64; i < 128; i++) {
115 | map->page[i].id = PCE_MEMORY_ROM;
116 | map->page[i].bank = (i & 0x1FU) + 32;
117 | }
118 | } else {
119 | for (i = 0; i < 128; i++) {
120 | map->page[i].id = PCE_MEMORY_ROM;
121 | map->page[i].bank = i % (map->memory[PCE_MEMORY_ROM].length / PCE_BANK_SIZE);
122 | }
123 | }
124 | ret = true;
125 | }
126 | return ret;
127 | }
128 |
--------------------------------------------------------------------------------
/rom.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_ROM_H
37 | #define ETRIPATOR_ROM_H
38 |
39 | #include "memory_map.h"
40 |
41 | /// Load ROM from file and update memory map.
42 | /// \param [in] filename ROM filename.
43 | /// \param [out] map Memory map.
44 | /// \return true if the ROM was successfully loaded.
45 | /// \return false if an error occured.
46 | bool rom_load(const char* filename, MemoryMap* map);
47 |
48 | #endif // ETRIPATOR_ROM_H
49 |
--------------------------------------------------------------------------------
/section.h:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #ifndef ETRIPATOR_SECTION_H
37 | #define ETRIPATOR_SECTION_H
38 |
39 | #include "config.h"
40 |
41 | /// Section type.
42 | typedef enum {
43 | SECTION_TYPE_UNKNOWN = -1,
44 | SECTION_TYPE_DATA = 0,
45 | SECTION_TYPE_CODE,
46 | SECTION_TYPE_COUNT
47 | } SectionType;
48 |
49 | /// Retrieves section type name
50 | /// \param [in] type Section type
51 | /// \return "data" if type is SECTION_TYPE_DATA
52 | /// \return "code" if type is SECTION_TYPE_CODE
53 | /// \return "unknown" otherwise
54 | const char* section_type_name(SectionType type);
55 |
56 | /// Data type
57 | typedef enum {
58 | DATA_TYPE_UNKNOWN = -1,
59 | DATA_TYPE_BINARY = 0,
60 | DATA_TYPE_HEX,
61 | DATA_TYPE_STRING,
62 | DATA_TYPE_JUMP_TABLE,
63 | DATA_TYPE_COUNT
64 | } DataType;
65 |
66 | /// Retrieves data type name
67 | /// \param [in] type Data type
68 | /// \return "binary" if type is DATA_TYPE_BINARY
69 | /// \return "hex" if type is DATA_TYPE_HEX
70 | /// \return "string" if type is DATA_TYPE_STRING
71 | /// \return "jumptable if type is DATA_TYPE_JUMP_TABLE
72 | /// \return "unknown" otherwise
73 | const char* data_type_name(DataType type);
74 |
75 | /// Data section configuration
76 | typedef struct {
77 | DataType type; //< type
78 | int32_t element_size; //< element size (string=0, byte=1, word=2)
79 | int32_t elements_per_line; //< number of elements per line
80 |
81 | uint8_t delimiter[8U]; //< string delimiter
82 | int32_t delimiter_size; //< string delimiter length
83 | } DataConfig;
84 |
85 | /// Section description
86 | typedef struct {
87 | char *name; //< Name
88 | SectionType type; //< Type
89 | uint8_t page; //< Memory page
90 | uint16_t logical; //< logical address
91 | uint32_t offset; //< input offset
92 | int32_t size; //< size (in bytes)
93 | uint8_t mpr[8]; //< mpr registers value
94 | char *output; //< output filename
95 | DataConfig data; //< data configuration (only valid for *data* sections)
96 | char *description; //< optional description
97 | } Section;
98 |
99 | /// Section array
100 | typedef struct {
101 | Section *data; ///< Pointer to section array.
102 | size_t count; ///< Number of sections currently in use.
103 | size_t capacity; ///< Number the section array can hold.
104 | } SectionArray;
105 |
106 | /// Reset a section array.
107 | /// \note The internal data pointer will not be freed.
108 | /// \param [in out] arr Section array to be reseted.
109 | void section_array_reset(SectionArray *arr);
110 |
111 | /// Release section array memory.
112 | /// \param [in out] arr Section array.
113 | void section_array_delete(SectionArray *arr);
114 |
115 | /// Add a new section.
116 | /// \param [in out] arr Section array the section will be added to.
117 | /// \param [in] in Section that will be added to the section array.
118 | /// \return 1 if the section was succesfully added.
119 | /// \return 0 if the section was merged with one from the section array.
120 | /// \return -1 if the section can not be merged or if there is not enough memory to add a new one.
121 | int section_array_add(SectionArray *arr, const Section* in);
122 |
123 | /// Merge and sort sections.
124 | /// \param [in out] arr Section array the section will be added to.
125 | void section_array_tidy(SectionArray *arr);
126 |
127 | /// Retrieve the ith section from the array.
128 | /// \param [in] arr Section array.
129 | /// \param [in] i Index of the section to be retrieved.
130 | /// \return A pointer to the section if the index is within the section array bounds.
131 | /// \return NULL if the index is out of the section array bounds.
132 | const Section* section_array_get(SectionArray *arr, size_t i);
133 |
134 | /// Reset a section to its default values.
135 | void section_reset(Section *s);
136 |
137 | /// Delete section.
138 | void section_delete(Section *ptr);
139 |
140 | // Load sections from a JSON file.
141 | // \param [out] arr Loaded sections.
142 | // \param [in] filename Input filename.
143 | // \return true if the sections contained in the file were succesfully loaded.
144 | // \return false if an error occured.
145 | bool section_load(SectionArray *arr, const char *filename);
146 |
147 | // Save sections to a JSON file.
148 | // \param [in] ptr Sections to be saved.
149 | // \param [in] count Number of sections.
150 | // \param [in] filename Output filename.
151 | // \return true if the sections were succesfully saved.
152 | // \return false if an error occured.
153 | bool section_save(const Section *ptr, int n, const char *filename); // [todo] use SectionArray
154 |
155 | #endif // ETRIPATOR_SECTION_H
156 |
--------------------------------------------------------------------------------
/section/save.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include "../section.h"
37 |
38 | #include "../jsonhelpers.h"
39 | #include "../message.h"
40 | #include
41 | #include
42 | #include
43 |
44 | // Save sections to a JSON file
45 | bool section_save(const Section *ptr, int n, const char *filename) {
46 | bool ret = false;
47 | FILE *out = fopen(filename, "wb");
48 | if(!out) {
49 | ERROR_MSG("Failed to open %s: %s", filename, strerror(errno));
50 | } else {
51 | fprintf(out, "{\n");
52 | for(int i=0; i
32 | WORKING_DIRECTORY $
33 | )
34 | add_custom_command(
35 | TARGET ${target_name} POST_BUILD
36 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/data $/data
37 | )
38 | endfunction()
39 |
40 | add_unit_test(
41 | NAME message
42 | SOURCES
43 | message.c
44 | LIBRARIES cwalk
45 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
46 | )
47 |
48 | add_unit_test(
49 | NAME memory
50 | SOURCES
51 | memory.c
52 | ${PROJECT_SOURCE_DIR}/memory.c
53 | ${PROJECT_SOURCE_DIR}/message.c
54 | ${PROJECT_SOURCE_DIR}/message/console.c
55 | LIBRARIES cwalk
56 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
57 | )
58 |
59 | add_unit_test(
60 | NAME memory_map
61 | SOURCES
62 | memory_map.c
63 | ${PROJECT_SOURCE_DIR}/memory_map.c
64 | ${PROJECT_SOURCE_DIR}/memory.c
65 | ${PROJECT_SOURCE_DIR}/message.c
66 | ${PROJECT_SOURCE_DIR}/message/console.c
67 | LIBRARIES cwalk
68 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
69 | )
70 |
71 | if(CMAKE_COMPILER_IS_GNUCC)
72 | add_unit_test(
73 | NAME rom
74 | SOURCES
75 | rom.c
76 | ${PROJECT_SOURCE_DIR}/rom.c
77 | ${PROJECT_SOURCE_DIR}/memory_map.c
78 | ${PROJECT_SOURCE_DIR}/memory.c
79 | ${PROJECT_SOURCE_DIR}/message.c
80 | ${PROJECT_SOURCE_DIR}/message/console.c
81 | LIBRARIES cwalk fff
82 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
83 | WRAP fopen fileno fstat fseek fread fclose
84 | )
85 | endif()
86 |
87 | add_unit_test(
88 | NAME cd
89 | SOURCES
90 | cd.c
91 | ${PROJECT_SOURCE_DIR}/cd.c
92 | ${PROJECT_SOURCE_DIR}/memory_map.c
93 | ${PROJECT_SOURCE_DIR}/memory.c
94 | ${PROJECT_SOURCE_DIR}/message.c
95 | ${PROJECT_SOURCE_DIR}/message/console.c
96 | LIBRARIES cwalk
97 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
98 | )
99 |
100 | add_unit_test(
101 | NAME label
102 | SOURCES
103 | label.c
104 | ${PROJECT_SOURCE_DIR}/label.c
105 | ${PROJECT_SOURCE_DIR}/label/load.c
106 | ${PROJECT_SOURCE_DIR}/message.c
107 | ${PROJECT_SOURCE_DIR}/jsonhelpers.c
108 | ${PROJECT_SOURCE_DIR}/message/console.c
109 | LIBRARIES cwalk jansson
110 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
111 | )
112 |
113 | add_unit_test(
114 | NAME comment
115 | SOURCES
116 | comment.c
117 | ${PROJECT_SOURCE_DIR}/comment.c
118 | ${PROJECT_SOURCE_DIR}/comment/load.c
119 | ${PROJECT_SOURCE_DIR}/comment/save.c
120 | ${PROJECT_SOURCE_DIR}/message.c
121 | ${PROJECT_SOURCE_DIR}/jsonhelpers.c
122 | ${PROJECT_SOURCE_DIR}/message/console.c
123 | LIBRARIES cwalk jansson
124 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
125 | )
126 |
127 | add_unit_test(
128 | NAME section
129 | SOURCES
130 | section.c
131 | ${PROJECT_SOURCE_DIR}/section/load.c
132 | ${PROJECT_SOURCE_DIR}/message.c
133 | ${PROJECT_SOURCE_DIR}/jsonhelpers.c
134 | ${PROJECT_SOURCE_DIR}/message/console.c
135 | LIBRARIES cwalk jansson
136 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
137 | )
138 |
139 | add_unit_test(
140 | NAME opcodes
141 | SOURCES
142 | opcodes.c
143 | ${PROJECT_SOURCE_DIR}/opcodes.c
144 | ${PROJECT_SOURCE_DIR}/message.c
145 | ${PROJECT_SOURCE_DIR}/message/console.c
146 | LIBRARIES cwalk jansson
147 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
148 | )
149 |
150 | add_unit_test(
151 | NAME ipl
152 | SOURCES
153 | ipl.c
154 | ${PROJECT_SOURCE_DIR}/section.c
155 | ${PROJECT_SOURCE_DIR}/message.c
156 | ${PROJECT_SOURCE_DIR}/message/console.c
157 | LIBRARIES cwalk jansson
158 | INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}
159 | )
160 |
--------------------------------------------------------------------------------
/test/cd.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 |
38 | #include
39 | #include
40 |
41 | #include
42 |
43 | void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) {
44 | return NULL;
45 | }
46 |
47 | void tear_down(void* fixture __attribute__((unused))) {
48 | }
49 |
50 | MunitResult cd_memory_map_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
51 | MemoryMap map = {};
52 |
53 | munit_assert_true(memory_map_init(&map));
54 | munit_assert_true(cd_memory_map(&map));
55 |
56 | munit_assert_not_null(map.memory[PCE_MEMORY_CD_RAM].data);
57 | munit_assert_size(map.memory[PCE_MEMORY_CD_RAM].length, ==, PCE_CD_RAM_BANK_COUNT*PCE_BANK_SIZE);
58 | for(size_t i=0; i ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 | #include "comment.h"
38 | #include "message.h"
39 | #include "message/console.h"
40 |
41 | void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) {
42 | message_printer_init();
43 | console_message_printer_init();
44 | return NULL;
45 | }
46 |
47 | void tear_down(void* fixture __attribute__((unused))) {
48 | message_printer_destroy();
49 | }
50 |
51 | MunitResult comment_add_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
52 | Comment comment = {0};
53 | CommentRepository repository = {0};
54 | munit_assert_true(comment_repository_create(&repository));
55 |
56 | munit_assert_true(comment_repository_add(&repository, 0x0002, 0x00, "comment #0"));
57 | munit_assert_true(comment_repository_add(&repository, 0x0001, 0x00, "comment #1"));
58 | munit_assert_true(comment_repository_add(&repository, 0x0003, 0x00, "comment #3"));
59 | munit_assert_true(comment_repository_add(&repository, 0x0001, 0x01, "comment #2"));
60 |
61 | munit_assert_true(comment_repository_find(&repository, 0x0001, 0x01, &comment));
62 | munit_assert_uint16(comment.logical, ==, 0x0001);
63 | munit_assert_uint8(comment.page, ==, 0x01);
64 | munit_assert_string_equal(comment.text, "comment #2");
65 |
66 | munit_assert_true(comment_repository_find(&repository, 0x0001, 0x00, &comment));
67 | munit_assert_uint16(comment.logical, ==, 0x0001);
68 | munit_assert_uint8(comment.page, ==, 0x00);
69 | munit_assert_string_equal(comment.text, "comment #1");
70 |
71 | munit_assert_true(comment_repository_find(&repository, 0x0003, 0x00, &comment));
72 | munit_assert_uint16(comment.logical, ==, 0x0003);
73 | munit_assert_uint8(comment.page, ==, 0x00);
74 | munit_assert_string_equal(comment.text, "comment #3");
75 |
76 | munit_assert_int(comment_repository_size(&repository), ==, 4);
77 |
78 | comment_repository_destroy(&repository);
79 |
80 | return MUNIT_OK;
81 | }
82 |
83 | MunitResult comment_delete_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
84 | Comment comment = {0};
85 | CommentRepository repository = {0};
86 | munit_assert_true(comment_repository_create(&repository));
87 |
88 | munit_assert_true(comment_repository_add(&repository, 0x0002, 0x03, "comment #7"));
89 | munit_assert_true(comment_repository_add(&repository, 0x0002, 0x01, "comment #6"));
90 | munit_assert_true(comment_repository_add(&repository, 0x0002, 0x02, "comment #5"));
91 | munit_assert_true(comment_repository_add(&repository, 0x000a, 0x00, "comment #4"));
92 | munit_assert_true(comment_repository_add(&repository, 0x0008, 0x00, "comment #3"));
93 | munit_assert_true(comment_repository_add(&repository, 0x0004, 0x00, "comment #2"));
94 | munit_assert_true(comment_repository_add(&repository, 0x0002, 0x00, "comment #1"));
95 | munit_assert_true(comment_repository_add(&repository, 0x0000, 0x00, "comment #0"));
96 | munit_assert_int(comment_repository_size(&repository), ==, 8);
97 |
98 | comment_repository_delete(&repository, 0x0001, 0x0009, 0x00);
99 |
100 | munit_assert_int(comment_repository_size(&repository), ==, 5);
101 |
102 | comment_repository_destroy(&repository);
103 |
104 | return MUNIT_OK;
105 | }
106 |
107 | MunitResult comment_load_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
108 | Comment comment = {0};
109 | CommentRepository repository = {0};
110 |
111 | munit_assert_true(comment_repository_create(&repository));
112 |
113 | munit_assert_false(comment_repository_load(&repository, "/not_here/comment.json"));
114 | munit_assert_int(comment_repository_size(&repository), ==, 0);
115 |
116 | munit_assert_false(comment_repository_load(&repository, "data/comment_1.json"));
117 | munit_assert_int(comment_repository_size(&repository), ==, 1);
118 |
119 | munit_assert_true(comment_repository_get(&repository, 0, &comment));
120 | munit_assert_uint16(comment.logical, ==, 0xCAFEU);
121 | munit_assert_uint8(comment.page, ==, 0x0AU);
122 | munit_assert_string_equal(comment.text, "hello!");
123 |
124 | comment_repository_destroy(&repository);
125 |
126 | munit_assert_true(comment_repository_load(&repository, "data/comment_0.json"));
127 | munit_assert_int(comment_repository_size(&repository), ==, 2);
128 |
129 | munit_assert_true(comment_repository_find(&repository, 0xC105U, 3, &comment));
130 | munit_assert_uint16(comment.logical, ==, 0xC105U);
131 | munit_assert_uint8(comment.page, ==, 3);
132 | munit_assert_string_equal(comment.text, "line 0\nline 1\nline 2");
133 |
134 | munit_assert_true(comment_repository_find(&repository, 0xEABCU, 0, &comment));
135 | munit_assert_uint16(comment.logical, ==, 0xEABCU);
136 | munit_assert_uint8(comment.page, ==, 0);
137 | munit_assert_string_equal(comment.text, "single line comment");
138 |
139 | comment_repository_destroy(&repository);
140 |
141 | return MUNIT_OK;
142 | }
143 |
144 | static MunitTest comment_tests[] = {
145 | { "/add", comment_add_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
146 | { "/delete", comment_delete_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
147 | { "/load", comment_load_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
148 | { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
149 | };
150 |
151 | static const MunitSuite comment_suite = {
152 | "Comment test suite", comment_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
153 | };
154 |
155 | int main (int argc, char* const* argv) {
156 | return munit_suite_main(&comment_suite, NULL, argc, argv);
157 | }
--------------------------------------------------------------------------------
/test/data/bank0_0.json:
--------------------------------------------------------------------------------
1 | {
2 | "cdbios_functions": {
3 | "filename": "syscard.asm",
4 | "type": "code",
5 | "page": "0",
6 | "logical" : "e000",
7 | "size": "504",
8 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
9 | },
10 |
11 | "unknown.0": {
12 | "filename": "syscard.asm",
13 | "type": "data",
14 | "page": "0",
15 | "logical" : "e504",
16 | "size": "5",
17 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
18 | },
19 |
20 | "ex_colorcmd.impl": {
21 | "filename": "syscard.asm",
22 | "type": "code",
23 | "page": "0",
24 | "logical" : "e509",
25 | "size": "ce",
26 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
27 | },
28 |
29 | "unknown.1": {
30 | "filename": "syscard.asm",
31 | "type": "data",
32 | "page": "0",
33 | "logical" : "e5d7",
34 | "size": "3",
35 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
36 | }
37 | }
--------------------------------------------------------------------------------
/test/data/bank0_1.json:
--------------------------------------------------------------------------------
1 | {
2 | "ex_satclr.impl": {
3 | "filename": "syscard.asm",
4 | "type": "code",
5 | "page": "0",
6 | "logical" : "e5da",
7 | "size": "26",
8 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
9 | },
10 |
11 | "unknown.2": {
12 | "filename": "syscard.asm",
13 | "type": "data",
14 | "page": "0",
15 | "logical" : "f8a9",
16 | "size": "f",
17 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
18 | },
19 |
20 | "bm_free.impl": {
21 | "filename": "syscard.asm",
22 | "type": "code",
23 | "page": "0",
24 | "logical" : "f8b8",
25 | "size": "575",
26 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
27 | },
28 |
29 | "grp_bios.impl": {
30 | "filename": "syscard.asm",
31 | "type": "code",
32 | "page": "0",
33 | "logical" : "fe57",
34 | "size": "18",
35 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
36 | },
37 |
38 | "jump_table.0": {
39 | "filename": "syscard.asm",
40 | "type": "data",
41 | "page": "0",
42 | "logical" : "fe2d",
43 | "size": "2a",
44 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
45 | },
46 |
47 | "jump_table.1": {
48 | "filename": "syscard.asm",
49 | "type": "data",
50 | "page": "0",
51 | "logical" : "fe70",
52 | "size": "22",
53 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
54 | },
55 |
56 | "ex_memopen.impl": {
57 | "filename": "syscard.asm",
58 | "type": "code",
59 | "page": "0",
60 | "logical" : "fe92",
61 | "size": "30",
62 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
63 | },
64 |
65 | "unknown.3": {
66 | "filename": "syscard.asm",
67 | "type": "data",
68 | "page": "0",
69 | "logical" : "fec2",
70 | "size": "134",
71 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ]
72 | },
73 |
74 | "irq_vectors": {
75 | "filename": "syscard.asm",
76 | "type": "data",
77 | "page": "0",
78 | "logical": "fff6",
79 | "size": "a",
80 | "mpr": ["ff", "f8", 0, 0, 0, 0, 0, 0 ],
81 | "data": { "type": "hex", "element_size": 2, "elements_per_line": 1 }
82 | }
83 | }
--------------------------------------------------------------------------------
/test/data/comment_0.json:
--------------------------------------------------------------------------------
1 | [
2 | { "logical": "EABC", "page": "0", "text": "single line comment" },
3 | { "logical": "C105", "page": "3", "text": [
4 | "line 0",
5 | "line 1",
6 | "line 2"
7 | ]
8 | }
9 | ]
--------------------------------------------------------------------------------
/test/data/comment_1.json:
--------------------------------------------------------------------------------
1 | [
2 | { "logical": "CAFE", "page": "0a", "text": "hello!" },
3 | { "logical": "F00D", "page": "40", "text": { "foo": "bar" } }
4 | ]
--------------------------------------------------------------------------------
/test/data/label_0.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "var", "logical": "31dc", "page": "f8" },
3 | { "name": "do_something", "logical": "eabc", "page": "00", "description": "do something" },
4 | { "name": "run", "logical" : "d6f7", "page": "1f", "description": [
5 | "line0",
6 | "line1",
7 | "line2",
8 | "line3"
9 | ]
10 | }
11 | ]
--------------------------------------------------------------------------------
/test/data/label_1.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "ok", "logical": "5030", "page": "04" },
3 | { "name": "broken", "logical": "cafe", "page": ["5a"], "description": "!" }
4 | ]
--------------------------------------------------------------------------------
/test/ipl.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 |
38 | #include "../ipl.c"
39 |
40 | #include "message.h"
41 | #include "message/console.h"
42 |
43 | static uint8_t g_hcd8004_ipl[] = {
44 | 0x00, 0x00, 0x02, 0x04, 0x00, 0x40, 0x00, 0x40, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00,
45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 | 0x50, 0x43, 0x20, 0x45, 0x6E, 0x67, 0x69, 0x6E, 0x65, 0x20, 0x43, 0x44, 0x2D, 0x52, 0x4F, 0x4D,
47 | 0x20, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4D, 0x00, 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
48 | 0x74, 0x20, 0x48, 0x55, 0x44, 0x53, 0x4F, 0x4E, 0x20, 0x53, 0x4F, 0x46, 0x54, 0x20, 0x2F, 0x20,
49 | 0x4E, 0x45, 0x43, 0x20, 0x48, 0x6F, 0x6D, 0x65, 0x20, 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F,
50 | 0x6E, 0x69, 0x63, 0x73, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x00, 0x53, 0x70, 0x61, 0x63, 0x65, 0x20,
51 | 0x41, 0x64, 0x76, 0x65, 0x6E, 0x74, 0x75, 0x72, 0x65, 0x20, 0x43, 0x4F, 0x42, 0x52, 0x41, 0x20,
52 | };
53 |
54 | void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) {
55 | message_printer_init();
56 | console_message_printer_init();
57 | return NULL;
58 | }
59 |
60 | void tear_down(void* fixture __attribute__((unused))) {
61 | message_printer_destroy();
62 | }
63 |
64 | MunitResult ipl_read_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
65 | IPL ipl = {0};
66 | const char *filename = "data/HCD8004.ipl";
67 |
68 | FILE *in = fmemopen(g_hcd8004_ipl, sizeof(g_hcd8004_ipl), "r");
69 |
70 | munit_assert_not_null(in);
71 | munit_assert_true(ipl_read_header(&ipl, in, filename));
72 | munit_assert_int(fclose(in), ==, 0);
73 |
74 | munit_assert_uint8(ipl.load_start_record[0], ==, 0x00U);
75 | munit_assert_uint8(ipl.load_start_record[1], ==, 0x00U);
76 | munit_assert_uint8(ipl.load_start_record[2], ==, 0x02U);
77 |
78 | munit_assert_uint8(ipl.load_sector_count, ==, 0x04U);
79 |
80 | munit_assert_uint8(ipl.load_store_address[0], ==, 0x00U);
81 | munit_assert_uint8(ipl.load_store_address[1], ==, 0x40U);
82 |
83 | munit_assert_uint8(ipl.load_exec_address[0], ==, 0x00U);
84 | munit_assert_uint8(ipl.load_exec_address[1], ==, 0x40U);
85 |
86 | munit_assert_uint8(ipl.mpr[0], ==, 0x00U);
87 | munit_assert_uint8(ipl.mpr[1], ==, 0x01U);
88 | munit_assert_uint8(ipl.mpr[2], ==, 0x02U);
89 | munit_assert_uint8(ipl.mpr[3], ==, 0x03U);
90 | munit_assert_uint8(ipl.mpr[4], ==, 0x04U);
91 |
92 | munit_assert_uint8(ipl.opening_mode, ==, 0x00U);
93 |
94 | munit_assert_uint8(ipl.opening_gfx_record[0], ==, 0x00U);
95 | munit_assert_uint8(ipl.opening_gfx_record[1], ==, 0x00U);
96 | munit_assert_uint8(ipl.opening_gfx_record[2], ==, 0x00U);
97 |
98 | munit_assert_uint8(ipl.opening_gfx_sector_count, ==, 0x00U);
99 |
100 | munit_assert_uint8(ipl.opening_gfx_read_address[0], ==, 0x00U);
101 | munit_assert_uint8(ipl.opening_gfx_read_address[1], ==, 0x00U);
102 |
103 | munit_assert_uint8(ipl.opening_adpcm_record[0], ==, 0x00U);
104 | munit_assert_uint8(ipl.opening_adpcm_record[1], ==, 0x00U);
105 | munit_assert_uint8(ipl.opening_adpcm_record[2], ==, 0x00U);
106 |
107 | munit_assert_uint8(ipl.opening_adpcm_sector_count, ==, 0x00U);
108 |
109 | munit_assert_uint8(ipl.opening_adpcm_sampling_rate, ==, 0x00U);
110 |
111 | for(unsigned int i=0; i<7; i++) {
112 | munit_assert_uint8(ipl.reserved[i], ==, 0x00U);
113 | }
114 |
115 | munit_assert_memory_equal(24U, ipl.id, "PC Engine CD-ROM SYSTEM");
116 |
117 | munit_assert_memory_equal(50U, ipl.legal, "Copyright HUDSON SOFT / NEC Home Electronics,Ltd.");
118 |
119 | munit_assert_memory_equal(16U, ipl.program_name, "Space Adventure ");
120 |
121 | munit_assert_memory_equal(6U, ipl.extra, "COBRA ");
122 |
123 | return MUNIT_OK;
124 | }
125 |
126 | static MunitTest g_ipl_tests[] = {
127 | { "/read", ipl_read_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
128 | { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
129 | };
130 |
131 | static const MunitSuite g_ipl_test_suite = {
132 | "Label test suite", g_ipl_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
133 | };
134 |
135 | int main (int argc, char* const* argv) {
136 | return munit_suite_main(&g_ipl_test_suite, NULL, argc, argv);
137 | }
--------------------------------------------------------------------------------
/test/memory.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 |
38 | #include
39 | #include
40 |
41 | #include
42 |
43 | void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) {
44 | return NULL;
45 | }
46 |
47 | void tear_down(void* fixture __attribute__((unused))) {
48 | }
49 |
50 | MunitResult memory_create_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
51 | Memory mem = {0};
52 | bool result = false;
53 |
54 | mem.data = NULL;
55 | mem.length = 0xCAFEU;
56 | munit_assert_false(memory_create(&mem, 0U));
57 | munit_assert_size(mem.length, ==, 0xCAFEU);
58 | munit_assert_ptr_null(mem.data);
59 |
60 | munit_assert_true(memory_create(&mem, 32U));
61 | munit_assert_size(mem.length, ==, 32U);
62 | munit_assert_ptr_not_null(mem.data);
63 |
64 | memory_destroy(&mem);
65 | munit_assert_size(mem.length, ==, 0U);
66 | munit_assert_ptr_null(mem.data);
67 |
68 | return MUNIT_OK;
69 | }
70 |
71 | MunitResult memory_create_fill(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
72 | Memory mem = {0};
73 |
74 | munit_assert_false(memory_fill(&mem, 0x7C));
75 |
76 | munit_assert_true(memory_create(&mem, 256U));
77 | munit_assert_size(mem.length, ==, 256U);
78 | munit_assert_ptr_not_null(mem.data);
79 |
80 | munit_assert_true(memory_fill(&mem, 0x7C));
81 | for(size_t i=0; i ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 |
38 | #include
39 | #include
40 |
41 | #include
42 |
43 | void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) {
44 | return NULL;
45 | }
46 |
47 | void tear_down(void* fixture __attribute__((unused))) {
48 | }
49 |
50 | MunitResult memory_map_read_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
51 | MemoryMap map = {0};
52 |
53 | munit_assert_true(memory_map_init(&map));
54 |
55 | map.mpr[1] = 0xF8U;
56 |
57 | map.memory[PCE_MEMORY_BASE_RAM].data[0x0000] = 0xC5;
58 | map.memory[PCE_MEMORY_BASE_RAM].data[0x0100] = 0x7E;
59 | map.memory[PCE_MEMORY_BASE_RAM].data[0x1000] = 0xA9;
60 |
61 | munit_assert_uint8(memory_map_read(&map, 0x2000U), ==, 0xC5);
62 | munit_assert_uint8(memory_map_read(&map, 0x2100U), ==, 0x7E);
63 | munit_assert_uint8(memory_map_read(&map, 0x3000U), ==, 0xA9);
64 |
65 | memory_map_destroy(&map);
66 |
67 | return MUNIT_OK;
68 | }
69 |
70 | static MunitTest memory_map_tests[] = {
71 | { "/read", memory_map_read_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
72 | { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
73 | };
74 |
75 | static const MunitSuite memory_map_suite = {
76 | "Memory map test suite", memory_map_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
77 | };
78 |
79 | int main (int argc, char* const* argv) {
80 | message_printer_init();
81 | console_message_printer_init();
82 |
83 | int ret = munit_suite_main(&memory_map_suite, NULL, argc, argv);
84 |
85 | message_printer_destroy();
86 |
87 | return ret;
88 | }
--------------------------------------------------------------------------------
/test/opcodes.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 | #include "opcodes.h"
38 | #include "message.h"
39 | #include "message/console.h"
40 |
41 | void* setup(const MunitParameter params[] __attribute__((unused)), void* user_data __attribute__((unused))) {
42 | message_printer_init();
43 | console_message_printer_init();
44 | return NULL;
45 | }
46 |
47 | void tear_down(void* fixture __attribute__((unused))) {
48 | message_printer_destroy();
49 | }
50 |
51 | MunitResult opcodes_get_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
52 | const Opcode* op;
53 |
54 | op = opcode_get(0x00);
55 | munit_assert_not_null(op);
56 | munit_assert_string_equal(op->name, "brk ");
57 | munit_assert_uint8(op->size, ==, 1U);
58 | munit_assert_uint8(op->type, ==, PCE_OP);
59 |
60 | op = opcode_get(0xFF);
61 | munit_assert_not_null(op);
62 | munit_assert_string_equal(op->name, "bbs7");
63 | munit_assert_uint8(op->size, ==, 3U);
64 | munit_assert_uint8(op->type, ==, PCE_OP_ZZ_lbl);
65 |
66 | op = opcode_get(0x2B);
67 | munit_assert_not_null(op);
68 | munit_assert_string_equal(op->name, ".db ");
69 | munit_assert_uint8(op->size, ==, 1U);
70 | munit_assert_uint8(op->type, ==, PCE_unknown);
71 |
72 | return MUNIT_OK;
73 | }
74 |
75 | MunitResult opcodes_format_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
76 | const Opcode* op;
77 | unsigned int i;
78 |
79 | // tii
80 | op = opcode_get(0x73);
81 | munit_assert_uint8(op->type, ==, PCE_OP_shsl_dhdl_hhll);
82 | for(i=0; i<(op->size-1); i++) { // skip opcode
83 | munit_assert_not_null(opcode_format(op, i));
84 | }
85 | for(; i<256; i++) {
86 | munit_assert_null(opcode_format(op, i));
87 | }
88 |
89 | return MUNIT_OK;
90 | }
91 |
92 | MunitResult opcodes_jump_test(const MunitParameter params[] __attribute__((unused)), void* fixture __attribute__((unused))) {
93 | // local jump
94 | for(unsigned int i=0x0FU; i<0x100U; i+=0x10U) {
95 | munit_assert_true(opcode_is_local_jump(i)); // BBR* and BBS*
96 | }
97 | munit_assert_true(opcode_is_local_jump(0x90U)); // BCC
98 | munit_assert_true(opcode_is_local_jump(0xB0U)); // BCS
99 | munit_assert_true(opcode_is_local_jump(0x80U)); // BRA
100 | munit_assert_true(opcode_is_local_jump(0xF0U)); // BEQ
101 | munit_assert_true(opcode_is_local_jump(0x30U)); // BMI
102 | munit_assert_true(opcode_is_local_jump(0xD0U)); // BNE
103 | munit_assert_true(opcode_is_local_jump(0x10U)); // BPL
104 | munit_assert_true(opcode_is_local_jump(0x44U)); // BSR
105 | munit_assert_true(opcode_is_local_jump(0x50U)); // BVC
106 | munit_assert_true(opcode_is_local_jump(0x70U)); // BVS
107 |
108 | munit_assert_false(opcode_is_local_jump(0xEAU)); // NO
109 | munit_assert_false(opcode_is_local_jump(0x4CU)); // JMP
110 | munit_assert_false(opcode_is_local_jump(0x20U)); // JSP
111 |
112 | // far jump
113 | for(unsigned int i=0x0FU; i<0x100U; i+=0x10U) {
114 | munit_assert_false(opcode_is_far_jump(i)); // BBR* and BBS*
115 | }
116 | munit_assert_false(opcode_is_far_jump(0x90U)); // BCC
117 | munit_assert_false(opcode_is_far_jump(0xB0U)); // BCS
118 | munit_assert_false(opcode_is_far_jump(0x80U)); // BRA
119 | munit_assert_false(opcode_is_far_jump(0xF0U)); // BEQ
120 | munit_assert_false(opcode_is_far_jump(0x30U)); // BMI
121 | munit_assert_false(opcode_is_far_jump(0xD0U)); // BNE
122 | munit_assert_false(opcode_is_far_jump(0x10U)); // BPL
123 | munit_assert_false(opcode_is_far_jump(0x44U)); // BSR
124 | munit_assert_false(opcode_is_far_jump(0x50U)); // BVC
125 | munit_assert_false(opcode_is_far_jump(0x70U)); // BVS
126 |
127 | munit_assert_false(opcode_is_far_jump(0xEAU)); // NOP
128 | munit_assert_true(opcode_is_far_jump(0x4CU)); // JMP
129 | munit_assert_true(opcode_is_far_jump(0x20U)); // JSR
130 |
131 | return MUNIT_OK;
132 | }
133 |
134 | static MunitTest opcodes_tests[] = {
135 | { "/get", opcodes_get_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
136 | { "/format", opcodes_format_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
137 | { "/jump", opcodes_jump_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
138 | { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
139 | };
140 |
141 | static const MunitSuite opcodes_suite = {
142 | "Opcodes test suite", opcodes_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
143 | };
144 |
145 | int main (int argc, char* const* argv) {
146 | return munit_suite_main(&opcodes_suite, NULL, argc, argv);
147 | }
--------------------------------------------------------------------------------
/test/rom.c:
--------------------------------------------------------------------------------
1 | /*
2 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
3 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
4 |
5 | __/¯\____ ___/\__ _/\__ _/\_ _/\__ _/\___ ___/\__ __/\_ _/\__
6 | \_ ____/_> ____ \_/ _ \_ \ < /_ \_/ _>> ____ \_ > \_/ _ \_
7 | _> ___/ ¯>__> <<__// __ _/ |> > _/> ¯ \\__> <<__// /\ // __ _/
8 | _> \7 <__/:. \__/:. \> \_/ L/ _____/. 7> .\_/:. \__/ <_/ \_
9 | |:::::::::::::::::::::::/:::::::::::::>::::::::/::::::::::::::::::::::::/:::::|
10 | |¯¯\::::/\:/¯\::::/¯¯¯¯<::::/\::/¯¯\:/¯¯¯¯¯¯\::\::/¯¯\::::/¯¯\::::/¯¯¯¯<::::/¯|
11 | |__ |¯¯| T _ |¯¯¯| ___ |¯¯| |¯| _ T ______ |¯¯¯¯| _ |¯¯¯| _ |¯¯¯| ___ |¯¯| _|
12 | \|__|/\|/ \|___|/ \|__|/\|_|/ \|/ \| |/ \|___|/ \|___|/dNo\|__|/
13 |
14 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
15 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
16 |
17 | This file is part of Etripator,
18 | copyright (c) 2009--2024 Vincent Cruz.
19 |
20 | Etripator is free software: you can redistribute it and/or modify
21 | it under the terms of the GNU General Public License as published by
22 | the Free Software Foundation, either version 3 of the License, or
23 | (at your option) any later version.
24 |
25 | Etripator is distributed in the hope that it will be useful,
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | GNU General Public License for more details.
29 |
30 | You should have received a copy of the GNU General Public License
31 | along with Etripator. If not, see .
32 |
33 | ¬°¤*,¸¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸
34 | ¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯¬°¤*,¸_¸,*¤°¬°¤*,¸,*¤°¬¯
35 | */
36 | #include
37 |
38 | #include
39 |
40 | #include
41 | #include
42 |
43 | #include
44 |
45 | DEFINE_FFF_GLOBALS;
46 |
47 | // [NOTE] munit is using fileno. If a test fails, munit will loop indefinitely :/
48 |
49 | FAKE_VALUE_FUNC(FILE*, __wrap_fopen, const char*, const char*)
50 | FAKE_VALUE_FUNC(int, __wrap_fileno, FILE*)
51 | FAKE_VALUE_FUNC(int, __wrap_fstat, int, struct stat*)
52 | FAKE_VALUE_FUNC(int, __wrap_fseek, FILE*, long, int)
53 | FAKE_VALUE_FUNC(size_t, __wrap_fread, void*, size_t, size_t, FILE*)
54 | FAKE_VALUE_FUNC(int, __wrap_fclose, FILE*)
55 |
56 | static int fstat_empty_file(int fd __attribute__((unused)), struct stat* infos) {
57 | memset(infos, 0, sizeof(struct stat));
58 | infos->st_size = 0;
59 | return 0;
60 | }
61 |
62 | static size_t g_dummy_file_size;
63 |
64 | static int fstat_dummy_file(int fd __attribute__((unused)), struct stat* infos) {
65 | infos->st_size = g_dummy_file_size;
66 | return 0;
67 | }
68 |
69 | static size_t fread_dummy(void* out, size_t size, size_t nmemb, FILE* in __attribute__((unused))) {
70 | uint8_t *ptr = (uint8_t*)out;
71 | uint8_t b = 0;
72 | for(size_t j=0; j 8kb
140 |
141 | static MunitTest rom_tests[] = {
142 | { "/load/small", rom_load_small_test, setup, tear_down, MUNIT_TEST_OPTION_NONE, NULL },
143 | { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
144 | };
145 |
146 | static const MunitSuite rom_suite = {
147 | "ROM test suite", rom_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
148 | };
149 |
150 | int main (int argc, char* const* argv) {
151 | message_printer_init();
152 | console_message_printer_init();
153 |
154 | int ret = munit_suite_main(&rom_suite, NULL, argc, argv);
155 |
156 | message_printer_destroy();
157 |
158 | return ret;
159 | }
--------------------------------------------------------------------------------