├── lib ├── libfree42_bcd.a ├── gcc111libbid_hard.a ├── libfree42_bcd_rel.a ├── README └── hypot_fix.patch ├── images ├── dmcp_menu.jpg └── system_menu.jpg ├── _layouts ├── asciidoc.html ├── page.html ├── default.html ├── docu.html ├── post.html ├── home.html └── dirlisting.html ├── _includes ├── footer.html ├── header.html ├── custom-head.html └── head.html ├── patch ├── dmcp5_lft_base.patch ├── dmcp5_sdb.patch ├── dmcp5_reset_state_ram.patch └── dmcp5_ram.patch ├── bin ├── check_qspi_crc └── add_pgm_chsum ├── README_build.md ├── dmcp ├── startup_pgm.s ├── qrcode.h ├── sys │ ├── sdb.h │ └── pgm_syscalls.c ├── ff_ifc.h ├── lft_ifc.h └── dmcp.h ├── free42 ├── free42.h ├── core_aux.h └── core_main.h ├── LICENSE ├── README.md ├── index.md ├── dm ├── qspi_crc.h ├── main.h ├── data │ ├── ann01.c │ ├── ann00.c │ ├── ann02.c │ └── ann03.c ├── dm42_menu.h ├── dm42_fns.h └── dm42_menu.cc ├── stm32_program.ld └── Makefile /lib/libfree42_bcd.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/DM42PGM/HEAD/lib/libfree42_bcd.a -------------------------------------------------------------------------------- /images/dmcp_menu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/DM42PGM/HEAD/images/dmcp_menu.jpg -------------------------------------------------------------------------------- /images/system_menu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/DM42PGM/HEAD/images/system_menu.jpg -------------------------------------------------------------------------------- /lib/gcc111libbid_hard.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/DM42PGM/HEAD/lib/gcc111libbid_hard.a -------------------------------------------------------------------------------- /lib/libfree42_bcd_rel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swissmicros/DM42PGM/HEAD/lib/libfree42_bcd_rel.a -------------------------------------------------------------------------------- /_layouts/asciidoc.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 |
5 | {{ content }} 6 |
7 | 8 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | {{ content }} 6 |
7 | 8 | -------------------------------------------------------------------------------- /_includes/footer.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | Libraries in this directory are for convenience suplied pre-built. 3 | 4 | 5 | Source code for free42 library: 6 | https://github.com/swissmicros/free42 7 | 8 | 9 | Source code for Intel library: 10 | https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library 11 | 12 | -------------------------------------------------------------------------------- /_includes/header.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {%- include head.html -%} 5 | 6 | 7 | 8 | {%- include header.html -%} 9 |
10 |
11 | {{ content }} 12 |
13 |
14 | 15 | {%- include footer.html -%} 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /patch/dmcp5_lft_base.patch: -------------------------------------------------------------------------------- 1 | diff --git a/DM32S/dmcp/lft_ifc.h b/DM32S/dmcp/lft_ifc.h 2 | index a67656cb..3b9f0801 100644 3 | --- a/DM32S/dmcp/lft_ifc.h 4 | +++ b/DM32S/dmcp/lft_ifc.h 5 | @@ -1,5 +1,5 @@ 6 | 7 | -#define LIBRARY_FN_BASE 0x08000201 8 | +#define LIBRARY_FN_BASE 0x08000301 9 | 10 | #define __sysfn_malloc (*(typeof(malloc)*)(LIBRARY_FN_BASE+0)) 11 | #define __sysfn_free (*(typeof(free)*)(LIBRARY_FN_BASE+4)) 12 | -------------------------------------------------------------------------------- /patch/dmcp5_sdb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/DM32S/dmcp/dmcp.h b/DM32S/dmcp/dmcp.h 2 | index 2d9b7610..33cf69b4 100644 3 | --- a/DM32S/dmcp/dmcp.h 4 | +++ b/DM32S/dmcp/dmcp.h 5 | @@ -309,7 +309,7 @@ typedef struct { 6 | #define t24 (sdb.pds_t24) 7 | #define fReg (sdb.pds_fReg) 8 | 9 | -#define sdb (*((sys_sdb_t*)0x10002000)) 10 | +#define sdb (*((sys_sdb_t*)0x20000000)) 11 | 12 | 13 | // ---------------------------------- 14 | -------------------------------------------------------------------------------- /_layouts/docu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {%- include head.html -%} 5 | 6 | 7 | 8 | {%- include header.html -%} 9 |
10 |
11 | {{ content }} 12 |
13 |
14 | 15 | {%- include footer.html -%} 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /patch/dmcp5_reset_state_ram.patch: -------------------------------------------------------------------------------- 1 | diff --git a/DM42PGM/dmcp/dmcp.h b/DM42PGM/dmcp/dmcp.h 2 | index fed708ab..c7833373 100644 3 | --- a/DM42PGM/dmcp/dmcp.h 4 | +++ b/DM42PGM/dmcp/dmcp.h 5 | @@ -468,8 +468,8 @@ uint8_t * qspi_user_addr(); 6 | int qspi_user_size(); 7 | 8 | 9 | -// RESET preserved region 0x10007f00-0x10007fff (L4) 10 | -#define RESET_STATE_RAM 0x10007f00 11 | +// RESET preserved region 0x28003f00-0x28003fff (U5) 12 | +#define RESET_STATE_RAM 0x28003f00 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lib/hypot_fix.patch: -------------------------------------------------------------------------------- 1 | diff --git a/IntelRDFPMathLib/LIBRARY/src/bid128_hypot.c b/IntelRDFPMathLib/LIBRARY/src/bid128_hypot.c 2 | index 51748a1..7e5b1ca 100755 3 | --- a/IntelRDFPMathLib/LIBRARY/src/bid128_hypot.c 4 | +++ b/IntelRDFPMathLib/LIBRARY/src/bid128_hypot.c 5 | @@ -126,7 +126,7 @@ else { 6 | x.w[BID_HIGH_128W] &= 0x7fffffffffffffffull; 7 | y.w[BID_HIGH_128W] &= 0x7fffffffffffffffull; 8 | 9 | - if(exponent_x - exponent_y >= 35) 10 | + if(exponent_x - exponent_y >= 68) 11 | { 12 | res.w[BID_HIGH_128W] = x.w[BID_HIGH_128W]; 13 | res.w[BID_LOW_128W] = x.w[BID_LOW_128W]; 14 | -------------------------------------------------------------------------------- /patch/dmcp5_ram.patch: -------------------------------------------------------------------------------- 1 | diff --git a/DM32S/stm32_program.ld b/DM32S/stm32_program.ld 2 | index 0ea157f2..bb8066a5 100644 3 | --- a/DM32S/stm32_program.ld 4 | +++ b/DM32S/stm32_program.ld 5 | @@ -29,8 +29,8 @@ MEMORY 6 | /* FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K */ 7 | /* RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K */ 8 | /* RAM0 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K-256 */ 9 | -FLASH (rx) : ORIGIN = 0x8050000, LENGTH = 704K 10 | -RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 8K 11 | +FLASH (rx) : ORIGIN = 0x80a0000, LENGTH = 1024K 12 | +RAM (xrw) : ORIGIN = 0x28000000, LENGTH = 8K 13 | QSPI (rx) : ORIGIN = 0x90000000, LENGTH = 2048K 14 | } 15 | 16 | -------------------------------------------------------------------------------- /bin/check_qspi_crc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pgm=$1 4 | h=${2:-dm/qspi_crc.h} 5 | 6 | q=build/${pgm}_qspi.bin 7 | 8 | 9 | filesize() { 10 | stat -Lc%s "$1" 11 | } 12 | 13 | 14 | if [ ! -f "$q" ];then 15 | echo "ERROR: Missing qspi file '$q'" 16 | exit 1 17 | fi 18 | 19 | if [ ! -f "$h" ]; then 20 | sz=0 21 | crc=0 22 | else 23 | sz=`cat $h | grep SIZE | awk '{print $3}'` 24 | crc=`cat $h | grep CRC | awk '{print $3}'` 25 | fi 26 | 27 | nsz=`filesize $q` 28 | ncrc=0x`crc32 $q` 29 | 30 | if [ $sz != $nsz -o $crc != $ncrc ]; then 31 | cat << OI 32 | ==== 33 | QSPI Contents changed: 34 | Size: $sz -> $nsz 35 | CRC: $crc -> $ncrc 36 | ==== 37 | Run build once more. 38 | OI 39 | cat << OI > $h 40 | 41 | #define QSPI_DATA_SIZE $nsz 42 | #define QSPI_DATA_CRC $ncrc 43 | 44 | OI 45 | exit 1 46 | fi 47 | -------------------------------------------------------------------------------- /_includes/custom-head.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Placeholder to allow defining custom head, in principle, you can add anything here, e.g. favicons: 3 | 4 | 1. Head over to https://realfavicongenerator.net/ to add your own favicons. 5 | 2. Customize default _includes/custom-head.html in your source directory and insert the given code snippet. 6 | {% endcomment %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {{ page.path }} 18 | 19 | -------------------------------------------------------------------------------- /README_build.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | 5 | # Building Instructions 6 | 7 | ## Prerequisites 8 | 9 | GNU ARM toolchain can be downloaded from 10 | https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads. 11 | We are currently using Version 7-2018-q2-update Linux 64-bit. 12 | 13 | Make is usually available in some base development package, but you 14 | can install it directly, e.g. for debian like systems 15 | ``` 16 | sudo apt-get install make 17 | ``` 18 | 19 | Basic shell utilities (usually present in system): 20 | ``` 21 | bash, dd, sed, tac, printf, find, etc. 22 | ``` 23 | 24 | Some usually available aux utilities (could require separate installation): 25 | ``` 26 | crc32, sha1sum 27 | ``` 28 | 29 | 30 | 31 | ## Build 32 | 33 | Add ARM toolchain bin/ directory to PATH. 34 | ``` 35 | (e.g. ~/arm/gcc-arm-none-eabi-7-2018-q2-update/bin) 36 | ``` 37 | 38 | Run make to build the program. 39 | 40 | Generated program 41 | ``` 42 | build/DM42PGM.pgm 43 | ``` 44 | 45 | Contents of QSPI 46 | ``` 47 | build/DM42PGM_qspi.bin 48 | ``` 49 | 50 | 51 | 52 | ## DM42PGM repository 53 | 54 | The latest version of DM42PGM is available at 55 | [https://github.com/swissmicros/DM42PGM](https://github.com/swissmicros/DM42PGM) 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /bin/add_pgm_chsum: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bin=$1 4 | pgm=$2 5 | 6 | # -- Functions ------------ 7 | 8 | 9 | checkutils() { 10 | e=0 11 | for p in "$@"; do 12 | type $p > /dev/null 2>&1 13 | if [ $? != 0 ]; then 14 | e=1 15 | echo "ERROR: Missing required utility $p" 16 | fi 17 | done 18 | if [ $e != 0 ]; then 19 | exit 1 20 | fi 21 | } 22 | 23 | 24 | # Convert hex digits to uint32_t 25 | toint() { 26 | local x 27 | x=`printf "%08x" "0x$1" | 28 | sed -e 's|\(..\)|\1@|g' | tr '@' '\012' | tac | tr -d '\012' | 29 | sed -e 's|\(..\)|@\1|g' | sed -e 's|@|\\\x|g'` 30 | printf "$x" 31 | } 32 | 33 | toint8() { 34 | local x 35 | x=`printf "$1" | sed -e 's|\(..\)|@\1|g' | sed -e 's|@|\\\x|g'` 36 | printf "$x" 37 | } 38 | 39 | dumppgm() { 40 | ( 41 | dd if=$bin bs=4 count=1 42 | toint $hexsz 43 | dd if=$bin bs=4 skip=2 44 | ) 2>/dev/null 45 | } 46 | 47 | 48 | 49 | # -- MAIN ------------------ 50 | 51 | checkutils sha1sum sed tac dd printf find type 52 | 53 | if [ ! -f "$bin" ]; then 54 | echo "ERROR: Cannot find program binary '$bin'" 55 | exit 1 56 | fi 57 | 58 | if [ -z "$pgm" ]; then 59 | echo "ERROR: Missing destination file name" 60 | exit 1 61 | fi 62 | 63 | pgmsz=`find "$bin" -printf "%s"` 64 | hexsz=`printf "%08x" $pgmsz` 65 | 66 | sha=`dumppgm | sha1sum | tr -d ' -'` 67 | 68 | echo "SHA1: $sha" 69 | 70 | ( 71 | dumppgm 72 | toint8 $sha 73 | ) > $pgm 74 | 75 | 76 | -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | 6 |
7 |

{{ page.title | escape }}

8 | 27 |
28 | 29 |
30 | {{ content }} 31 |
32 | 33 | {%- if site.disqus.shortname -%} 34 | {%- include disqus_comments.html -%} 35 | {%- endif -%} 36 | 37 | 38 |
39 | -------------------------------------------------------------------------------- /dmcp/startup_pgm.s: -------------------------------------------------------------------------------- 1 | /** 2 | */ 3 | 4 | .syntax unified 5 | .cpu cortex-m4 6 | .fpu softvfp 7 | .thumb 8 | 9 | 10 | /* == Following section addresses are defined in ld script == */ 11 | 12 | /* = initialized data should be copied from flash to RAM before pgm start = */ 13 | /* .data section start addr in flash */ 14 | .word _sidata 15 | /* .data section start addr in RAM */ 16 | .word _sdata 17 | /* .data section end addr in RAM */ 18 | .word _edata 19 | 20 | /* = .bss section should be zeroed before pgm start = */ 21 | /* .bss section start addr in RAM */ 22 | .word _sbss 23 | /* .bss section end addr */ 24 | .word _ebss 25 | 26 | /** **/ 27 | 28 | 29 | /** 30 | Program entry point 31 | */ 32 | 33 | .section .text.Program_Entry 34 | .weak Program_Entry 35 | .type Program_Entry, %function 36 | Program_Entry: 37 | 38 | /* Copy the data segment initializers from flash to SRAM */ 39 | ldr r0, =_sidata 40 | ldr r1, =_sdata 41 | ldr r2, =_edata 42 | b CopyDataInit0 43 | 44 | CopyDataInit: 45 | ldr r3, [r0], #4 46 | str r3, [r1], #4 47 | CopyDataInit0: 48 | cmp r1, r2 49 | bcc CopyDataInit 50 | 51 | /* Zero fill the bss segment. */ 52 | movs r0, #0 53 | ldr r1, =_sbss 54 | ldr r2, = _ebss 55 | b FillZerobss0 56 | 57 | FillZerobss: 58 | str r0, [r1], #4 59 | FillZerobss0: 60 | cmp r1, r2 61 | bcc FillZerobss 62 | 63 | 64 | /* Call static constructors */ 65 | bl __libc_init_array 66 | /* Call the application entry point.*/ 67 | bl program_main 68 | bl post_main 69 | 70 | /* Just for sure as post_main shouldn't return. */ 71 | LoopForever: 72 | b LoopForever 73 | 74 | .size Program_Entry, .-Program_Entry 75 | 76 | -------------------------------------------------------------------------------- /free42/free42.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Free42 -- an HP-42S calculator simulator 3 | * Copyright (C) 2004-2025 Thomas Okken 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License, version 2, 7 | * as published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, see http://www.gnu.org/licenses/. 16 | *****************************************************************************/ 17 | 18 | #ifndef FREE42_H 19 | #define FREE42_H 1 20 | 21 | 22 | #ifndef BCD_MATH 23 | #include 24 | #endif 25 | 26 | #define int2 short 27 | #define uint2 unsigned short 28 | #define int4 int 29 | #define uint4 unsigned int 30 | #define int8 long long 31 | #define uint8 unsigned long long 32 | 33 | #pragma STDC FP_CONTRACT OFF 34 | 35 | #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 36 | /* I have tested big-endian state file compatibility in Fedora 12 37 | * running on qemu-system-ppc. I found that I needed to explicitly 38 | * set F42_BIG_ENDIAN for it to work; apparently the __BYTE_ORDER__ 39 | * macro is not defined in such old compilers. 40 | * Also see the comment about setting BID_BIG_ENDIAN in 41 | * gtk/build-intel-lib.sh. 42 | */ 43 | #define F42_BIG_ENDIAN 1 44 | #endif 45 | 46 | /* Magic number "24kF" for the state file. */ 47 | #define FREE42_MAGIC 0x466b3432 48 | #define FREE42_MAGIC_STR "24kF" 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | {%- if page.title -%} 7 |

{{ page.title }}

8 | {%- endif -%} 9 | 10 | {{ content }} 11 | 12 | 13 | {% if site.paginate %} 14 | {% assign posts = paginator.posts %} 15 | {% else %} 16 | {% assign posts = site.posts %} 17 | {% endif %} 18 | 19 | 20 | {%- if posts.size > 0 -%} 21 | {%- if page.list_title -%} 22 |

{{ page.list_title }}

23 | {%- endif -%} 24 | 40 | 41 | {% if site.paginate %} 42 |
43 | 56 |
57 | {%- endif %} 58 | 59 | {%- endif -%} 60 | 61 |
62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DM42PGM - Free42 frontend implementation for DM42 2 | 3 | [http://tech.swissmicros.com/DM42PGM](http://tech.swissmicros.com/DM42PGM) 4 | 5 | - There is DMCP interface doc in progress see [DMCP IFC doc](http://technical.swissmicros.com/dmcp/doc/DMCP-ifc-html/) (or 6 | you can download HTML zip file from [doc directory](http://technical.swissmicros.com/dm42/doc/)). 7 | 8 | # Architecture Overview 9 | ## Structure 10 | The DM Calculator Platform (DMCP) is the OS for the DM42 calculator and comes as a binary file DMCP_flash_X.Y.bin. 11 | The OS runs executable modules like Free42 which have a .pgm extension. 12 | Both binaries are found here [link to binaries](http:/technical.swissmicros.com/dm42/firmware) 13 | 14 | ## DM42 Menus 15 | The DM42 has two menus, the DMCP Menu and the System Menu. 16 | The System Menu is the regular menu as known from previous versions, see 17 | [DM42 User Manual](https://technical.swissmicros.com/dm42/doc/dm42_user_manual/) 18 | for details. 19 | 20 | 21 | ### The DMCP Menu features these options: 22 | 23 | ![dmcp_menu.jpg](/images/dmcp_menu.jpg) 24 | 1. "Program Info" display information of the program loaded in the CPU 25 | 1. "Run Program" runs the program loaded in the CPU 26 | 1. "Load Program" copies an executable module from the FAT partition to the flash memory of the CPU 27 | 1. "Load QSPI from FAT" should not be needed 28 | 1. "Settings" for Time and Date 29 | 1. "Active USB Disk" puts the DM42 in USB mode for file copy 30 | 1. "Enter System Menu" jumps to the main System Menu 31 | 1. "About" displays general information 32 | 33 | ## Update procedure 34 | 35 | 1. Active USB disk in the setup menu 36 | 1. Copy both [DMCP_flash_X.Y.bin and the .pgm](http://technical.swissmicros.com/dm42/firmware) file from the PC/MAC to the FAT partition of the DM42 37 | 1. Eject DM42 from PC/MAC 38 | 1. On the DM42, SETUP > System > Flash firmware from FAT. 39 | 1. Once finished the calculator resets and displays the DMCP Menu. 40 | 1. Choose "Load Program" and select DM-X.Y.Z.pgm 41 | 1. Once loaded, select "Run Program" and Free42 starts. 42 | 43 | # Building Instructions 44 | Read the [README_build](README_build.md) . 45 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | # DM42PGM - Free42 frontend implementation for DM42 5 | 6 | [https://github.com/swissmicros/DM42PGM](https://github.com/swissmicros/DM42PGM) 7 | 8 | - There is DMCP interface doc in progress see [DMCP IFC doc](http://technical.swissmicros.com/dmcp/doc/DMCP-ifc-html/) (or 9 | you can download HTML zip file from [doc directory](http://technical.swissmicros.com/dm42/doc/)). 10 | 11 | # Architecture Overview 12 | ## Structure 13 | The DM Calculator Platform (DMCP) is the OS for the DM42 calculator and comes as a binary file DMCP_flash_X.Y.bin. 14 | The OS runs executable modules like Free42 which have a .pgm extension. 15 | Both binaries are found here [link to binaries](http:/technical.swissmicros.com/dm42/firmware) 16 | 17 | ## DM42 Menus 18 | The DM42 has two menus, the DMCP Menu and the System Menu. 19 | The System Menu is the regular menu as known from previous versions, see 20 | [DM42 User Manual](https://technical.swissmicros.com/dm42/doc/dm42_user_manual/) 21 | for details. 22 | 23 | 24 | ### The DMCP Menu features these options: 25 | 26 | ![dmcp_menu.jpg](/images/dmcp_menu.jpg) 27 | 1. "Program Info" display information of the program loaded in the CPU 28 | 1. "Run Program" runs the program loaded in the CPU 29 | 1. "Load Program" copies an executable module from the FAT partition to the flash memory of the CPU 30 | 1. "Load QSPI from FAT" should not be needed 31 | 1. "Settings" for Time and Date 32 | 1. "Active USB Disk" puts the DM42 in USB mode for file copy 33 | 1. "Enter System Menu" jumps to the main System Menu 34 | 1. "About" displays general information 35 | 36 | ## Update procedure 37 | 38 | 1. Active USB disk in the setup menu 39 | 1. Copy both [DMCP_flash_X.Y.bin and the .pgm](http://technical.swissmicros.com/dm42/firmware) file from the PC/MAC to the FAT partition of the DM42 40 | 1. Eject DM42 from PC/MAC 41 | 1. On the DM42, SETUP > System > Flash firmware from FAT. 42 | 1. Once finished the calculator resets and displays the DMCP Menu. 43 | 1. Choose "Load Program" and select DM-X.Y.Z.pgm 44 | 1. Once loaded, select "Run Program" and Free42 starts. 45 | 46 | # Building Instructions 47 | Read the [README_build](README_build.html) . 48 | -------------------------------------------------------------------------------- /dm/qspi_crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #define QSPI_DATA_SIZE 1370864 45 | #define QSPI_DATA_CRC 0x000cfed6 46 | 47 | -------------------------------------------------------------------------------- /dm/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __PGM_MAIN_H__ 44 | #define __PGM_MAIN_H__ 45 | 46 | #define PROGRAM_NAME "DM42PGM" 47 | #define DM42_VERSION "3.26" 48 | #define F42_VERSION "3.3.10" 49 | #define PROGRAM_VERSION DM42_VERSION "/" F42_VERSION 50 | 51 | // Disable printf traces for release build 52 | //#define DBG_PRINT 53 | //#define DEBUG_THELL 54 | //#define DEBUG_SHELL 55 | 56 | #ifdef DBG_PRINT 57 | #else 58 | #define printf(...) 59 | #define puts(...) 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /free42/core_aux.h: -------------------------------------------------------------------------------- 1 | #ifndef __CORE_AUX_H__ 2 | #define __CORE_AUX_H__ 3 | 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include 10 | 11 | /* 12 | typedef enum { 13 | AUX_REG_X = 1, 14 | AUX_REG_Y, 15 | AUX_REG_Z, 16 | AUX_REG_T, 17 | AUX_REG_LX, 18 | AUX_REG_A 19 | } reg_id_t; 20 | */ 21 | 22 | #define AUX_REG_X 1 23 | #define AUX_REG_Y 2 24 | #define AUX_REG_Z 3 25 | #define AUX_REG_T 4 26 | #define AUX_REG_LX 5 27 | #define AUX_REG_A 6 28 | 29 | typedef int reg_id_t; 30 | 31 | 32 | void set_graphics_mode(int gm); 33 | int graphics_mode(); 34 | int gr_MAXX(); 35 | int gr_MAXY(); 36 | 37 | 38 | // Convert register to string 39 | int reg2str(char *buf, int buflen, reg_id_t reg_id); 40 | 41 | 42 | // Avoid Free42 functionality disablig auto-started program 43 | // after ON to turn the calc back to OFF 44 | void clear_no_keystrokes_yet(); 45 | 46 | // Returns mode pause state 47 | int is_mode_pause(); 48 | 49 | // Returns mode number entry state 50 | int is_number_entry(); 51 | 52 | // Returns wide print flag 53 | int is_wide_print(); 54 | 55 | // Returns clk24 flag 56 | int is_clk24(); 57 | 58 | // Returns dmy flag 59 | int is_dmy(); 60 | 61 | // Is program mode 62 | int is_pgm_mode(); 63 | 64 | // Is current program locked 65 | int is_cur_pgm_locked(); 66 | 67 | // Set clk24 flag 68 | void set_clk24(int val); 69 | 70 | // Set DMY flag 71 | void set_dmy(int val); 72 | 73 | 74 | // Is goose displayed 75 | int is_goose(); 76 | 77 | // Returns RefLCD mask for LCD update during program RUN 78 | int get_reflcd_mask(); 79 | void set_reflcd_mask(int reflcd); 80 | 81 | typedef struct { 82 | int pgm_line; 83 | int8_t y_row; 84 | } pgm_info_t; 85 | 86 | void get_pgm_info(pgm_info_t * pi); 87 | 88 | typedef struct { 89 | int pc; 90 | int line; 91 | int8_t is_end; 92 | char * buf; 93 | int buflen; 94 | } pgm_line_t; 95 | 96 | 97 | int is_program_line_entry(); 98 | void pgm_line_init(pgm_line_t * p, char * buf, int buflen); 99 | int get_pgm_line(pgm_line_t * p, int line); 100 | 101 | 102 | // Returns free42 version string 103 | const char * free42_version_str(); 104 | 105 | // Get/Set calc flag 106 | int get_calc_flag(int flag_nr); 107 | void set_calc_flag(int flag_nr, int val); 108 | 109 | // DynStack 110 | int is_dynstack(); 111 | int get_dynstack_size(); 112 | 113 | 114 | // Core keydown hack to support separate menu key line 115 | //int core_keydown_ex(int key, int *enqueued, int *repeat, int no_menu_key); 116 | bool core_keydown_ex(int key, bool *enqueued, int *repeat, int no_menu_key); 117 | 118 | // Returns printer delay set by DELAY command 119 | unsigned int core_printer_delay(); 120 | void core_set_printer_delay(unsigned int val); 121 | 122 | void core_redisplay(); 123 | 124 | #ifdef __cplusplus 125 | } // extern "C" 126 | #endif 127 | 128 | char* core_display_buffer(); 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /dmcp/qrcode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * This library is written and maintained by Richard Moore. 5 | * Major parts were derived from Project Nayuki's library. 6 | * 7 | * Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) 8 | * Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files (the "Software"), to deal 12 | * in the Software without restriction, including without limitation the rights 13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | * copies of the Software, and to permit persons to whom the Software is 15 | * furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in 18 | * all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | * THE SOFTWARE. 27 | */ 28 | 29 | /** 30 | * Special thanks to Nayuki (https://www.nayuki.io/) from which this library was 31 | * heavily inspired and compared against. 32 | * 33 | * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp 34 | */ 35 | 36 | #ifndef __QRCODE_H_ 37 | #define __QRCODE_H_ 38 | 39 | #ifndef __cplusplus 40 | typedef unsigned char bool; 41 | static const bool false = 0; 42 | static const bool true = 1; 43 | #endif 44 | 45 | #include 46 | 47 | 48 | // QR Code Format Encoding 49 | #define MODE_NUMERIC 0 50 | #define MODE_ALPHANUMERIC 1 51 | #define MODE_BYTE 2 52 | 53 | 54 | // Error Correction Code Levels 55 | #define ECC_LOW 0 56 | #define ECC_MEDIUM 1 57 | #define ECC_QUARTILE 2 58 | #define ECC_HIGH 3 59 | 60 | 61 | // If set to non-zero, this library can ONLY produce QR codes at that version 62 | // This saves a lot of dynamic memory, as the codeword tables are skipped 63 | #ifndef LOCK_VERSION 64 | #define LOCK_VERSION 0 65 | #endif 66 | 67 | 68 | typedef struct QRCode { 69 | uint8_t version; 70 | uint8_t size; 71 | uint8_t ecc; 72 | uint8_t mode; 73 | uint8_t mask; 74 | uint8_t *modules; 75 | } QRCode; 76 | 77 | 78 | #ifdef __cplusplus 79 | extern "C"{ 80 | #endif /* __cplusplus */ 81 | 82 | 83 | 84 | uint16_t qrcode_getBufferSize(uint8_t version); 85 | 86 | int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data); 87 | int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length); 88 | 89 | bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y); 90 | 91 | 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif /* __cplusplus */ 96 | 97 | 98 | #endif /* __QRCODE_H_ */ 99 | -------------------------------------------------------------------------------- /_layouts/dirlisting.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: docu 3 | --- 4 | {% assign abs_url = page.url | absolute_url %} 5 | {% assign rel_url = page.url | relative_url %} 6 | {% if rel_url != '/' %} {% assign base_url = abs_url | replace: rel_url, '' | append: '/' %} 7 | {% else %} {% assign base_url = abs_url %} 8 | {% endif %} 9 | {% assign depth = page.path | split: '/' | size %} 10 | {% assign pwd = page.path | replace: page.name, '' %} 11 | 12 | 23 | 24 |

Directory listing {{ site.github.repository_name }}{{ page.url | replace page.path, '' | replace '/', '' }}

25 | 26 |
27 | {{ content }} 28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {% capture folders_list %} 37 | {% for file in site.static_files %} 38 | {% assign path = file.path | split: '/' %} 39 | {% if path | size != depth %} 40 | {% if path[depth] != file.name %} 41 | {% assign dif = file.path | split: pwd %} 42 | {% if dif[0] == '/' || depth == 1 %} 43 | {{ file.path | replace: file.name, '' }} 44 | {% if forloop.last == false %}::{% endif%} 45 | {% endif %} 46 | {% endif %} 47 | {% endif %} 48 | {% endfor %} 49 | {% endcapture %} 50 | {% assign folders = folders_list | strip_newlines | replace: ' ', '' | split: '::'| uniq | sort %} 51 | 52 | 53 | {% capture top_folder_list %} 54 | {% for folder in folders %} 55 | {% assign path = folder | split: '/' %} 56 | {{ path[depth] }} 57 | {% if forloop.last == false %}::{% endif %} 58 | {% endfor %} 59 | {% endcapture %} 60 | {% assign top_folders = top_folder_list | strip_newlines | replace: ' ', '' | split: '::' | uniq | compact | sort %} 61 | 62 | 63 | 64 | 65 | 66 | {% if depth != 1 %} 67 | 68 | {% endif %} 69 | 70 | {% for folder in top_folders %} 71 | 72 | {% endfor %} 73 | 74 | {% for file in site.static_files %} 75 | {% assign path_s = file.path | split: '/' | size | minus: 1 %} 76 | {% if path_s == depth %} 77 | {% assign dif = file.path | split: pwd %} 78 | {% if dif[0] == '/' %} 79 | {% assign desc = page.descriptions | where:"name", file.name | first %} 80 | 81 | {% endif %} 82 | {% endif %} 83 | {% endfor %} 84 | 85 | 86 |
NameDescription
Parent Directory
{{ folder }}
{{ file.name }}{{ desc.text }}
87 | -------------------------------------------------------------------------------- /dm/data/ann01.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | // Data len 3328 bits 0.4kB 44 | // img/ann_alpha_dith.pnm 208x16 45 | "\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\xe0\x07\xe0\xff\xf1\xff\x8f\xf1\xc3\x8f\xf1\xff\x8f" 46 | "\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\xc0\x03\xc0\xff\xf9\xff\x9f\xf9\xc3\x9f\xf9\xff\x9f" 47 | "\xf3\xff\xff\xcf\xf3\xff\xff\xcf\xf3\xff\xff\xcf\x03\xc0\xc3\xc3\xff\xf9\x81\x9f\xf9\x81\x9f\xf9\xff\x9f" 48 | "\xf9\xff\xf9\x9f\x39\x3c\x78\x9e\xf9\x87\xcf\x9f\x01\x80\x61\x86\xff\xf9\x00\x9f\xf9\x81\x9f\xf9\xff\x9f" 49 | "\xf9\xff\xf9\x9f\x19\x18\x38\x9c\xf9\x33\xcf\x9f\xe1\x87\x31\x8c\xff\x79\x18\x9e\xf9\x99\x9f\xf9\xff\x9f" 50 | "\xf9\xff\xf9\x9f\x99\x99\x19\x98\xf9\x33\xcf\x9f\x31\x8c\x31\x8c\xff\x79\x3c\x9e\xf9\x18\x9f\xf9\xff\x9f" 51 | "\x39\x3c\x38\x9c\xf9\x99\x99\x99\xf9\xf3\x9f\x9f\x31\x80\x31\x8c\xff\x79\xfc\x9f\xf9\x18\x9f\xf9\xff\x9f" 52 | "\x99\x99\x99\x9b\xf9\x39\x98\x99\xf9\xe7\x9f\x9f\x31\x80\x31\x8c\xff\x79\x00\x9f\xf9\x3c\x9f\xf9\xff\x9f" 53 | "\xf9\x99\x99\x9f\xf9\x39\x18\x98\xf9\xcf\x3f\x9f\xf1\x87\xf1\x8f\xff\x79\x00\x9e\x79\x3c\x9e\xf9\xff\x9f" 54 | "\xf9\x99\x19\x9c\xf9\x99\x19\x98\xf9\x9f\x27\x9f\x31\x8c\x31\x8c\xff\x79\x3c\x9c\x79\x00\x9e\xf9\xff\x9f" 55 | "\xf9\x99\x99\x99\x99\x99\x99\x99\xf9\x3f\x03\x9f\x31\x8c\x31\x8c\xff\x79\x7c\x9c\x79\x00\x9e\xf9\xff\x9f" 56 | "\x99\x99\x99\x99\x19\x18\x98\x99\xf9\x3f\xe7\x9f\x71\x8c\x31\x8c\xff\x79\x7c\x9c\x39\x7e\x9c\xf9\xff\x9f" 57 | "\x39\x3c\x5a\x9c\x39\x3c\x98\x99\xf9\x03\xe7\x9f\xb1\x87\x31\x8c\xff\x79\x30\x9c\x39\x7e\x9c\xf9\xff\x9f" 58 | "\xf3\xff\xff\xcf\xf3\xff\xff\xcf\xf3\xff\xff\xcf\x03\xc0\x33\xcc\xff\x39\x02\x9e\x39\x7e\x9c\xf9\xff\x9f" 59 | "\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\x00\x00\xc0\x03\xc0\x03\xc0\xff\x39\x07\x9f\x19\xff\x98\xf9\xff\x9f" 60 | "\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\x00\x00\xe0\x07\xe0\x07\xe0\xff\xf1\xff\x8f\x11\xff\x88\xf1\xff\x8f" 61 | -------------------------------------------------------------------------------- /dmcp/sys/sdb.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2018, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __SYS_SDB_H__ 44 | #define __SYS_SDB_H__ 45 | 46 | // === IFC START === 47 | // System data block 48 | 49 | typedef int get_flag_fn_t(); 50 | typedef void set_flag_fn_t(int val); 51 | 52 | typedef int run_menu_item_fn_t(uint8_t line_id); 53 | typedef const char * menu_line_str_fn_t(uint8_t line_id, char * s, const int slen); 54 | 55 | typedef void void_fn_t(); 56 | 57 | 58 | typedef struct { 59 | volatile uint32_t calc_state; 60 | FIL * ppgm_fp; 61 | const char * key_to_alpha_table; 62 | 63 | run_menu_item_fn_t * run_menu_item_app; 64 | menu_line_str_fn_t * menu_line_str_app; 65 | 66 | void_fn_t * after_fat_format; 67 | 68 | get_flag_fn_t * is_flag_dmy; 69 | set_flag_fn_t * set_flag_dmy; 70 | get_flag_fn_t * is_flag_clk24; 71 | set_flag_fn_t * set_flag_clk24; 72 | get_flag_fn_t * is_beep_mute; 73 | set_flag_fn_t * set_beep_mute; 74 | 75 | disp_stat_t * pds_t20; 76 | disp_stat_t * pds_t24; 77 | disp_stat_t * pds_fReg; 78 | 79 | } sys_sdb_t; 80 | 81 | 82 | #define calc_state (sdb.calc_state) 83 | #define ppgm_fp (sdb.ppgm_fp) 84 | 85 | #define key_to_alpha_table (sdb.key_to_alpha_table) 86 | 87 | #define run_menu_item_app (sdb.run_menu_item_app) 88 | #define menu_line_str_app (sdb.menu_line_str_app) 89 | 90 | #define after_fat_format (sdb.after_fat_format) 91 | 92 | #define is_flag_dmy (sdb.is_flag_dmy) 93 | #define set_flag_dmy (sdb.set_flag_dmy) 94 | #define is_flag_clk24 (sdb.is_flag_clk24) 95 | #define set_flag_clk24 (sdb.set_flag_clk24) 96 | #define is_beep_mute (sdb.is_beep_mute) 97 | #define set_beep_mute (sdb.set_beep_mute) 98 | 99 | // === IFC END === 100 | 101 | 102 | extern sys_sdb_t sdb; 103 | 104 | #if 0 105 | // === IFC START === 106 | 107 | #define t20 (sdb.pds_t20) 108 | #define t24 (sdb.pds_t24) 109 | #define fReg (sdb.pds_fReg) 110 | 111 | #define sdb (*((sys_sdb_t*)0x10002000)) 112 | 113 | // === IFC END === 114 | #endif 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /dm/data/ann00.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | // Data len 4096 bits 0.5kB 44 | // img/ann_new.pnm 256x16 45 | "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdf\xff\xf7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" 46 | "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xff\xe7\xff\xff\xff\x03\xfe\xff\xfb\xff\xff\xff\xff\xf9\x00\xc0" 47 | "\xff\xff\xff\xff\xff\x1f\xf8\xfc\x80\x07\xff\x01\x00\x00\xf8\xcf\xff\xe7\xff\xff\x3f\x00\xf8\xff\xf1\xff\xff\xff\xff\xf9\x00\xc0" 48 | "\xff\xff\xff\xff\xff\x0f\x78\x78\x80\x03\xfe\x00\x00\x00\xf0\xe7\x7d\xcf\xff\xff\x03\x00\xf0\xff\xe0\xff\xff\xff\xff\xf0\x01\xe0" 49 | "\xff\xff\xff\xff\xff\xcf\x79\x78\x9e\x71\xfc\xfc\xff\xff\xf3\xe7\x7c\xce\xff\x7f\x00\x00\xe0\x7f\xc0\xff\xff\xff\xff\xf0\x03\xe0" 50 | "\xff\xff\xff\xff\xff\xc7\x79\x78\x9e\xf9\xfc\xfc\xff\xff\x83\x67\xfe\xcc\xff\x07\x00\x00\xc0\x3f\x80\xff\xff\xff\x7f\xe0\x03\xf0" 51 | "\xff\xff\xff\xff\xff\xe7\x39\x73\x9e\xff\xfc\xfc\xff\xff\x07\x73\xc6\x9c\x7f\x00\x00\x00\xc0\x1f\x00\xff\xff\xff\x7f\xc0\x07\xf0" 52 | "\xff\xff\xff\xff\xff\xe7\x39\x73\x9c\xff\xfc\xfc\xff\xff\x3f\x33\x83\x99\x1f\x00\x00\x00\x80\x0f\x00\xfe\xff\xff\x7f\xc0\x07\xf8" 53 | "\xff\xff\xff\xff\xff\xe7\x39\xf3\x80\xc1\xfc\xfc\xff\xff\x3f\x33\x83\x99\x0f\x00\x00\x00\x80\x0f\x00\xfe\xff\xff\x3f\xc0\x07\xf8" 54 | "\xff\xff\xff\xff\xff\xe7\x19\xe0\x81\xc1\xfc\xfc\xff\xff\x3f\x33\x83\x99\x07\x00\x00\x00\x80\xff\xe0\xff\xff\xff\x3f\x80\x0f\xfc" 55 | "\xff\xff\xff\xff\xff\xcf\x19\xe0\x98\xf9\xfc\xfc\xff\xff\x07\x63\xc6\x8c\x07\xa8\xaa\x02\xc0\xff\xe0\xff\xff\xff\x1f\x80\x0f\xfc" 56 | "\xff\xff\xff\xff\xff\xcf\x99\x67\x9c\x71\xfc\xfc\xff\xff\x83\x67\xfe\xcc\x07\xf8\xff\x07\xc0\xff\x00\x00\x00\xf0\x1f\x00\x1f\xfe" 57 | "\xff\xff\xff\xff\xff\x0f\x88\x4f\x9e\x03\xfe\xfc\xff\xff\xf3\xe7\x7c\xce\xff\xaf\xaa\x0e\xe0\xff\x00\x00\x00\xf0\x0f\x00\x1f\xfe" 58 | "\xff\xff\xff\xff\xff\x1f\xc8\x4f\x9e\x07\xff\x00\x00\x00\xf0\xcf\x7d\xe7\xff\x07\x00\x1c\xf8\xff\x00\x00\x00\xf0\x0f\x00\x3e\xff" 59 | "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\xf8\xcf\xff\xe7\x03\x00\x00\x78\xfd\xff\x00\x00\x00\xf0\x07\x00\x3e\xff" 60 | "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdf\xff\xf7\xff\xff\xff\xfd\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" 61 | -------------------------------------------------------------------------------- /dm/data/ann02.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | // Data len 4096 bits 0.5kB 44 | // img/ann_power.pnm 256x16 45 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 46 | "\xe0\x01\x00\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\x00\x30\x00\x00" 47 | "\x50\x03\x80\x1d\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\x00\xf8\x0f\x00" 48 | "\x30\x06\xc0\x08\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x00\xf8\x1f\x00" 49 | "\x20\x1c\x70\x18\x30\x00\x00\x18\x30\x00\x80\x1b\x30\x00\xb8\x1b\x30\x80\xbb\x1b\x30\xb8\xbb\x1b\xb0\xbb\xbb\x1b\x00\x30\x38\x00" 50 | "\x14\xf8\x3c\x10\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\x08\x00\x70\x00" 51 | "\x2a\xc0\x0f\x18\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\x0c\x00\xe0\x1c" 52 | "\x14\x00\x00\x08\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\xfe\xff\xff\x3f" 53 | "\x2a\x00\x00\x18\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\xff\xff\xff\x3f" 54 | "\x14\x00\x00\x10\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\xfe\xff\xff\x3f" 55 | "\x2a\xc0\x0f\x18\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\x0c\x00\x1c\x1c" 56 | "\x14\xf8\x3c\x08\x3e\x00\x00\x18\x3e\x00\x80\x1b\x3e\x00\xb8\x1b\x3e\x80\xbb\x1b\x3e\xb8\xbb\x1b\xbe\xbb\xbb\x1b\x08\x00\x0e\x00" 57 | "\x20\x1c\x70\x18\x30\x00\x00\x18\x30\x00\x80\x1b\x30\x00\xb8\x1b\x30\x80\xbb\x1b\x30\xb8\xbb\x1b\xb0\xbb\xbb\x1b\x80\x07\x07\x00" 58 | "\x30\x06\xc0\x10\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x30\x00\x00\x18\x80\xff\x03\x00" 59 | "\x70\x03\x80\x1d\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\xf0\xff\xff\x1f\x80\xff\x01\x00" 60 | "\xe0\x01\x00\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\xe0\xff\xff\x0f\x80\x07\x00\x00" 61 | -------------------------------------------------------------------------------- /dm/data/ann03.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | // Data len 4096 bits 0.5kB 44 | // img/ann_flags.pnm 256x16 45 | "\xff\xff\xff\xff\xff\xff\xff\xff\x3f\x00\x7e\x00\xfc\x00\xf8\x01\xf0\x03\xe0\x07\xc0\x0f\x80\x1f\x00\x3f\x00\x7e\x00\xfc\x00\xf8" 46 | "\xff\xff\xff\xff\xff\xff\xff\xff\x1f\xc7\x3c\x7c\x78\xf8\xf0\xfc\xe7\xe1\xc1\xe3\x8f\x87\x01\x0f\x3f\x1e\x7e\x3c\x38\x78\xf8\xf0" 47 | "\xff\xff\xff\xff\xff\xff\xff\xff\x9f\xcf\x3c\xfe\x78\xfc\xf1\xfc\xe7\xf1\xc3\xe3\x8f\x87\x03\x8f\x7f\x1e\xff\x3c\xf8\x78\xfc\xf1" 48 | "\xff\xff\xff\xff\xff\xff\xff\xff\x8f\xcd\x19\xc6\x31\x8e\x63\x18\xc0\x10\x87\x01\x0c\x83\x03\xc6\x41\x8c\x83\x18\xd8\x30\x8c\xe1" 49 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x19\x83\x31\x06\x63\x18\xc0\x00\x8e\x01\x0c\x83\x05\xc6\x00\x8c\x01\x18\x18\x30\x06\xe3" 50 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\x83\x31\x06\x63\x18\xc0\x00\x8c\x01\x0c\x83\x05\xc6\x00\x8c\x01\x18\x18\x30\x06\xe3" 51 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\x83\x31\x8c\x61\x30\xc0\xe0\x8d\xc1\x0f\x83\x09\x86\x01\x8c\x01\x18\x18\x30\x06\xe3" 52 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\xc7\x31\xf8\x60\x30\xc0\xf0\x8f\xe1\x0f\x83\x19\x06\x1f\x8c\x03\x18\x18\x30\x06\xe3" 53 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\xff\x30\xfc\x61\x70\xc0\x38\x8e\x71\x08\x83\x11\x86\x1f\x0c\x07\x18\x18\x30\x06\xe3" 54 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\x7b\x30\x8e\x63\x60\xc0\x18\x8c\x31\x00\x83\x31\xc6\x01\x0c\x0e\x18\x18\x30\x06\xe3" 55 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\x03\x30\x06\x63\x60\xc0\x18\x8c\x31\x00\xe3\x3f\xc6\x00\x0c\x1c\x18\x18\x30\x06\xe3" 56 | "\xff\xff\xff\xff\xff\xff\xff\xff\xcf\xd8\x18\x07\x30\x06\x63\xc0\xc0\x18\x8c\x31\x00\xe3\x3f\xc6\x00\x0c\x30\x18\x18\x30\x06\xe3" 57 | "\xff\xff\xff\xff\xff\xff\xff\xff\x8f\xcd\x18\x8e\x30\x8e\x63\xc0\xc0\x38\x86\x71\x10\x83\x01\xc6\x41\x0c\x60\x18\x18\x30\x8c\xe1" 58 | "\xff\xff\xff\xff\xff\xff\xff\xff\x9f\xcf\x3c\xfc\x78\xfc\xf1\xc0\xe0\xf1\xc7\xe3\x9f\x87\x01\x8f\x7f\x9e\xff\x3c\xff\x78\xfc\xf1" 59 | "\xff\xff\xff\xff\xff\xff\xff\xff\x1f\xc7\x3c\x78\x78\xf8\xf0\x80\xe1\xe1\xc3\xc3\x8f\x87\x01\x0f\x3f\x9e\xff\x3c\xff\x78\xf8\xf0" 60 | "\xff\xff\xff\xff\xff\xff\xff\xff\x3f\x00\x7e\x00\xfc\x00\xf8\x01\xf0\x03\xe0\x07\xc0\x0f\x80\x1f\x00\x3f\x00\x7e\x00\xfc\x00\xf8" 61 | -------------------------------------------------------------------------------- /dmcp/sys/pgm_syscalls.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | 55 | #include 56 | #include 57 | 58 | void Program_Entry(); 59 | 60 | #ifndef PROGRAM_KEYMAP_ID 61 | #define PROGRAM_KEYMAP_ID 0xffffffff 62 | #endif 63 | 64 | prog_info_t const prog_info = { 65 | PROG_INFO_MAGIC, // uint32_t pgm_magic; 66 | 0, // uint32_t pgm_size; 67 | (void*)Program_Entry, // void * pgm_entry; 68 | PLATFORM_IFC_CNR, // uint32_t ifc_cnr; 69 | PLATFORM_IFC_VER, // uint32_t ifc_ver; 70 | QSPI_DATA_SIZE, // uint32_t qspi_size; 71 | QSPI_DATA_CRC, // uint32_t qspi_crc; 72 | PROGRAM_NAME, // char pgm_name[16]; 73 | PROGRAM_VERSION, // char pgm_version[16]; 74 | PROGRAM_KEYMAP_ID // uint32_t required_keymap_id; 75 | }; 76 | 77 | 78 | 79 | int _read(int file, char *ptr, int len) 80 | { 81 | return len; 82 | } 83 | 84 | 85 | int _write(int file, char *ptr, int len) 86 | { 87 | // Routed to OS, where it is printed to ITM 88 | #ifdef USER_WRITE 89 | return USER_WRITE(file, ptr, len); 90 | #else 91 | return __sysfn__write(file, ptr, len); 92 | #endif 93 | } 94 | 95 | 96 | int _close(int file) 97 | { 98 | return -1; 99 | } 100 | 101 | 102 | int _fstat(int file, struct stat *st) 103 | { 104 | st->st_mode = S_IFCHR; 105 | return 0; 106 | } 107 | 108 | int _isatty(int file) 109 | { 110 | return 1; 111 | } 112 | 113 | int _lseek(int file, int ptr, int dir) 114 | { 115 | return 0; 116 | } 117 | 118 | int _kill(int pid, int sig) 119 | { 120 | errno = EINVAL; 121 | return -1; 122 | } 123 | 124 | int _getpid(void) 125 | { 126 | return 1; 127 | } 128 | 129 | 130 | 131 | // Remove any debug substitutions 132 | 133 | #ifdef malloc 134 | #undef malloc 135 | #endif 136 | 137 | #ifdef free 138 | #undef free 139 | #endif 140 | 141 | #ifdef calloc 142 | #undef calloc 143 | #endif 144 | 145 | #ifdef realloc 146 | #undef realloc 147 | #endif 148 | 149 | 150 | void free(void *ptr) { 151 | __sysfn_free(ptr); 152 | } 153 | 154 | 155 | void *malloc(size_t size) { 156 | return __sysfn_malloc(size); 157 | } 158 | 159 | 160 | void *calloc(size_t count, size_t nbytes) { 161 | return __sysfn_calloc(count, nbytes); 162 | } 163 | 164 | void *realloc(void *ptr, size_t size) { 165 | return __sysfn_realloc(ptr, size); 166 | } 167 | 168 | 169 | 170 | void * __wrap__malloc_r (struct _reent *pr, size_t size) { 171 | return malloc(size); 172 | } 173 | 174 | void * _calloc_r (struct _reent *pr, size_t nmemb, size_t size) { 175 | return calloc(nmemb, size); 176 | } 177 | 178 | void * _realloc_r (struct _reent *pr, void *ptr, size_t size) { 179 | return realloc(ptr, size); 180 | } 181 | 182 | void _free_r (struct _reent *pr, void *ptr) { 183 | free(ptr); 184 | } 185 | 186 | 187 | void post_main() { 188 | // Just start DMCP 189 | set_reset_magic(RUN_DMCP_MAGIC); 190 | sys_reset(); 191 | } 192 | 193 | -------------------------------------------------------------------------------- /stm32_program.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ***************************************************************************** 3 | ** 4 | 5 | ** File : stm32_flash.ld 6 | ** 7 | ** Abstract : Linker script for STM32L476ZG Device with 8 | ** 1024KByte FLASH, 96KByte RAM 9 | ** 10 | ** Set heap size, stack size and stack location according 11 | ** to application requirements. 12 | ** 13 | ** Set memory bank area and size if external memory is used. 14 | ** 15 | ** Target : STMicroelectronics STM32 16 | ** 17 | ** 18 | ** Distribution: The file is distributed as is, without any warranty 19 | ** of any kind. 20 | ** 21 | ** Swissmicros - ld script for STM32 + QSPI 22 | ** 23 | ***************************************************************************** 24 | */ 25 | 26 | /* Specify the memory areas */ 27 | MEMORY 28 | { 29 | /* FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K */ 30 | /* RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K */ 31 | /* RAM0 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K-256 */ 32 | FLASH (rx) : ORIGIN = 0x8050000, LENGTH = 704K 33 | RAM (xrw) : ORIGIN = 0x10000000, LENGTH = 8K 34 | QSPI (rx) : ORIGIN = 0x90000000, LENGTH = 2048K 35 | } 36 | 37 | /* Entry Point */ 38 | ENTRY(Program_Entry) 39 | 40 | 41 | /* Define output sections */ 42 | SECTIONS 43 | { 44 | 45 | .qspi : 46 | { 47 | . = ALIGN(8); 48 | _qspi_start = .; /* create a global symbol at qspi start */ 49 | *(.qspi) /* .qspi sections */ 50 | *(.qspi*) /* .qspi* sections */ 51 | /* ==== Symbols to QSPI - in direct order === */ 52 | *(.rodata.__bid_mod10_18_tbl) 53 | *(.rodata.__bid_convert_table) 54 | *(.rodata.bid_log_table_1) 55 | *(.rodata.bid_log_table_2) 56 | *(.rodata.bid_decimal128_moduli) 57 | *(.rodata.bid_exponents_bid64) 58 | *(.rodata.bid_exponents_binary128) 59 | *(.rodata.bid_breakpoints_binary128) 60 | *(.rodata.bid_breakpoints_bid64) 61 | *(.rodata.bid_multipliers1_binary128) 62 | *(.rodata.bid_multipliers2_bid64) 63 | *(.rodata.bid_multipliers1_bid64) 64 | *(.rodata.bid_multipliers2_binary128) 65 | /* ======================== */ 66 | . = ALIGN(8); 67 | _qspi_end = .; /* define a global symbols at end of qspi */ 68 | 69 | } >QSPI /* AT> FLASH */ 70 | 71 | /* Constant data goes into FLASH */ 72 | .rodata : 73 | { 74 | KEEP(*(.rodata.prog_info)) /* Program info */ 75 | . = ALIGN(64); 76 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 77 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 78 | . = ALIGN(8); 79 | } >FLASH 80 | 81 | _qspi_init_base = LOADADDR(.qspi); 82 | _qspi_init_length = SIZEOF(.qspi); 83 | 84 | /* The program code and other data goes into FLASH */ 85 | .text : 86 | { 87 | . = ALIGN(8); 88 | *(.text) /* .text sections (code) */ 89 | *(.text*) /* .text* sections (code) */ 90 | *(.glue_7) /* glue arm to thumb code */ 91 | *(.glue_7t) /* glue thumb to arm code */ 92 | *(.eh_frame) 93 | 94 | KEEP (*(.init)) 95 | KEEP (*(.fini)) 96 | 97 | . = ALIGN(8); 98 | _etext = .; /* define a global symbols at end of code */ 99 | } >FLASH 100 | 101 | .ARM.extab : 102 | { 103 | . = ALIGN(8); 104 | *(.ARM.extab* .gnu.linkonce.armextab.*) 105 | . = ALIGN(8); 106 | } >FLASH 107 | .ARM : { 108 | . = ALIGN(8); 109 | __exidx_start = .; 110 | *(.ARM.exidx*) 111 | __exidx_end = .; 112 | . = ALIGN(8); 113 | } >FLASH 114 | 115 | .preinit_array : 116 | { 117 | . = ALIGN(8); 118 | PROVIDE_HIDDEN (__preinit_array_start = .); 119 | KEEP (*(.preinit_array*)) 120 | PROVIDE_HIDDEN (__preinit_array_end = .); 121 | . = ALIGN(8); 122 | } >FLASH 123 | 124 | .init_array : 125 | { 126 | . = ALIGN(8); 127 | PROVIDE_HIDDEN (__init_array_start = .); 128 | KEEP (*(SORT(.init_array.*))) 129 | KEEP (*(.init_array*)) 130 | PROVIDE_HIDDEN (__init_array_end = .); 131 | . = ALIGN(8); 132 | } >FLASH 133 | .fini_array : 134 | { 135 | . = ALIGN(8); 136 | PROVIDE_HIDDEN (__fini_array_start = .); 137 | KEEP (*(SORT(.fini_array.*))) 138 | KEEP (*(.fini_array*)) 139 | PROVIDE_HIDDEN (__fini_array_end = .); 140 | . = ALIGN(8); 141 | } >FLASH 142 | 143 | /* used by the startup to initialize data */ 144 | _sidata = LOADADDR(.data); 145 | 146 | /* Initialized data sections goes into RAM, load LMA copy after code */ 147 | .data : 148 | { 149 | . = ALIGN(8); 150 | _sdata = .; /* create a global symbol at data start */ 151 | *(.data.sdb) /* SDB at the beginning of the RAM0 */ 152 | *(.data) /* .data sections */ 153 | *(.data*) /* .data* sections */ 154 | 155 | . = ALIGN(8); 156 | _edata = .; /* define a global symbol at data end */ 157 | } >RAM AT> FLASH 158 | 159 | /* Uninitialized data section */ 160 | . = ALIGN(4); 161 | .bss : 162 | { 163 | /* This is used by the startup in order to initialize the .bss secion */ 164 | _sbss = .; /* define a global symbol at bss start */ 165 | __bss_start__ = _sbss; 166 | *(.bss) 167 | *(.bss*) 168 | *(COMMON) 169 | 170 | . = ALIGN(4); 171 | _ebss = .; /* define a global symbol at bss end */ 172 | __bss_end__ = _ebss; 173 | } >RAM AT> RAM 174 | 175 | /* Remove information from the standard libraries */ 176 | /DISCARD/ : 177 | { 178 | libc.a ( * ) 179 | libm.a ( * ) 180 | libgcc.a ( * ) 181 | } 182 | 183 | .ARM.attributes 0 : { *(.ARM.attributes) } 184 | } 185 | 186 | 187 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ###################################### 2 | # target 3 | ###################################### 4 | TARGET = DM42PGM 5 | 6 | ###################################### 7 | # building variables 8 | ###################################### 9 | # debug build? 10 | ifdef DEBUG 11 | DEBUG = 1 12 | endif 13 | 14 | # DMCP5 build 15 | ifdef DMCP5 16 | PGMEXT=pg5 17 | else 18 | PGMEXT=pgm 19 | endif 20 | 21 | ####################################### 22 | # pathes 23 | ####################################### 24 | # Build path 25 | BUILD_DIR = build 26 | # Free42 header files 27 | FREE42DIR = free42 28 | 29 | # Path to aux build scripts (including trailing /) 30 | # Leave empty for scripts in PATH 31 | BIN_DIR = bin/ 32 | 33 | ###################################### 34 | # System sources 35 | ###################################### 36 | C_INCLUDES += -Idmcp 37 | C_SOURCES += dmcp/sys/pgm_syscalls.c 38 | ASM_SOURCES = dmcp/startup_pgm.s 39 | 40 | ####################################### 41 | # Custom section 42 | ####################################### 43 | 44 | # Includes 45 | C_INCLUDES += -Idm 46 | 47 | # Free42 frontend 48 | CXX_SOURCES += dm/dm42_fns.cc 49 | CXX_SOURCES += dm/dm42_menu.cc 50 | C_DEFS += -DARM -DDM42 51 | C_DEFS += -DDECIMAL_CALL_BY_REFERENCE=1 -DDECIMAL_GLOBAL_ROUNDING=1 \ 52 | -DDECIMAL_GLOBAL_ROUNDING_ACCESS_FUNCTIONS=1 -DDECIMAL_GLOBAL_EXCEPTION_FLAGS=1 \ 53 | -DDECIMAL_GLOBAL_EXCEPTION_FLAGS_ACCESS_FUNCTIONS=1 \ 54 | -DBCD_MATH 55 | C_INCLUDES += -I$(FREE42DIR) 56 | 57 | # Free42 libraries 58 | ifeq ($(DEBUG), 1) 59 | LIBS += lib/libfree42_bcd.a lib/gcc111libbid_hard.a 60 | else 61 | LIBS += lib/libfree42_bcd_rel.a lib/gcc111libbid_hard.a 62 | endif 63 | 64 | # --- 65 | 66 | 67 | ####################################### 68 | # binaries 69 | ####################################### 70 | CC = arm-none-eabi-gcc 71 | CXX = arm-none-eabi-g++ 72 | AS = arm-none-eabi-gcc -x assembler-with-cpp 73 | OBJCOPY = arm-none-eabi-objcopy 74 | AR = arm-none-eabi-ar 75 | SIZE = arm-none-eabi-size 76 | HEX = $(OBJCOPY) -O ihex 77 | BIN = $(OBJCOPY) -O binary -S 78 | 79 | ####################################### 80 | # CFLAGS 81 | ####################################### 82 | # macros for gcc 83 | AS_DEFS = 84 | C_DEFS += -D__weak="__attribute__((weak))" -D__packed="__attribute__((__packed__))" 85 | AS_INCLUDES = 86 | 87 | 88 | CPUFLAGS += -mthumb -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 89 | 90 | 91 | # compile gcc flags 92 | ASFLAGS = $(CPUFLAGS) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 93 | CFLAGS += $(CPUFLAGS) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 94 | CFLAGS += -Wno-misleading-indentation -Wno-unknown-pragmas 95 | DBGFLAGS = -g 96 | 97 | ifeq ($(DEBUG), 1) 98 | CFLAGS += -O0 99 | else 100 | CFLAGS += -Os -DFW_RELEASE 101 | endif 102 | 103 | CFLAGS += $(DBGFLAGS) 104 | LDFLAGS += $(DBGFLAGS) 105 | 106 | # Generate dependency information 107 | CFLAGS += -MD -MP -MF .dep/$(@F).d 108 | 109 | ####################################### 110 | # LDFLAGS 111 | ####################################### 112 | # link script 113 | LDSCRIPT = stm32_program.ld 114 | # libraries 115 | #LIBS = -lc -lm -lnosys 116 | LIBDIR = 117 | LDFLAGS += $(CPUFLAGS) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref 118 | LDFLAGS += -specs=nano.specs 119 | LDFLAGS += -Wl,--gc-sections -Wl,--wrap=_malloc_r 120 | 121 | 122 | # default action: build all 123 | all: $(BUILD_DIR)/$(TARGET).elf 124 | 125 | ####################################### 126 | # build the application 127 | ####################################### 128 | # list of objects 129 | OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) 130 | vpath %.c $(sort $(dir $(C_SOURCES))) 131 | # C++ sources 132 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CXX_SOURCES:.cc=.o))) 133 | vpath %.cc $(sort $(dir $(CXX_SOURCES))) 134 | # list of ASM program objects 135 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) 136 | vpath %.s $(sort $(dir $(ASM_SOURCES))) 137 | 138 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 139 | 140 | $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 141 | $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ 142 | 143 | $(BUILD_DIR)/%.o: %.cc Makefile | $(BUILD_DIR) 144 | $(CXX) -c $(CXXFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cc=.lst)) $< -o $@ 145 | 146 | $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) 147 | $(AS) -c $(CFLAGS) $< -o $@ 148 | 149 | $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile 150 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@ 151 | $(OBJCOPY) --remove-section .qspi -O ihex $@ $(BUILD_DIR)/$(TARGET)_flash.hex 152 | $(OBJCOPY) --remove-section .qspi -O binary $@ $(BUILD_DIR)/$(TARGET)_flash.bin 153 | $(OBJCOPY) --only-section .qspi -O ihex $@ $(BUILD_DIR)/$(TARGET)_qspi.hex 154 | $(OBJCOPY) --only-section .qspi -O binary $@ $(BUILD_DIR)/$(TARGET)_qspi.bin 155 | $(BIN_DIR)check_qspi_crc $(TARGET) dm/qspi_crc.h || ( $(MAKE) clean && false ) 156 | $(BIN_DIR)add_pgm_chsum build/$(TARGET)_flash.bin build/$(TARGET).$(PGMEXT) 157 | $(SIZE) $@ 158 | 159 | $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 160 | $(HEX) $< $@ 161 | 162 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 163 | $(BIN) $< $@ 164 | 165 | $(BUILD_DIR): 166 | mkdir -p $@ 167 | 168 | ####################################### 169 | # clean up 170 | ####################################### 171 | clean: 172 | -rm -fR .dep $(BUILD_DIR)/*.o $(BUILD_DIR)/*.lst 173 | 174 | ####################################### 175 | # dependencies 176 | ####################################### 177 | -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) 178 | 179 | .PHONY: clean all 180 | 181 | # *** EOF *** 182 | -------------------------------------------------------------------------------- /dm/dm42_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __DM42_MENU_H__ 44 | #define __DM42_MENU_H__ 45 | 46 | 47 | extern const smenu_t MID_MENU; // Main setup menu 48 | extern const smenu_t MID_FILE; // File menu 49 | extern const smenu_t MID_PRINT; // Print to file menu 50 | extern const smenu_t MID_STACK_CONFIG; // Stack config menu 51 | extern const smenu_t MID_STATEFILE; // State file load/save 52 | extern const smenu_t MID_TOPBAR; // Top bar config 53 | extern const smenu_t MID_STACK_AREA; // Stack area config 54 | 55 | 56 | // -------------------------------- 57 | // Menu items 58 | // app range 0-127 59 | // sys range 128-255 60 | // -------------------------------- 61 | 62 | // DM42 app MI's 63 | 64 | #define MI_LOAD_PGM 28 65 | #define MI_SAVE_PGM 29 66 | #define MI_SAVE_STAT 30 67 | #define MI_FILE 31 68 | #define MI_CLEAN_RESET 32 69 | 70 | #define MI_STACK_CONFIG 33 71 | #define MI_STACK_XYZTL 34 72 | #define MI_STACK_XYZTA 35 73 | #define MI_STACK_XYZT 36 74 | #define MI_STACK_XYL 37 75 | #define MI_STACK_XYA 38 76 | #define MI_STACK_XY 39 77 | #define MI_STACK_LXYZT 40 78 | 79 | #define MI_STATEFILE 41 80 | #define MI_LOAD_STATE 42 81 | #define MI_SAVE_STATE 43 82 | 83 | 84 | #define MI_DISP_STATFN 44 85 | #define MI_DISP_DOW 45 86 | #define MI_DISP_DATE 46 87 | #define MI_DISP_DATE_SEP 47 88 | #define MI_DISP_SHORTMON 48 89 | #define MI_DISP_TIME 49 90 | #define MI_DISP_VOLTAGE 50 91 | 92 | #define MI_SETTINGS 51 93 | #define MI_ABOUT_PGM 52 94 | 95 | #define MI_STACK_AREA 53 96 | #define MI_SA_REG_X 54 97 | #define MI_SA_REG_Y 55 98 | #define MI_SA_REG_Z 56 99 | #define MI_SA_REG_T 57 100 | #define MI_SA_REG_L 58 101 | #define MI_SA_REG_A 59 102 | 103 | #define MI_TOPBAR_MENU 60 104 | 105 | #define MI_PRINT_MENU 61 106 | #define MI_PRTOF_GRAPH 62 107 | #define MI_PRTOF_TEXT 63 108 | #define MI_PRTOF_GR_IN_TXT 64 109 | #define MI_PRTOF_NOIR 65 110 | #define MI_PRINT_DBLNL 66 111 | 112 | #define MI_DYNSTACKEXT 67 113 | //#define MI_DYNSTACK_MENU 68 114 | #define MI_F42CONF_MENU 69 115 | #define MI_F42C_MXSING 70 116 | #define MI_F42C_MXOVFL 71 117 | 118 | #define MI_DEVEL_TEST 77 119 | 120 | // -------------------------------- 121 | 122 | #define MRET_SAVESTATE 777 123 | 124 | // -------------------------------- 125 | 126 | 127 | #define DISP_LOADING_STATE 100 128 | #define DISP_SAVING_STATE 101 129 | #define DISP_SAVE_FAILED 102 130 | #define DISP_ALLOC_FAIL 103 131 | #define DISP_NO_PGM_SEL 104 132 | #define DISP_PRBUF_ALLOC_FAIL 105 133 | #define DISP_NEW_HELP 106 134 | 135 | int lcd_for_dm42(int what); 136 | 137 | // Menu functions 138 | const char * menu_line_str(uint8_t line_id, char * s, const int slen); 139 | int run_menu_item(uint8_t line_id); 140 | 141 | // After FAT format callback 142 | void after_fat_format_dm42(); 143 | 144 | // Start help 145 | void start_help(); 146 | 147 | // Filesystem function wrapper 148 | void init_sf_buf(); 149 | void deinit_sf_buf(); 150 | 151 | // Devel test 152 | void devel_test(); 153 | 154 | 155 | // Program import/export 156 | int pgm_import_enter(const char * fpath, const char * fname, void * data); 157 | int pgm_export_enter(const char * fpath, const char * fname, void * data); 158 | 159 | void run_reset_state_file(); 160 | int load_statefile(const char * fpath, const char * fname, void * data); 161 | 162 | int select_programs(const char * title, int * pgm_indices, int * pgm_cnt); 163 | void pgm_export(); 164 | 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /dmcp/ff_ifc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __FF_IFC_H__ 44 | #define __FF_IFC_H__ 45 | 46 | 47 | 48 | /* These types MUST be 16-bit or 32-bit */ 49 | typedef int INT; 50 | typedef unsigned int UINT; 51 | 52 | /* This type MUST be 8-bit */ 53 | typedef unsigned char BYTE; 54 | 55 | /* These types MUST be 16-bit */ 56 | typedef short SHORT; 57 | typedef unsigned short WORD; 58 | typedef unsigned short WCHAR; 59 | 60 | /* These types MUST be 32-bit */ 61 | typedef long LONG; 62 | typedef unsigned long DWORD; 63 | 64 | /* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */ 65 | typedef unsigned long long QWORD; 66 | 67 | typedef char TCHAR; 68 | #define _T(x) x 69 | #define _TEXT(x) x 70 | 71 | typedef DWORD FSIZE_t; 72 | 73 | typedef struct __FATFS FATFS; 74 | 75 | 76 | typedef struct { 77 | FATFS* fs; 78 | WORD id; 79 | BYTE attr; 80 | BYTE stat; 81 | DWORD sclust; 82 | FSIZE_t objsize; 83 | UINT lockid; 84 | } _FDID; 85 | 86 | typedef struct { 87 | _FDID obj; 88 | BYTE flag; 89 | BYTE err; 90 | FSIZE_t fptr; 91 | DWORD clust; 92 | DWORD sect; 93 | DWORD dir_sect; 94 | BYTE* dir_ptr; 95 | DWORD* cltbl; 96 | BYTE buf[512]; 97 | } FIL; 98 | 99 | 100 | /* File access mode and open method flags (3rd argument of f_open) */ 101 | #define FA_READ 0x01 102 | #define FA_WRITE 0x02 103 | #define FA_OPEN_EXISTING 0x00 104 | #define FA_CREATE_NEW 0x04 105 | #define FA_CREATE_ALWAYS 0x08 106 | #define FA_OPEN_ALWAYS 0x10 107 | #define FA_OPEN_APPEND 0x30 108 | 109 | 110 | 111 | /* File function return code (FRESULT) */ 112 | 113 | typedef enum { 114 | FR_OK = 0, /* (0) Succeeded */ 115 | FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ 116 | FR_INT_ERR, /* (2) Assertion failed */ 117 | FR_NOT_READY, /* (3) The physical drive cannot work */ 118 | FR_NO_FILE, /* (4) Could not find the file */ 119 | FR_NO_PATH, /* (5) Could not find the path */ 120 | FR_INVALID_NAME, /* (6) The path name format is invalid */ 121 | FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ 122 | FR_EXIST, /* (8) Access denied due to prohibited access */ 123 | FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ 124 | FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ 125 | FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ 126 | FR_NOT_ENABLED, /* (12) The volume has no work area */ 127 | FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ 128 | FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ 129 | FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ 130 | FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ 131 | FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ 132 | FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */ 133 | FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ 134 | } FRESULT; 135 | 136 | 137 | 138 | FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ 139 | FRESULT f_close (FIL* fp); /* Close an open file object */ 140 | FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ 141 | FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ 142 | FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ 143 | FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ 144 | FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ 145 | 146 | #define f_size(fp) ((fp)->obj.objsize) 147 | #define f_tell(fp) ((fp)->fptr) 148 | #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) 149 | 150 | #ifndef EOF 151 | #define EOF (-1) 152 | #endif 153 | 154 | #endif 155 | -------------------------------------------------------------------------------- /dm/dm42_fns.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __DM42_MAIN_H__ 44 | #define __DM42_MAIN_H__ 45 | 46 | 47 | 48 | // Stack display 49 | 50 | #define LINE_REG_X 0 51 | #define LINE_REG_Y 1 52 | #define LINE_REG_Z 2 53 | #define LINE_REG_T 3 54 | #define LINE_REG_L 4 55 | #define LINE_REG_A 5 56 | 57 | #define STACK_REG_L0 BIT(0) 58 | #define STACK_REG_Y BIT(1) 59 | #define STACK_REG_Z BIT(2) 60 | #define STACK_REG_T BIT(3) 61 | #define STACK_REG_L BIT(4) 62 | #define STACK_REG_A BIT(5) 63 | 64 | 65 | #define STACK_XYZTL (STACK_REG_Y|STACK_REG_Z|STACK_REG_T|STACK_REG_L) 66 | #define STACK_XYZTA (STACK_REG_Y|STACK_REG_Z|STACK_REG_T|STACK_REG_A) 67 | #define STACK_XYZT (STACK_REG_Y|STACK_REG_Z|STACK_REG_T) 68 | #define STACK_XYL (STACK_REG_Y|STACK_REG_L) 69 | #define STACK_XYA (STACK_REG_Y|STACK_REG_A) 70 | #define STACK_XY (STACK_REG_Y) 71 | #define STACK_LXYZT (STACK_REG_L0|STACK_REG_Y|STACK_REG_Z|STACK_REG_T) 72 | 73 | 74 | // LCD update constants 75 | #define LCD_UPD_MAIN 1 76 | #define LCD_UPD_GOOSE 2 77 | #define LCD_UPD_ANN 4 78 | #define LCD_UPD_ALL 7 79 | #define LCD_UPD_DFLT -1 80 | 81 | 82 | // Program load/save 83 | #define PGM_DIR "/PROGRAMS" 84 | #define PGM_EXT ".raw" 85 | #define MAX_PGM_SEL 64 86 | 87 | // Program import/export 88 | typedef struct { 89 | int pgm_cnt; 90 | int pgm_indices[MAX_PGM_SEL]; 91 | } pgm_import_sel_t; 92 | 93 | extern FRESULT pgm_res; 94 | 95 | 96 | // State files dir 97 | #define STATE_DIR "/STATE" 98 | #define STATE_EXT_MASK ".?42" 99 | #define STATE_EXT ".f42" 100 | 101 | 102 | // Print to file dir 103 | #define PRINT_DIR "/PRINTS" 104 | #define PRINT_GR_EXT ".bmp" 105 | #define PRINT_TXT_EXT ".txt" 106 | 107 | 108 | // Graphics backup during off 109 | //#define GR_OFF_IMG SCR_DIR "/GROFFIMG.BMP" 110 | 111 | 112 | 113 | // Top-Bar aka header 114 | #define DISP_STATFN 1 115 | #define DISP_DOW 2 116 | #define DISP_DATE 3 117 | #define DISP_DATE_SEP 4 118 | #define DISP_SHORTMON 5 119 | #define DISP_TIME 6 120 | #define DISP_VOLTAGE 7 121 | 122 | //void toggle_disp_voltage(); 123 | //int is_disp_voltage(); 124 | 125 | void toggle_disp(int what); 126 | int is_disp(int what); 127 | 128 | char get_disp_date_sep(); 129 | 130 | int get_reg_font_offset(int line_reg_nr); 131 | int inc_reg_font_offset(int line_reg_nr); 132 | int set_reg_font_offset(int line_reg_nr, int offs); 133 | 134 | 135 | #define PRTOF_TEXT 0 136 | #define PRTOF_GRAPHICS 1 137 | #define PRTOF_BUF_COUNT 2 138 | 139 | #define PRTOF_GR_IN_TXT 6 140 | #define PRTOF_NOIR 7 141 | #define PRINT_DBLNL 8 142 | 143 | 144 | 145 | int is_print_to_file(int what); 146 | void set_print_to_file(int what, int val, int gui); 147 | 148 | #define PRTOF_LIMIT_FLUSH 0 149 | #define PRTOF_FULL_FLUSH 1 150 | void prtof_buf_flush(int what, int full); 151 | 152 | // -- 153 | 154 | 155 | #define ALPHA_NO_TRANSL '_' 156 | extern const char alpha_upper_transl[]; 157 | 158 | 159 | // State functions 160 | 161 | void set_stack_layout(int layout); 162 | int get_stack_layout(); 163 | char * get_stack_layout_str(char *s, int layout); 164 | 165 | 166 | int get_dynstackext(); 167 | void set_dynstackext(int val); 168 | 169 | int get_f42conf_mxsing(); 170 | void set_f42conf_mxsing(int val); 171 | 172 | int get_f42conf_mxovfl(); 173 | void set_f42conf_mxovfl(int val); 174 | 175 | 176 | void copy_reset_state_filename(char *s, int maxlen); 177 | 178 | // res >= 0 -> OK 179 | int savestat_check_read(const char * state_file_name); 180 | 181 | #define LCD_HEADER_LINES 24 182 | #define LCD_ANN_LINES 16 183 | 184 | // Force to redraw calc LCD 185 | void calc_lcd_redraw(); 186 | 187 | 188 | #define AUX_BUF_PGM_LIST_SIZE (3*512) 189 | #define AUX_BUF_SELS_SIZE (512) 190 | 191 | 192 | #ifndef max 193 | #define max(x,y) ({ \ 194 | __typeof__ (x) _x = (x); \ 195 | __typeof__ (y) _y = (y); \ 196 | _x > _y ? _x : _y; }) 197 | #endif 198 | 199 | #ifndef min 200 | #define min(x,y) ({ \ 201 | __typeof__ (x) _x = (x); \ 202 | __typeof__ (y) _y = (y); \ 203 | _x < _y ? _x : _y; }) 204 | #endif 205 | 206 | #endif 207 | -------------------------------------------------------------------------------- /dmcp/lft_ifc.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #define LIBRARY_FN_BASE 0x08000201 45 | 46 | #define __sysfn_malloc (*(typeof(malloc)*)(LIBRARY_FN_BASE+0)) 47 | #define __sysfn_free (*(typeof(free)*)(LIBRARY_FN_BASE+4)) 48 | #define __sysfn_calloc (*(typeof(calloc)*)(LIBRARY_FN_BASE+8)) 49 | #define __sysfn_realloc (*(typeof(realloc)*)(LIBRARY_FN_BASE+12)) 50 | #define __sysfn__write (*(typeof(_write)*)(LIBRARY_FN_BASE+16)) 51 | #define LCD_clear (*(typeof(LCD_clear)*)(LIBRARY_FN_BASE+20)) 52 | #define LCD_power_on (*(typeof(LCD_power_on)*)(LIBRARY_FN_BASE+24)) 53 | #define LCD_power_off (*(typeof(LCD_power_off)*)(LIBRARY_FN_BASE+28)) 54 | #define LCD_write_line (*(typeof(LCD_write_line)*)(LIBRARY_FN_BASE+32)) 55 | #define bitblt24 (*(typeof(bitblt24)*)(LIBRARY_FN_BASE+36)) 56 | #define lcd_line_addr (*(typeof(lcd_line_addr)*)(LIBRARY_FN_BASE+40)) 57 | #define lcd_clear_buf (*(typeof(lcd_clear_buf)*)(LIBRARY_FN_BASE+44)) 58 | #define lcd_refresh (*(typeof(lcd_refresh)*)(LIBRARY_FN_BASE+48)) 59 | #define lcd_forced_refresh (*(typeof(lcd_forced_refresh)*)(LIBRARY_FN_BASE+52)) 60 | #define lcd_refresh_lines (*(typeof(lcd_refresh_lines)*)(LIBRARY_FN_BASE+56)) 61 | #define lcd_fill_rect (*(typeof(lcd_fill_rect)*)(LIBRARY_FN_BASE+60)) 62 | #define lcd_draw_img (*(typeof(lcd_draw_img)*)(LIBRARY_FN_BASE+64)) 63 | #define lcd_draw_img_direct (*(typeof(lcd_draw_img_direct)*)(LIBRARY_FN_BASE+68)) 64 | #define lcd_draw_img_part (*(typeof(lcd_draw_img_part)*)(LIBRARY_FN_BASE+72)) 65 | #define lcd_fillLine (*(typeof(lcd_fillLine)*)(LIBRARY_FN_BASE+76)) 66 | #define lcd_fillLines (*(typeof(lcd_fillLines)*)(LIBRARY_FN_BASE+80)) 67 | #define lcd_set_buf_cleared (*(typeof(lcd_set_buf_cleared)*)(LIBRARY_FN_BASE+84)) 68 | #define lcd_get_buf_cleared (*(typeof(lcd_get_buf_cleared)*)(LIBRARY_FN_BASE+88)) 69 | #define lcd_writeNl (*(typeof(lcd_writeNl)*)(LIBRARY_FN_BASE+92)) 70 | #define lcd_prevLn (*(typeof(lcd_prevLn)*)(LIBRARY_FN_BASE+96)) 71 | #define lcd_writeClr (*(typeof(lcd_writeClr)*)(LIBRARY_FN_BASE+100)) 72 | #define lcd_setLine (*(typeof(lcd_setLine)*)(LIBRARY_FN_BASE+104)) 73 | #define lcd_setXY (*(typeof(lcd_setXY)*)(LIBRARY_FN_BASE+108)) 74 | #define lcd_lineHeight (*(typeof(lcd_lineHeight)*)(LIBRARY_FN_BASE+112)) 75 | #define lcd_baseHeight (*(typeof(lcd_baseHeight)*)(LIBRARY_FN_BASE+116)) 76 | #define lcd_fontWidth (*(typeof(lcd_fontWidth)*)(LIBRARY_FN_BASE+120)) 77 | #define lcd_writeText (*(typeof(lcd_writeText)*)(LIBRARY_FN_BASE+124)) 78 | #define lcd_textWidth (*(typeof(lcd_textWidth)*)(LIBRARY_FN_BASE+128)) 79 | #define lcd_charWidth (*(typeof(lcd_charWidth)*)(LIBRARY_FN_BASE+132)) 80 | #define lcd_textToWidth (*(typeof(lcd_textToWidth)*)(LIBRARY_FN_BASE+136)) 81 | #define lcd_writeTextWidth (*(typeof(lcd_writeTextWidth)*)(LIBRARY_FN_BASE+140)) 82 | #define lcd_textForWidth (*(typeof(lcd_textForWidth)*)(LIBRARY_FN_BASE+144)) 83 | #define lcd_nextFontNr (*(typeof(lcd_nextFontNr)*)(LIBRARY_FN_BASE+148)) 84 | #define lcd_prevFontNr (*(typeof(lcd_prevFontNr)*)(LIBRARY_FN_BASE+152)) 85 | #define lcd_switchFont (*(typeof(lcd_switchFont)*)(LIBRARY_FN_BASE+156)) 86 | #define lcd_toggleFontT (*(typeof(lcd_toggleFontT)*)(LIBRARY_FN_BASE+160)) 87 | #define lcd_draw_menu_bg (*(typeof(lcd_draw_menu_bg)*)(LIBRARY_FN_BASE+164)) 88 | #define lcd_draw_menu_key (*(typeof(lcd_draw_menu_key)*)(LIBRARY_FN_BASE+168)) 89 | #define lcd_draw_menu_keys (*(typeof(lcd_draw_menu_keys)*)(LIBRARY_FN_BASE+172)) 90 | #define lcd_print (*(typeof(lcd_print)*)(LIBRARY_FN_BASE+176)) 91 | #define lcd_for_calc (*(typeof(lcd_for_calc)*)(LIBRARY_FN_BASE+180)) 92 | #define get_wday_shortcut (*(typeof(get_wday_shortcut)*)(LIBRARY_FN_BASE+184)) 93 | #define get_month_shortcut (*(typeof(get_month_shortcut)*)(LIBRARY_FN_BASE+188)) 94 | #define julian_day (*(typeof(julian_day)*)(LIBRARY_FN_BASE+192)) 95 | #define julian_to_date (*(typeof(julian_to_date)*)(LIBRARY_FN_BASE+196)) 96 | #define get_hw_id (*(typeof(get_hw_id)*)(LIBRARY_FN_BASE+200)) 97 | #define rtc_read (*(typeof(rtc_read)*)(LIBRARY_FN_BASE+204)) 98 | #define rtc_write (*(typeof(rtc_write)*)(LIBRARY_FN_BASE+208)) 99 | #define rtc_read_century (*(typeof(rtc_read_century)*)(LIBRARY_FN_BASE+212)) 100 | #define rtc_write_century (*(typeof(rtc_write_century)*)(LIBRARY_FN_BASE+216)) 101 | #define rtc_read_min (*(typeof(rtc_read_min)*)(LIBRARY_FN_BASE+220)) 102 | #define rtc_read_sec (*(typeof(rtc_read_sec)*)(LIBRARY_FN_BASE+224)) 103 | #define rtc_wakeup_delay (*(typeof(rtc_wakeup_delay)*)(LIBRARY_FN_BASE+228)) 104 | #define read_power_voltage (*(typeof(read_power_voltage)*)(LIBRARY_FN_BASE+232)) 105 | #define get_lowbat_state (*(typeof(get_lowbat_state)*)(LIBRARY_FN_BASE+236)) 106 | #define get_vbat (*(typeof(get_vbat)*)(LIBRARY_FN_BASE+240)) 107 | #define start_buzzer_freq (*(typeof(start_buzzer_freq)*)(LIBRARY_FN_BASE+244)) 108 | #define stop_buzzer (*(typeof(stop_buzzer)*)(LIBRARY_FN_BASE+248)) 109 | #define beep_volume_up (*(typeof(beep_volume_up)*)(LIBRARY_FN_BASE+252)) 110 | #define beep_volume_down (*(typeof(beep_volume_down)*)(LIBRARY_FN_BASE+256)) 111 | #define get_beep_volume (*(typeof(get_beep_volume)*)(LIBRARY_FN_BASE+260)) 112 | #define mark_region (*(typeof(mark_region)*)(LIBRARY_FN_BASE+264)) 113 | #define no_region (*(typeof(no_region)*)(LIBRARY_FN_BASE+268)) 114 | #define set_reset_magic (*(typeof(set_reset_magic)*)(LIBRARY_FN_BASE+272)) 115 | #define is_reset_state_file (*(typeof(is_reset_state_file)*)(LIBRARY_FN_BASE+276)) 116 | #define get_reset_state_file (*(typeof(get_reset_state_file)*)(LIBRARY_FN_BASE+280)) 117 | #define set_reset_state_file (*(typeof(set_reset_state_file)*)(LIBRARY_FN_BASE+284)) 118 | #define usb_powered (*(typeof(usb_powered)*)(LIBRARY_FN_BASE+288)) 119 | #define aux_buf_ptr (*(typeof(aux_buf_ptr)*)(LIBRARY_FN_BASE+292)) 120 | #define write_buf_ptr (*(typeof(write_buf_ptr)*)(LIBRARY_FN_BASE+296)) 121 | #define print_byte (*(typeof(print_byte)*)(LIBRARY_FN_BASE+300)) 122 | #define printer_get_delay (*(typeof(printer_get_delay)*)(LIBRARY_FN_BASE+304)) 123 | #define printer_set_delay (*(typeof(printer_set_delay)*)(LIBRARY_FN_BASE+308)) 124 | #define printer_advance_buf (*(typeof(printer_advance_buf)*)(LIBRARY_FN_BASE+312)) 125 | #define printer_busy_for (*(typeof(printer_busy_for)*)(LIBRARY_FN_BASE+316)) 126 | #define rtc_check_unset (*(typeof(rtc_check_unset)*)(LIBRARY_FN_BASE+320)) 127 | #define run_set_time (*(typeof(run_set_time)*)(LIBRARY_FN_BASE+324)) 128 | #define run_set_date (*(typeof(run_set_date)*)(LIBRARY_FN_BASE+328)) 129 | #define disp_disk_info (*(typeof(disp_disk_info)*)(LIBRARY_FN_BASE+332)) 130 | #define file_selection_screen (*(typeof(file_selection_screen)*)(LIBRARY_FN_BASE+336)) 131 | #define power_check_screen (*(typeof(power_check_screen)*)(LIBRARY_FN_BASE+340)) 132 | #define handle_menu (*(typeof(handle_menu)*)(LIBRARY_FN_BASE+344)) 133 | #define rb_str (*(typeof(rb_str)*)(LIBRARY_FN_BASE+348)) 134 | #define sel_str (*(typeof(sel_str)*)(LIBRARY_FN_BASE+352)) 135 | #define opt_str (*(typeof(opt_str)*)(LIBRARY_FN_BASE+356)) 136 | #define date_str (*(typeof(date_str)*)(LIBRARY_FN_BASE+360)) 137 | #define time_str (*(typeof(time_str)*)(LIBRARY_FN_BASE+364)) 138 | #define read_file_items (*(typeof(read_file_items)*)(LIBRARY_FN_BASE+368)) 139 | #define sort_file_items (*(typeof(sort_file_items)*)(LIBRARY_FN_BASE+372)) 140 | #define create_screenshot (*(typeof(create_screenshot)*)(LIBRARY_FN_BASE+376)) 141 | #define key_empty (*(typeof(key_empty)*)(LIBRARY_FN_BASE+380)) 142 | #define key_push (*(typeof(key_push)*)(LIBRARY_FN_BASE+384)) 143 | #define key_tail (*(typeof(key_tail)*)(LIBRARY_FN_BASE+388)) 144 | #define key_pop (*(typeof(key_pop)*)(LIBRARY_FN_BASE+392)) 145 | #define key_pop_last (*(typeof(key_pop_last)*)(LIBRARY_FN_BASE+396)) 146 | #define key_pop_all (*(typeof(key_pop_all)*)(LIBRARY_FN_BASE+400)) 147 | #define key_to_nr (*(typeof(key_to_nr)*)(LIBRARY_FN_BASE+404)) 148 | #define wait_for_key_press (*(typeof(wait_for_key_press)*)(LIBRARY_FN_BASE+408)) 149 | #define runner_get_key (*(typeof(runner_get_key)*)(LIBRARY_FN_BASE+412)) 150 | #define runner_get_key_delay (*(typeof(runner_get_key_delay)*)(LIBRARY_FN_BASE+416)) 151 | #define wait_for_key_release (*(typeof(wait_for_key_release)*)(LIBRARY_FN_BASE+420)) 152 | #define runner_key_tout_value (*(typeof(runner_key_tout_value)*)(LIBRARY_FN_BASE+424)) 153 | #define runner_key_tout_init (*(typeof(runner_key_tout_init)*)(LIBRARY_FN_BASE+428)) 154 | #define toggle_slow_autorepeat (*(typeof(toggle_slow_autorepeat)*)(LIBRARY_FN_BASE+432)) 155 | #define is_slow_autorepeat (*(typeof(is_slow_autorepeat)*)(LIBRARY_FN_BASE+436)) 156 | #define reset_auto_off (*(typeof(reset_auto_off)*)(LIBRARY_FN_BASE+440)) 157 | #define is_auto_off (*(typeof(is_auto_off)*)(LIBRARY_FN_BASE+444)) 158 | #define is_menu_auto_off (*(typeof(is_menu_auto_off)*)(LIBRARY_FN_BASE+448)) 159 | #define sys_auto_off_cnt (*(typeof(sys_auto_off_cnt)*)(LIBRARY_FN_BASE+452)) 160 | #define print_dmy_date (*(typeof(print_dmy_date)*)(LIBRARY_FN_BASE+456)) 161 | #define print_clk24_time (*(typeof(print_clk24_time)*)(LIBRARY_FN_BASE+460)) 162 | #define check_create_dir (*(typeof(check_create_dir)*)(LIBRARY_FN_BASE+464)) 163 | #define set_fat_label (*(typeof(set_fat_label)*)(LIBRARY_FN_BASE+468)) 164 | #define file_exists (*(typeof(file_exists)*)(LIBRARY_FN_BASE+472)) 165 | #define sys_disk_ok (*(typeof(sys_disk_ok)*)(LIBRARY_FN_BASE+476)) 166 | #define sys_disk_write_enable (*(typeof(sys_disk_write_enable)*)(LIBRARY_FN_BASE+480)) 167 | #define sys_disk_check_valid (*(typeof(sys_disk_check_valid)*)(LIBRARY_FN_BASE+484)) 168 | #define sys_is_disk_write_enable (*(typeof(sys_is_disk_write_enable)*)(LIBRARY_FN_BASE+488)) 169 | #define sys_clear_write_buf_used (*(typeof(sys_clear_write_buf_used)*)(LIBRARY_FN_BASE+492)) 170 | #define sys_write_buf_used (*(typeof(sys_write_buf_used)*)(LIBRARY_FN_BASE+496)) 171 | #define sys_timer_disable (*(typeof(sys_timer_disable)*)(LIBRARY_FN_BASE+500)) 172 | #define sys_timer_start (*(typeof(sys_timer_start)*)(LIBRARY_FN_BASE+504)) 173 | #define sys_timer_active (*(typeof(sys_timer_active)*)(LIBRARY_FN_BASE+508)) 174 | #define sys_timer_timeout (*(typeof(sys_timer_timeout)*)(LIBRARY_FN_BASE+512)) 175 | #define sys_delay (*(typeof(sys_delay)*)(LIBRARY_FN_BASE+516)) 176 | #define sys_tick_count (*(typeof(sys_tick_count)*)(LIBRARY_FN_BASE+520)) 177 | #define sys_current_ms (*(typeof(sys_current_ms)*)(LIBRARY_FN_BASE+524)) 178 | #define sys_critical_start (*(typeof(sys_critical_start)*)(LIBRARY_FN_BASE+528)) 179 | #define sys_critical_end (*(typeof(sys_critical_end)*)(LIBRARY_FN_BASE+532)) 180 | #define sys_sleep (*(typeof(sys_sleep)*)(LIBRARY_FN_BASE+536)) 181 | #define sys_free_mem (*(typeof(sys_free_mem)*)(LIBRARY_FN_BASE+540)) 182 | #define sys_reset (*(typeof(sys_reset)*)(LIBRARY_FN_BASE+544)) 183 | #define sys_last_key (*(typeof(sys_last_key)*)(LIBRARY_FN_BASE+548)) 184 | #define run_help (*(typeof(run_help)*)(LIBRARY_FN_BASE+552)) 185 | #define draw_power_off_image (*(typeof(draw_power_off_image)*)(LIBRARY_FN_BASE+556)) 186 | #define reset_off_image_cycle (*(typeof(reset_off_image_cycle)*)(LIBRARY_FN_BASE+560)) 187 | #define f_open (*(typeof(f_open)*)(LIBRARY_FN_BASE+564)) 188 | #define f_close (*(typeof(f_close)*)(LIBRARY_FN_BASE+568)) 189 | #define f_read (*(typeof(f_read)*)(LIBRARY_FN_BASE+572)) 190 | #define f_write (*(typeof(f_write)*)(LIBRARY_FN_BASE+576)) 191 | #define f_lseek (*(typeof(f_lseek)*)(LIBRARY_FN_BASE+580)) 192 | #define run_help_file (*(typeof(run_help_file)*)(LIBRARY_FN_BASE+584)) 193 | #define set_buzzer (*(typeof(set_buzzer)*)(LIBRARY_FN_BASE+588)) 194 | #define __sysfn_read_key (*(typeof(read_key)*)(LIBRARY_FN_BASE+592)) 195 | #define get_tim1_timer (*(typeof(get_tim1_timer)*)(LIBRARY_FN_BASE+596)) 196 | #define update_bmp_file_header (*(typeof(update_bmp_file_header)*)(LIBRARY_FN_BASE+600)) 197 | #define make_date_filename (*(typeof(make_date_filename)*)(LIBRARY_FN_BASE+604)) 198 | #define reverse_byte (*(typeof(reverse_byte)*)(LIBRARY_FN_BASE+608)) 199 | #define f_rename (*(typeof(f_rename)*)(LIBRARY_FN_BASE+612)) 200 | #define file_size (*(typeof(file_size)*)(LIBRARY_FN_BASE+616)) 201 | #define start_timer2 (*(typeof(start_timer2)*)(LIBRARY_FN_BASE+620)) 202 | #define start_timer3 (*(typeof(start_timer3)*)(LIBRARY_FN_BASE+624)) 203 | #define stop_timer2 (*(typeof(stop_timer2)*)(LIBRARY_FN_BASE+628)) 204 | #define stop_timer3 (*(typeof(stop_timer3)*)(LIBRARY_FN_BASE+632)) 205 | #define __sysfn_suspended_bg_key_read (*(typeof(suspended_bg_key_read)*)(LIBRARY_FN_BASE+636)) 206 | #define __sysfn_resume_bg_key_read (*(typeof(resume_bg_key_read)*)(LIBRARY_FN_BASE+640)) 207 | #define lcd_refresh_dma (*(typeof(lcd_refresh_dma)*)(LIBRARY_FN_BASE+644)) 208 | #define lcd_refresh_wait (*(typeof(lcd_refresh_wait)*)(LIBRARY_FN_BASE+648)) 209 | #define lcd_textToBox (*(typeof(lcd_textToBox)*)(LIBRARY_FN_BASE+652)) 210 | #define item_sel_init (*(typeof(item_sel_init)*)(LIBRARY_FN_BASE+656)) 211 | #define item_sel_reinit (*(typeof(item_sel_reinit)*)(LIBRARY_FN_BASE+660)) 212 | #define item_sel_header (*(typeof(item_sel_header)*)(LIBRARY_FN_BASE+664)) 213 | #define item_sel_engine (*(typeof(item_sel_engine)*)(LIBRARY_FN_BASE+668)) 214 | #define sys_flashing_init (*(typeof(sys_flashing_init)*)(LIBRARY_FN_BASE+672)) 215 | #define sys_flashing_finish (*(typeof(sys_flashing_finish)*)(LIBRARY_FN_BASE+676)) 216 | #define sys_flash_erase_block (*(typeof(sys_flash_erase_block)*)(LIBRARY_FN_BASE+680)) 217 | #define sys_flash_write_block (*(typeof(sys_flash_write_block)*)(LIBRARY_FN_BASE+684)) 218 | #define msg_box (*(typeof(msg_box)*)(LIBRARY_FN_BASE+688)) 219 | #define write_buf_size (*(typeof(write_buf_size)*)(LIBRARY_FN_BASE+692)) 220 | #define get_rtc_ticks (*(typeof(get_rtc_ticks)*)(LIBRARY_FN_BASE+696)) 221 | #define rtc_update_ticks (*(typeof(rtc_update_ticks)*)(LIBRARY_FN_BASE+700)) 222 | #define rtc_set_alarm (*(typeof(rtc_set_alarm)*)(LIBRARY_FN_BASE+704)) 223 | #define rtc_cancel_alarm (*(typeof(rtc_cancel_alarm)*)(LIBRARY_FN_BASE+708)) 224 | #define rtc_update_time_sec (*(typeof(rtc_update_time_sec)*)(LIBRARY_FN_BASE+712)) 225 | #define run_help_file_style (*(typeof(run_help_file_style)*)(LIBRARY_FN_BASE+716)) 226 | #define print_buffer (*(typeof(print_buffer)*)(LIBRARY_FN_BASE+720)) 227 | #define print_is_ready (*(typeof(print_is_ready)*)(LIBRARY_FN_BASE+724)) 228 | #define run_menu_item_sys (*(typeof(run_menu_item_sys)*)(LIBRARY_FN_BASE+728)) 229 | #define lcd_fill_ptrn (*(typeof(lcd_fill_ptrn)*)(LIBRARY_FN_BASE+732)) 230 | #define usb_acm_on (*(typeof(usb_acm_on)*)(LIBRARY_FN_BASE+736)) 231 | #define usb_turn_off (*(typeof(usb_turn_off)*)(LIBRARY_FN_BASE+740)) 232 | #define usb_is_on (*(typeof(usb_is_on)*)(LIBRARY_FN_BASE+744)) 233 | #define acm_puts (*(typeof(acm_puts)*)(LIBRARY_FN_BASE+748)) 234 | #define switch_usb_powered_freq (*(typeof(switch_usb_powered_freq)*)(LIBRARY_FN_BASE+752)) 235 | #define qspi_user_write (*(typeof(qspi_user_write)*)(LIBRARY_FN_BASE+756)) 236 | #define qspi_user_addr (*(typeof(qspi_user_addr)*)(LIBRARY_FN_BASE+760)) 237 | #define qspi_user_size (*(typeof(qspi_user_size)*)(LIBRARY_FN_BASE+764)) 238 | #define f_unlink (*(typeof(f_unlink)*)(LIBRARY_FN_BASE+768)) 239 | #define sys_last_scan (*(typeof(sys_last_scan)*)(LIBRARY_FN_BASE+772)) 240 | #define sys_largest_free_mem (*(typeof(sys_largest_free_mem)*)(LIBRARY_FN_BASE+776)) 241 | #define sys_request (*(typeof(sys_request)*)(LIBRARY_FN_BASE+780)) 242 | #define qrcode_disp (*(typeof(qrcode_disp)*)(LIBRARY_FN_BASE+784)) 243 | #define qrcode_getBufferSize (*(typeof(qrcode_getBufferSize)*)(LIBRARY_FN_BASE+788)) 244 | #define qrcode_initText (*(typeof(qrcode_initText)*)(LIBRARY_FN_BASE+792)) 245 | #define qrcode_initBytes (*(typeof(qrcode_initBytes)*)(LIBRARY_FN_BASE+796)) 246 | #define qrcode_getModule (*(typeof(qrcode_getModule)*)(LIBRARY_FN_BASE+800)) 247 | -------------------------------------------------------------------------------- /free42/core_main.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Free42 -- an HP-42S calculator simulator 3 | * Copyright (C) 2004-2025 Thomas Okken 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License, version 2, 7 | * as published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, see http://www.gnu.org/licenses/. 16 | *****************************************************************************/ 17 | 18 | #ifndef CORE_MAIN_H 19 | #define CORE_MAIN_H 1 20 | 21 | #include "free42.h" 22 | 23 | 24 | /**********************************/ 25 | /* Shell/Core interface functions */ 26 | /**********************************/ 27 | 28 | /* core_init() 29 | * 30 | * This function initializes the emulator core. If the read_state parameter is 31 | * 1, the core should read saved state from the file named by the 32 | * state_file_name parameter, reading from the offset indicated by the offset 33 | * parameter; if read_state is 0, or if there is a problem reading the saved 34 | * state, it should perform a hard reset. 35 | * If the read_state parameter is 1, the 'version' parameter should contain the 36 | * state file version number; otherwise its value is not used. 37 | * This is guaranteed to be the first function called on the emulator core. 38 | */ 39 | void core_init(int read_state, int4 version, const char *state_file_name, int offset); 40 | 41 | /* core_save_state() 42 | * 43 | * This function is called by the mobile apps when they are placed in 44 | * background mode, and by the desktop apps when they are shutting down. 45 | * It writes all the simulator's persistent state to a file given by the 46 | * state_file_name parameter, creating it if it doesn't already exist. 47 | */ 48 | void core_save_state(const char *state_file_name); 49 | 50 | /* core_cleanup() 51 | * 52 | * This function deletes down the emulator core state from memory. It may be 53 | * called during app shutdown, although that's not really necessary unless you 54 | * are checking for memory leaks. It should be called between saving state and 55 | * loading a new state, that is, when switching states. 56 | */ 57 | void core_cleanup(); 58 | 59 | /* core_repaint_display() 60 | * 61 | * This function asks the emulator core to repaint the display. The core will 62 | * respond by immediately calling shell_blitter() to repaint the entire 63 | * display. 64 | * The shell uses this function to re-generate the display after switching 65 | * skins. 66 | */ 67 | void core_repaint_display(); 68 | 69 | /* core_menu() 70 | * 71 | * The shell uses this function to check if a menu is active. This affects 72 | * whether or not clicking in the display, to activate menu keys, is 73 | * enabled. 74 | */ 75 | bool core_menu(); 76 | 77 | /* core_alpha_menu() 78 | * 79 | * The shell uses this function to check if the core is in "alpha" mode (i.e. 80 | * the ALPHA menu or any of its submenus is active). This affects how events 81 | * from the keyboard (the real PC keyboard, not the on-screen one emulated by 82 | * Free42) are handled: in alpha mode, printable ASCII characters are sent 83 | * straight to the core; outside alpha mode, all key events are translated 84 | * sequences of HP-42S key events according to the keymap file. 85 | */ 86 | bool core_alpha_menu(); 87 | 88 | /* core_hex_menu() 89 | * 90 | * The shell uses this function to check if the core is in "hex" mode (i.e. 91 | * the A..F submenu of the BASE application is active). This affects how events 92 | * from the keyboard (the real PC keyboard, not the on-screen one emulated by 93 | * Free42) are handled: in hex mode, 'A' through 'F' and 'a' through 'f' are 94 | * translated to keycodes 1 through 6, regardless of the keyboard map. 95 | */ 96 | bool core_hex_menu(); 97 | 98 | /* core_special_menu_key() 99 | * 100 | * The shell can call this function if the physical cursor left, cursor right, 101 | * or delete keys have been pressed; the core will return the appropriate 102 | * menu key to trigger. This is to support menus like the matrix editor. 103 | * Which can be: 1=left, 2=shift left, 3=right, 4=shift right, 5=del. 104 | * The return value is a menu key number 1-6, or 0 if no special menu key 105 | * is available. 106 | */ 107 | int core_special_menu_key(int which); 108 | 109 | /* core_keydown() 110 | * 111 | * This function informs the emulator core that an HP-42S key was pressed. Keys 112 | * are identified using a numeric key code, which corresponds to the key 113 | * numbers returned by the HP-42S 'GETKEY' function: 'Sigma+' is 1, '1/x' is 2, 114 | * and so on. The shift key is 28 -- 'shift' handling is performed by the 115 | * emulator core, so it needs to receive raw key codes, unlike the 'GETKEY' 116 | * function, which handles the shift key itself and then returns key codes in 117 | * the range 38..74 for shifted keys. The core_keydown() function should only 118 | * be called with key codes from 1 to 37, inclusive. 119 | * Keys that cause immediate action should be handled immediately when this 120 | * function is called, and calls to core_keytimeout1(), core_keytimeout2(), 121 | * and core_keyup() should be ignored (until the next core_keydown(), that 122 | * is!). Keys that are handled only when *released* should not be handled 123 | * immediately when this function is called; the emulator core should store the 124 | * key code, handle core_keytimeout1() and core_keytimeout2() as appropriate, 125 | * and not perform any action until core_keyup() is called. 126 | * RETURNS: a flag indicating whether or not the front end should call this 127 | * function again as soon as possible. This will be 1 if the calculator is 128 | * running a user program, and is only returning execution to the shell because 129 | * it has detected that there is a pending event. 130 | * The 'enqueued' pointer is a return parameter that the emulator core uses to 131 | * tell the shell if it has enqueued the keystroke. If this is 1, the shell 132 | * should not send call timeout1(), timeout2(), or keyup() for this keystroke. 133 | * NOTE: a key code of 0 (zero) signifies 'no key'; this is needed if the shell 134 | * is calling this function because it asked to be called (by returning 1 the 135 | * last time) but no keystrokes are available. It is not necessary to balance 136 | * the keydown call with a keyup in this case. 137 | * The 'repeat' pointer is a return parameter that the emulator core uses to 138 | * ask the shell to auto-repeat the current key. If this is set to 1 or 2, the 139 | * shell will not call timeout1() and timeout2(), but will repeatedly call 140 | * core_repeat() until the key is released. (1 requests a slow repeat rate, for 141 | * SST/BST; 2 requests a fast repeat rate, for number/alpha entry.) 142 | */ 143 | bool core_keydown(int key, bool *enqueued, int *repeat); 144 | 145 | /* core_keydown_command() 146 | * 147 | * This function is equivalent to core_keydown(), except that instead of a key 148 | * number, it expects a command name. This can be used to implement skins that 149 | * map skin keys or keyboard keys directly to calculator commands, which is 150 | * useful if you want to assign commands to the keyboard that aren't directly 151 | * mapped on the original calculator. Without this, you'd have to create such a 152 | * mapping by creating a macro that performs XEQ and spells out the command 153 | * name, or selects the command from a menu or the FCN catalog, all of which 154 | * have potentially undesirable side effects. 155 | * The is_text parameter signals that the command is actually literal text to 156 | * be entered. This should only happen when ALPHA is active. This corresponds 157 | * to secondary macros with '' delimiters. 158 | */ 159 | bool core_keydown_command(const char *name, bool is_text, bool *enqueued, int *repeat); 160 | 161 | /* core_repeat() 162 | * 163 | * This function is called by the shell to signal auto-repeating key events. 164 | * It is the core's responsibility to keep track of *which* key is repeating. 165 | * The function can return 0, to request repeating to stop; 1, which requests 166 | * a slow repeat rate, for SST/BST; or 2, which requests a fast repeat rate, 167 | * for number/alpha entry. 168 | */ 169 | int core_repeat(); 170 | 171 | /* core_keytimeout1() 172 | * 173 | * This function informs the emulator core that the currently pressed key has 174 | * been held down for 1/4 of a second. (If the key is released less than 1/4 175 | * second after being pressed, this function is not called.) 176 | * For keys that do not execute immediately, this marks the moment when the 177 | * calculator displays the key's function name. 178 | */ 179 | void core_keytimeout1(); 180 | 181 | /* core_keytimeout2() 182 | * 183 | * This function informs the emulator core that 2 seconds have passed since 184 | * core_keytimeout1() was called. (If the key is released less than 2 seconds 185 | * after core_keytimeout1() is called, this function is not called.) 186 | * This marks the moment when the calculator switches from displaying the key's 187 | * function name to displaying 'NULL' (informing the user that the key has been 188 | * annulled and so no operation will be performed when it is released). 189 | */ 190 | void core_keytimeout2(); 191 | 192 | /* core_timeout3() 193 | * 194 | * A wakeup call that the core can request by calling shell_request_timeout3(). 195 | * Used to implement PSE and the brief linger period after MEM, SHOW, and 196 | * shift-VARMENU. The 'repaint' parameter says whether the callback is invoked 197 | * because the timeout period expired (1), or because a key event is on its 198 | * way (0); if a key event is on its way, the emulator core should not repaint 199 | * the screen, in order to avoid flashing. 200 | * If the function returns 'true', this means that the timeout was used for 201 | * PSE, and the shell should resume program execution. 202 | */ 203 | bool core_timeout3(bool repaint); 204 | 205 | /* core_keyup() 206 | * 207 | * This function informs the emulator core that the currently pressed key (that 208 | * is, the one whose key code was given to it in the most recent call to 209 | * core_keydown()) has been released. 210 | * This function is always called when a key is released, regardless of how 211 | * long it was held down, and regardless of whether or not core_keytimeout1() 212 | * and core_keytimeout2() were called following the most recent 213 | * core_keydown(). 214 | * RETURNS: a flag indicating whether or not the front end should call this 215 | * function again as soon as possible. This will be 1 if the calculator is 216 | * running a user program, and is only returning execution to the shell because 217 | * it has detected that there is a pending event. 218 | */ 219 | bool core_keyup(); 220 | 221 | /* core_powercycle() 222 | * 223 | * This tells the core to pretend that a power cycle has just taken place. 224 | * Usually called right after core_init(). 225 | * The core should respond by performing power-down activities, immediately 226 | * followed by power-up activities. (The emulator core is never expected to 227 | * actually emulate the state of *being* off -- the host environment can handle 228 | * being off just fine by itself, thank you very much -- it's just the side 229 | * effects of the *transitions* of a power cycle we want emulated (stopping 230 | * program execution, restarting it if flag 11 is set, clearing flags 11 and 231 | * 44, and maybe other stuff once I discover it). 232 | * This function returns a flag telling the shell whether or not the core wants 233 | * to run again -- this will be true if flag 11 was set, so there's program 234 | * execution to be done. 235 | */ 236 | bool core_powercycle(); 237 | 238 | /* core_list_programs() 239 | * 240 | * This function is called by the shell when the user activates the Export 241 | * Program command. The core returns a list of program names, corresponding to 242 | * the programs as they appear in the PGM catalog, but in reverse order (the 243 | * .END. is last). Each item corresponds to one program, and consists of the 244 | * names of all the global labels in that program. Programs that contain no 245 | * global labels are given the name END (or .END.). 246 | * The indexes into the list of program names should be used to identify 247 | * programs to core_export_programs(). 248 | * The function returns a dynamically allocated buffer. The first four bytes 249 | * are the number of programs returned (as a big-endian int) which is 250 | * guaranteed to always be at least 1. This is followed by a sequence of 251 | * 'program_count' null-terminated strings. 252 | * This function will return NULL if it fails to allocate the buffer. 253 | * The caller should free() the buffer once it is finished using it. 254 | */ 255 | 256 | #ifdef ARM 257 | // Use old non-dynamically allocated version 258 | int core_list_programs(char *buf, int bufsize); 259 | #else 260 | char *core_list_programs(); 261 | #endif 262 | 263 | /* core_program_size() 264 | * This function returns the size of a program, specified by its index. 265 | * The indexes correspond to those returned by core_list_programs(). The caller 266 | * should *only* use those indexes; any indexes outside of that range will 267 | * cause weirdness and mayhem. 268 | * The size returned by this function does not include the 3 bytes for the 269 | * END; this matches what the HP-42S displays on line 00, but the caller should 270 | * be aware that the actual byte stream produced by core_export_programs() will 271 | * be 3 bytes longer. 272 | */ 273 | int4 core_program_size(int prgm_index); 274 | 275 | /* core_export_programs() 276 | * 277 | * This function is called by the shell after the user has selected a nonempty 278 | * set of programs (from the list returned by core_list_programs()) and 279 | * confirmed the operation (supplied a file name etc.). 280 | * The 'count' parameter indicates how many programs are to be exported; the 281 | * 'indexes' parameter is an array of program indexes. 282 | * When called by the core during state file saving, raw_file_name will be 283 | * NULL, which tells it to write to the already-opened state file. 284 | */ 285 | void core_export_programs(int count, const int *indexes, const char *raw_file_name); 286 | 287 | /* core_import_programs() 288 | * 289 | * This function imports programs from the file named by the raw_file_name 290 | * parameter. It will read at most num_progs programs. When called by the 291 | * shell, num_progs should be 0, which tells it to load the entire file. 292 | * When called by the core during state file loading, raw_file_name will be 293 | * NULL, which tells it to read from the already-opened state file. 294 | */ 295 | void core_import_programs(int num_progs, const char *raw_file_name); 296 | 297 | /* core_copy() 298 | * 299 | * Returns a string representation of the contents of the X register. In 300 | * program mode, returns a listing of the current program. I alpha mode, 301 | * returns the contents of the alpha register. 302 | * Used by the shell to implement the Copy command. 303 | * The caller should free the returned text using free(3). 304 | */ 305 | char *core_copy(); 306 | 307 | /* core_paste() 308 | * 309 | * In normal mode, puts the given value on the stack, parsing it as tab- 310 | * delimited spreadsheet cells, complex or real scalars, or, if nothing 311 | * matches, as a simple string. In program mode, attempts to parse the text as 312 | * a program listing, and adds the converted code as a new program at the end 313 | * of program memory. In alpha mode, pastes the text in the alpha register, 314 | * appending it to whatever is already there. 315 | * Used by the shell to implement the Paste command. 316 | */ 317 | void core_paste(const char *s); 318 | 319 | #if defined(ANDROID) || defined(IPHONE) 320 | 321 | /* core_get_char_pixels() 322 | * 323 | * Gets character pixels from the calculator's 8x5 characters, for the 324 | * given UTF-8 encoded character, provided as a null-terminated string. 325 | */ 326 | void core_get_char_pixels(const char *ch, char *pixels); 327 | 328 | #endif 329 | 330 | /* core_update_allow_big_stack() 331 | * 332 | * Updates the big stack state and the UI to reflect a change in the 333 | * global Allow Big Stack setting. 334 | */ 335 | void core_update_allow_big_stack(); 336 | 337 | /* core_settings 338 | * 339 | * This is a struct that stores user-configurable core settings. The shell 340 | * should provide the appropriate controls in a "Preferences" dialog box to 341 | * allow the user to view and change these settings. 342 | */ 343 | struct core_settings_struct { 344 | bool matrix_singularmatrix; 345 | bool matrix_outofrange; 346 | bool auto_repeat; 347 | bool allow_big_stack; 348 | bool localized_copy_paste; 349 | }; 350 | 351 | extern core_settings_struct core_settings; 352 | 353 | 354 | /*******************/ 355 | /* Keyboard repeat */ 356 | /*******************/ 357 | 358 | extern int repeating; 359 | extern int repeating_shift; 360 | extern int repeating_key; 361 | 362 | 363 | /*******************/ 364 | /* Other functions */ 365 | /*******************/ 366 | 367 | extern bool quitting; 368 | 369 | void set_alpha_entry(bool state); 370 | void set_running(bool state); 371 | bool program_running(); 372 | bool alpha_active(); 373 | void set_annunciators(int updn, int shf, int prt, int run, int g, int rad); 374 | int dequeue_key(); 375 | 376 | void do_interactive(int command); 377 | int find_builtin(const char *name, int namelen); 378 | 379 | void sst(); 380 | void bst(); 381 | 382 | int find_menu_key(int key); 383 | void start_incomplete_command(int cmd_id); 384 | void finish_command_entry(bool refresh); 385 | void finish_xeq(); 386 | bool start_alpha_prgm_line(); 387 | void finish_alpha_prgm_line(); 388 | int shiftcharacter(char c); 389 | void set_old_pc(int4 pc); 390 | const char *number_format(); 391 | 392 | 393 | #endif 394 | -------------------------------------------------------------------------------- /dmcp/dmcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | #ifndef __SYS_DMCP_H__ 44 | #define __SYS_DMCP_H__ 45 | 46 | #include 47 | 48 | typedef unsigned int uint; 49 | 50 | #include "ff_ifc.h" 51 | #include "qrcode.h" 52 | 53 | // ---------------------------------- 54 | 55 | 56 | // Configuration 57 | #define LCD_INVERT_XAXIS 58 | #define LCD_INVERT_DATA 59 | // ------- 60 | 61 | 62 | #define BLT_OR 0 63 | #define BLT_ANDN 1 64 | #define BLT_XOR 2 // 3 65 | 66 | #define BLT_NONE 0 67 | #define BLT_SET 1 68 | 69 | 70 | #ifdef LCD_INVERT_DATA 71 | # define LCD_EMPTY_VALUE 0xFF 72 | # define LCD_SET_VALUE 0 73 | #else 74 | # define LCD_EMPTY_VALUE 0 75 | # define LCD_SET_VALUE 0xFF 76 | #endif 77 | 78 | 79 | 80 | // HW interface 81 | void LCD_clear(); 82 | void LCD_power_on(); 83 | void LCD_power_off(int clear); 84 | void LCD_write_line(uint8_t * buf); 85 | 86 | 87 | void bitblt24(uint32_t x, uint32_t dx, uint32_t y, uint32_t val, int blt_op, int fill); 88 | 89 | // Returns pointer to line buffer (doesn't depend on LCD_INVERT_XAXIS) 90 | uint8_t * lcd_line_addr(int y); 91 | 92 | // Drawing Prototypes 93 | void lcd_clear_buf(); 94 | void lcd_refresh(); 95 | void lcd_refresh_dma(); 96 | void lcd_refresh_wait(); 97 | void lcd_forced_refresh(); 98 | void lcd_refresh_lines(int ln, int cnt); 99 | 100 | 101 | void lcd_fill_rect(uint32_t x, uint32_t y, uint32_t dx, uint32_t dy, int val); 102 | void lcd_fill_ptrn(int x, int y, int dx, int dy, int ptrn1, int ptrn2); 103 | 104 | // Place image into LCD buffer 105 | void lcd_draw_img(const char* img, uint32_t xo, uint32_t yo, uint32_t x, uint32_t y); 106 | void lcd_draw_img_direct(const char* img, uint32_t xo, uint32_t yo, uint32_t x, uint32_t y); 107 | void lcd_draw_img_part(const char* img, uint32_t xo, uint32_t yo, uint32_t x, uint32_t y, uint32_t dx); 108 | 109 | #define LCD_X 400 110 | #define LCD_Y 240 111 | #define LCD_LINE_SIZE 50 // LCD_X/8 112 | #define LCD_LINE_BUF_SIZE (2+LCD_LINE_SIZE+2) // CMD, Line_nr, line data (50 bytes), dummy (2 bytes) 113 | 114 | void lcd_fillLine(int ln, uint8_t val); 115 | void lcd_fillLines(int ln, uint8_t val, int cnt); 116 | 117 | 118 | void lcd_set_buf_cleared(int val); 119 | int lcd_get_buf_cleared(); 120 | 121 | uint8_t reverse_byte(uint8_t x); 122 | 123 | 124 | // ---------------------------------- 125 | 126 | 127 | // Font structure 128 | typedef struct { 129 | const char * name; 130 | uint8_t width; 131 | uint8_t height; 132 | uint8_t baseline; 133 | uint8_t first_char; 134 | uint8_t char_cnt; 135 | uint8_t scale_x; 136 | uint8_t scale_y; 137 | uint8_t const * data; 138 | uint16_t const * offs; 139 | } line_font_t; 140 | 141 | 142 | #define NR2T(x) (-(x)-1) // x<0 143 | #define T2NR(x) (-(x)-1) // x>=0 144 | 145 | // Font display state 146 | typedef struct { 147 | line_font_t const * f; // Current font 148 | int16_t x, y; // Current x,y position 149 | int16_t ln_offs; // Line offset (when displaying by line numbers) 150 | int16_t y_top_grd; // Don't overwrite anything above this line 151 | int8_t ya; // Lines to fill above the font 152 | int8_t yb; // Lines to fill below the font 153 | int8_t xspc; // Space between chars 154 | int8_t xoffs; // X offset for first char on line 155 | 156 | uint8_t fixed; // Draw in fixed width 157 | uint8_t inv; // Draw inverted 158 | uint8_t bgfill; // Fill background while drawing 159 | uint8_t lnfill; // Fill whole lines before writing line 160 | uint8_t newln; // New line after writing line 161 | const uint8_t *post_offs; // X-advance character width minus this value (if not-null) 162 | } disp_stat_t; 163 | 164 | void lcd_writeNl(disp_stat_t * ds); 165 | void lcd_prevLn(disp_stat_t * ds); 166 | void lcd_writeClr(disp_stat_t * ds); 167 | void lcd_setLine(disp_stat_t * ds, int ln_nr); 168 | void lcd_setXY(disp_stat_t * ds, int x, int y); 169 | 170 | int lcd_lineHeight(disp_stat_t * ds); 171 | int lcd_baseHeight(disp_stat_t * ds); 172 | int lcd_fontWidth(disp_stat_t * ds); 173 | 174 | // Font display functions 175 | void lcd_writeText(disp_stat_t * ds, const char* text); 176 | // Note that 'text' has to be in RAM 177 | void lcd_textToBox(disp_stat_t * ds, int x, int width, char *text, int from_right, int align_right); 178 | 179 | // Width calculation functions 180 | int lcd_textWidth(disp_stat_t * ds, const char* text); 181 | int lcd_charWidth(disp_stat_t * ds, int c); 182 | 183 | // Get just text which fits in expected_width 184 | // Returns index of char which breaks the space limit 185 | // Optional plen variable can be supplied to get text width up to index limit. 186 | int lcd_textToWidth(disp_stat_t * ds, const char* text, int expected_width, int * plen); 187 | // ... alternative version to upper function which takes text from the end 188 | // returns -1 if whole text fits into 'expected_width' 189 | int lcd_textToWidthR(disp_stat_t * ds, const char* text, int expected_width, int * plen); 190 | 191 | // Just advance ds->x don't print anything 192 | void lcd_writeTextWidth(disp_stat_t * ds, const char* text); 193 | 194 | // Get text which fits in expected width *without breaking words* 195 | // - word could be broken in the middle only when is placed single long word on line 196 | int lcd_textForWidth(disp_stat_t * ds, const char* text, int expected_width, int * plen); 197 | 198 | 199 | // Font switching 200 | int lcd_nextFontNr(int nr); 201 | int lcd_prevFontNr(int nr); 202 | void lcd_switchFont(disp_stat_t * ds, int nr); 203 | int lcd_toggleFontT(int nr); 204 | 205 | 206 | // ---------------------------------- 207 | 208 | 209 | // Display screens for calc 210 | #define DISP_CALC 0 211 | #define DISP_SYS_MENU 2 212 | #define DISP_BOOTLOADER 4 213 | #define DISP_UNIMPLEMENTED 5 214 | #define DISP_USB_WRITE 6 215 | #define DISP_MSC_CONNECT_USB 7 216 | #define DISP_ABOUT 8 217 | #define DISP_FAT_FORMAT 9 218 | #define DISP_FAULT 11 219 | #define DISP_QSPI_BAD_CRC 12 220 | #define DISP_QSPI_CHECK 13 221 | #define DISP_MARK_REGION 15 222 | #define DISP_DISK_TEST 16 223 | #define DISP_DSKTST_CONNECT_USB 17 224 | #define DISP_QSPI_CONNECT_USB 18 225 | #define DISP_OFF_IMAGE_ERR 19 226 | #define DISP_HELP 21 227 | #define DISP_BOOTLDR_CON_USB 22 228 | #define DISP_PROD_DIAG 23 229 | #define DISP_POWER_CHECK 24 230 | #define DISP_FLASH_CONNECT_USB 26 231 | // ---- 232 | 233 | 234 | // Display predefined screen by number 235 | int lcd_for_calc(int what); 236 | 237 | 238 | // == Menu keys 239 | 240 | #define LCD_MENU_LINES 32 241 | 242 | #define MENU_KEY_LABEL_LEN 12 243 | #define MENU_KEY_COUNT 6 244 | 245 | void lcd_draw_menu_bg(); 246 | void lcd_draw_menu_key(int n, const char *s, int highlight); 247 | void lcd_draw_menu_keys(const char *keys[]); 248 | 249 | void lcd_print(disp_stat_t * ds, const char* fmt, ...); 250 | 251 | #define lcd_printAt(ds, ln, ...) do { lcd_setLine(ds, ln); lcd_print(ds, __VA_ARGS__); } while(0) 252 | #define lcd_printR(ds, ...) do { ds->inv=1; lcd_print(ds, __VA_ARGS__); ds->inv=0; } while(0) 253 | #define lcd_printRAt(ds, ln, ...) do { lcd_setLine(ds, ln); ds->inv=1; lcd_print(ds, __VA_ARGS__); ds->inv=0; } while(0) 254 | 255 | #define lcd_puts lcd_writeText 256 | #define lcd_putsAt(ds, ln, str) do { lcd_setLine(ds, ln); lcd_puts(ds,str); } while(0) 257 | #define lcd_putsR(ds, str) do { ds->inv=1; lcd_puts(ds,str); ds->inv=0; } while(0) 258 | #define lcd_putsRAt(ds, ln, str) do { lcd_setLine(ds, ln); ds->inv=1; lcd_puts(ds,str); ds->inv=0; } while(0) 259 | 260 | 261 | // ---------------------------------- 262 | 263 | 264 | typedef struct { 265 | uint16_t year; 266 | uint8_t month; 267 | uint8_t day; 268 | } dt_t; 269 | 270 | typedef struct { 271 | uint8_t hour; 272 | uint8_t min; 273 | uint8_t sec; 274 | uint8_t csec; 275 | uint8_t dow; 276 | } tm_t; 277 | 278 | const char* get_wday_shortcut(int day); // 0 = Monday 279 | const char* get_month_shortcut(int month); // 1 = Jan 280 | 281 | // DOW is julian_day % 7 ... where 0 = Mon 282 | int julian_day(dt_t *d); 283 | void julian_to_date(int julian_day, dt_t *d); 284 | 285 | 286 | // ---------------------------------- 287 | 288 | // System data block 289 | 290 | typedef int get_flag_fn_t(); 291 | typedef void set_flag_fn_t(int val); 292 | 293 | typedef int run_menu_item_fn_t(uint8_t line_id); 294 | typedef const char * menu_line_str_fn_t(uint8_t line_id, char * s, const int slen); 295 | 296 | typedef void void_fn_t(); 297 | 298 | 299 | typedef struct { 300 | volatile uint32_t calc_state; 301 | FIL * ppgm_fp; 302 | const char * key_to_alpha_table; 303 | 304 | run_menu_item_fn_t * run_menu_item_app; 305 | menu_line_str_fn_t * menu_line_str_app; 306 | 307 | void_fn_t * after_fat_format; 308 | 309 | get_flag_fn_t * get_flag_dmy; 310 | set_flag_fn_t * set_flag_dmy; 311 | get_flag_fn_t * is_flag_clk24; 312 | set_flag_fn_t * set_flag_clk24; 313 | get_flag_fn_t * is_beep_mute; 314 | set_flag_fn_t * set_beep_mute; 315 | 316 | disp_stat_t * pds_t20; 317 | disp_stat_t * pds_t24; 318 | disp_stat_t * pds_fReg; 319 | 320 | uint32_t * timer2_counter; 321 | uint32_t * timer3_counter; 322 | 323 | void_fn_t * msc_end_cb; 324 | 325 | } sys_sdb_t; 326 | 327 | 328 | #define calc_state (sdb.calc_state) 329 | #define ppgm_fp (sdb.ppgm_fp) 330 | 331 | #define key_to_alpha_table (sdb.key_to_alpha_table) 332 | 333 | #define run_menu_item_app (sdb.run_menu_item_app) 334 | #define menu_line_str_app (sdb.menu_line_str_app) 335 | 336 | #define after_fat_format (sdb.after_fat_format) 337 | 338 | #define get_flag_dmy (sdb.get_flag_dmy) 339 | #define set_flag_dmy (sdb.set_flag_dmy) 340 | #define is_flag_clk24 (sdb.is_flag_clk24) 341 | #define set_flag_clk24 (sdb.set_flag_clk24) 342 | #define is_beep_mute (sdb.is_beep_mute) 343 | #define set_beep_mute (sdb.set_beep_mute) 344 | #define timer2_counter (sdb.timer2_counter) 345 | #define timer3_counter (sdb.timer3_counter) 346 | 347 | #define msc_end_cb (sdb.msc_end_cb) 348 | 349 | 350 | #define t20 (sdb.pds_t20) 351 | #define t24 (sdb.pds_t24) 352 | #define fReg (sdb.pds_fReg) 353 | 354 | #define sdb (*((sys_sdb_t*)0x10002000)) 355 | 356 | 357 | // ---------------------------------- 358 | 359 | #define PLATFORM_VERSION "3.29" 360 | 361 | // System interface version 362 | #define PLATFORM_IFC_CNR 3 363 | #define PLATFORM_IFC_VER 17 364 | 365 | // STATIC_ASSERT ... 366 | #define ASSERT_CONCAT_(a, b) a##b 367 | #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) 368 | #define STATIC_ASSERT(e,m) ;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(int)(!!(e)) } 369 | //#define STATIC_ASSERT(expr, msg) typedef char ASSERT_CONCAT(static_assert_check_, __LINE__) [(expr) ? (+1) : (-1)] 370 | 371 | #define _STRINGIFY(x) #x 372 | #define STR(x) _STRINGIFY(x) 373 | 374 | #define BIT(n) (1<<(n)) 375 | 376 | // ==== HW ID 377 | uint8_t get_hw_id(); 378 | 379 | // ==== RTC 380 | void rtc_read(tm_t * tm, dt_t *dt); 381 | void rtc_write(tm_t * tm, dt_t *dt); 382 | void rtc_update_time_sec(int delta_sec); 383 | uint8_t rtc_read_century(); 384 | void rtc_write_century(uint8_t cent); 385 | uint8_t rtc_read_min(); 386 | uint8_t rtc_read_sec(); 387 | void rtc_wakeup_delay(); 388 | 389 | // ==== VBAT 390 | uint32_t read_power_voltage(); 391 | int get_lowbat_state(); 392 | int get_vbat(); 393 | 394 | // ==== Buzzer 395 | // Freq in mHz 396 | void start_buzzer_freq(uint32_t freq); 397 | void stop_buzzer(); 398 | void set_buzzer(int pin1val, int pin2val); 399 | 400 | void beep_volume_up(); 401 | void beep_volume_down(); 402 | int get_beep_volume(); 403 | 404 | 405 | // ==== REGIONS 406 | uint32_t mark_region(uint32_t id); 407 | void no_region(); 408 | 409 | 410 | // ==== RESET values 411 | #define NO_SPLASH_MAGIC 0xEACE7362 412 | #define ALLOC_FAIL_MAGIC 0x363EACE7 413 | #define CLEAN_RESET_MAGIC 0x3EACE736 414 | #define RUN_DMCP_MAGIC 0x3CE7EA37 415 | 416 | void set_reset_magic(uint32_t value); 417 | 418 | 419 | 420 | // === RESET STATE FILE 421 | int is_reset_state_file(); 422 | char * get_reset_state_file(); 423 | void set_reset_state_file(const char * str); 424 | 425 | 426 | // ==== USB functions 427 | int switch_usb_powered_freq(); 428 | int usb_powered(); 429 | void usb_acm_on(); 430 | int usb_is_on(); 431 | void usb_turn_off(); 432 | void acm_puts(const char *str); 433 | 434 | // Aux buf 435 | #define AUX_BUF_SIZE (5*512) 436 | 437 | char * aux_buf_ptr(); 438 | void * write_buf_ptr(); 439 | int write_buf_size(); 440 | 441 | // Program info structure 442 | #define PROG_INFO_MAGIC 0xd377C0DE 443 | 444 | void program_main(); 445 | 446 | typedef struct { 447 | uint32_t pgm_magic; 448 | uint32_t pgm_size; 449 | void * pgm_entry; 450 | uint32_t ifc_cnr; 451 | uint32_t ifc_ver; 452 | uint32_t qspi_size; 453 | uint32_t qspi_crc; 454 | char pgm_name[16]; 455 | char pgm_ver[16]; 456 | uint32_t required_keymap_id; 457 | } __packed prog_info_t; 458 | 459 | 460 | // Keyboard 461 | int read_key(int *k1, int *k2); 462 | int sys_last_scan(int *k1, int *k2); 463 | 464 | ///////////////////////////////// 465 | // Low level diagnostics 466 | ///////////////////////////////// 467 | 468 | void suspended_bg_key_read(); 469 | void resume_bg_key_read(); 470 | 471 | // Timer 472 | uint32_t get_tim1_timer(); 473 | 474 | // Base frequency 8MHz 475 | #define TIMER_BASE_FREQ (8000000) 476 | void start_timer2(uint32_t div32); 477 | void start_timer3(uint16_t div16); 478 | void stop_timer2(); 479 | void stop_timer3(); 480 | 481 | // RTC linear reading 482 | #define RTCREGS_SS_PER_SEC 256 483 | 484 | typedef struct { 485 | uint32_t dt; 486 | uint32_t tm; 487 | uint16_t ss; 488 | } rtc_time_regs_t; 489 | 490 | 491 | typedef struct { 492 | rtc_time_regs_t regs; 493 | uint64_t dsec; // julian day * seconds_per_day 494 | uint32_t jday; // julian day 495 | uint32_t sec; // seconds in day 496 | uint32_t msec; // seconds in day corresponding to current minute (for easy sub-minute updates) 497 | } rtc_ticks_stat_t; 498 | 499 | 500 | uint32_t get_rtc_ticks(); 501 | rtc_ticks_stat_t* rtc_update_ticks(); 502 | void rtc_set_alarm(tm_t * tm, dt_t *dt); 503 | void rtc_cancel_alarm(); 504 | 505 | 506 | 507 | // QSPI User area 508 | int qspi_user_write(uint8_t *data, int size, int offset, int erase); 509 | uint8_t * qspi_user_addr(); 510 | int qspi_user_size(); 511 | 512 | 513 | // RESET preserved region 0x10007f00-0x10007fff (L4) 514 | #define RESET_STATE_RAM 0x10007f00 515 | 516 | 517 | 518 | // ---------------------------------- 519 | 520 | 521 | // Printer 522 | #define PRINT_GRA_LN 1 523 | #define PRINT_TXT_LN 0 524 | 525 | #define MAX_82240_WIDTH 166 526 | #define DFLT_82240_LINE_DUR 1800 527 | 528 | void print_byte(uint8_t b); 529 | void print_buffer(uint8_t * buf, int cnt); 530 | int print_is_ready(); 531 | 532 | // Printer delay in ms 533 | uint printer_get_delay(); 534 | void printer_set_delay(uint val); 535 | 536 | 537 | void printer_advance_buf(int what); 538 | int printer_busy_for(int what); 539 | 540 | 541 | // ---------------------------------- 542 | 543 | 544 | // -------------------------------- 545 | // Menu pages 546 | // -------------------------------- 547 | 548 | typedef void void_fn_t(); 549 | 550 | typedef struct { 551 | const char * name; 552 | const uint8_t * items; 553 | const char* const * msg; 554 | void_fn_t * post_disp; 555 | } smenu_t; 556 | 557 | extern const smenu_t MID_SYS_WARN; // System menu entry warning 558 | extern const smenu_t MID_SYSTEM; // System menu 559 | extern const smenu_t MID_FAT_FORMAT; // FAT format menu 560 | extern const smenu_t MID_DSKTST_ENTER; // Disk test menu 561 | extern const smenu_t MID_PROD_DIAG; // Production diagnostic screen 562 | extern const smenu_t MID_PROD_DIAG2; // Production diagnostic screen - selftest version in main menu 563 | extern const smenu_t MID_DMCP; // Top level system menu 564 | extern const smenu_t MID_BASE_SETUP; // System setup menu 565 | extern const smenu_t MID_BAD_KMAP; // Bad keymap menu 566 | 567 | 568 | // -------------------------------- 569 | // Menu items 570 | // app range 0-127 571 | // sys range 128-255 572 | // -------------------------------- 573 | 574 | #define MI_SYSTEM 192 575 | #define MI_BOOTLOADER 193 576 | #define MI_QSPI_LOADER 194 577 | #define MI_DIAG 195 578 | #define MI_MSC 196 579 | #define MI_ABOUT 197 580 | #define MI_BASE_SETUP 198 581 | #define MI_BEEP_MUTE 199 582 | #define MI_SYSTEM_ENTER 200 583 | #define MI_RELOAD_RESET 201 584 | #define MI_SET_TIME 202 585 | #define MI_SET_DATE 203 586 | #define MI_FF_ENTER 204 587 | #define MI_FAT_FORMAT 205 588 | #define MI_DISK_TEST 206 589 | #define MI_DSKTST_ENTER 207 590 | #define MI_DISK_INFO 208 591 | #define MI_LOAD_QSPI 209 592 | #define MI_SLOW_AUTOREP 210 593 | 594 | #define MI_EXIT 211 595 | 596 | #define MI_KBD_TEST 212 597 | #define MI_LCD_TEST 213 598 | #define MI_IR_TEST 214 599 | #define MI_BEEP_TEST 215 600 | #define MI_DMCP_MENU 216 601 | 602 | #define MI_SELF_TEST 217 603 | 604 | #define MI_RAMFLASH 218 605 | 606 | #define MI_PGM_INFO 219 607 | #define MI_PGM_RUN 220 608 | #define MI_PGM_LOAD 221 609 | 610 | #define MI_RUN_DMCP 222 611 | 612 | #define MI_OFF_MODE 223 613 | 614 | #define MI_KMAP_PGM_RUN 224 615 | #define MI_KMAP_DMCP 225 616 | 617 | // -------------------------------- 618 | 619 | 620 | 621 | #define MRET_LEAVELIMIT 512 622 | 623 | 624 | 625 | // -------------------------------- 626 | 627 | #define MENU_MAX_LEVEL 8 628 | 629 | #define MENU_FONT t24 630 | #define MENU_LCD_LINES 8 631 | 632 | #define MENU_RESET 0 633 | #define MENU_ADD 1 634 | 635 | #define MRET_UNIMPL -1 636 | #define MRET_EXIT -2 637 | 638 | // === Date/Time 639 | 640 | #define PRINT_DT_TM_SZ 20 641 | 642 | 643 | void rtc_check_unset(); 644 | void run_set_time(); 645 | void run_set_date(); 646 | 647 | 648 | // === Base dialogs 649 | void disp_disk_info(const char * hdr); 650 | int power_check_screen(); 651 | 652 | 653 | // === Base menu functions === 654 | int handle_menu(const smenu_t * menu_id, int action, int cur_line); 655 | 656 | // === Menu formatting support 657 | const char * rb_str(int val); 658 | const char * sel_str(int val); 659 | char * opt_str(char * s, char const *txt, int val); 660 | char * date_str(char * s, const char * txt); 661 | char * time_str(char * s, const char * txt); 662 | 663 | // === File selection === 664 | 665 | #define MAX_PGM_FN_LEN 24 666 | 667 | typedef int (*file_sel_fn_t)(const char * fpath, const char * fname, void * data); 668 | 669 | int file_selection_screen(const char * title, const char * base_dir, const char * ext, file_sel_fn_t sel_fn, 670 | int disp_new, int overwrite_check, void * data); 671 | 672 | 673 | 674 | 675 | // --------------------------------------------------- 676 | // Item selection screen 677 | // --------------------------------------------------- 678 | 679 | #define ISEL_FILL_ITEMS -100 680 | #define ISEL_KEY_PRESSED -101 681 | #define ISEL_EXIT -102 682 | 683 | #define ISEL_POST_DRAW -2 684 | #define ISEL_PRE_DRAW -1 685 | 686 | typedef uint16_t list_item_t; 687 | 688 | struct item_sel_state; 689 | typedef void isel_disp_line_fn_t(int lnr, list_item_t *fis, int cur_fnr, struct item_sel_state *st); 690 | typedef void fis_name_fn_t(struct item_sel_state *st, list_item_t fis, char * nmbuf, int len); 691 | 692 | 693 | typedef struct item_sel_state { 694 | int fnr; 695 | int top_nr; 696 | int8_t lncnt; // Number of LCD lines available 697 | int8_t roll_lines; 698 | int8_t key; 699 | 700 | list_item_t * fis; 701 | fis_name_fn_t * fis_name_fn; // Used for sorting 702 | int max_items; 703 | int fcnt; 704 | 705 | // -- Set by user -- 706 | const char * title; // Screen title 707 | char * title2; // Optional right part of title 708 | isel_disp_line_fn_t * disp_line_fn; // Line draw function 709 | char * lnbuf; // line buffer if app wants to use it for line drawing 710 | int lnsize; // lnbuf size 711 | 712 | void * data; // Custom data (useful for line draw callback) 713 | void * items; // Custom data for items 714 | 715 | } __packed item_sel_state_t; 716 | 717 | 718 | // Initialize item sel structure 719 | void item_sel_init(item_sel_state_t *st); 720 | void item_sel_reinit(item_sel_state_t *st); 721 | 722 | // upd == 1 -> force repaint 723 | int item_sel_engine(item_sel_state_t *st, int upd); 724 | 725 | // Display header 726 | void item_sel_header(item_sel_state_t *st, int update); 727 | 728 | // --------------------------------------------------- 729 | 730 | void msg_box(disp_stat_t * ds, const char * txt, int inv); 731 | 732 | 733 | int run_menu_item_sys(uint8_t line_id); 734 | 735 | 736 | // ---------------------------------- 737 | 738 | 739 | #define MAX_LCD_LINE_LEN 40 740 | 741 | #define MAX_KEY_NR 37 742 | #define MAX_FNKEY_NR 43 743 | 744 | 745 | // ------------- 746 | // Key codes 747 | // ------------- 748 | 749 | #define KEY_SIGMA 1 750 | #define KEY_INV 2 751 | #define KEY_SQRT 3 752 | #define KEY_LOG 4 753 | #define KEY_LN 5 754 | #define KEY_XEQ 6 755 | #define KEY_STO 7 756 | #define KEY_RCL 8 757 | #define KEY_RDN 9 758 | #define KEY_SIN 10 759 | #define KEY_COS 11 760 | #define KEY_TAN 12 761 | #define KEY_ENTER 13 762 | #define KEY_SWAP 14 763 | #define KEY_CHS 15 764 | #define KEY_E 16 765 | #define KEY_BSP 17 766 | #define KEY_UP 18 767 | #define KEY_7 19 768 | #define KEY_8 20 769 | #define KEY_9 21 770 | #define KEY_DIV 22 771 | #define KEY_DOWN 23 772 | #define KEY_4 24 773 | #define KEY_5 25 774 | #define KEY_6 26 775 | #define KEY_MUL 27 776 | #define KEY_SHIFT 28 777 | #define KEY_1 29 778 | #define KEY_2 30 779 | #define KEY_3 31 780 | #define KEY_SUB 32 781 | #define KEY_EXIT 33 782 | #define KEY_0 34 783 | #define KEY_DOT 35 784 | #define KEY_RUN 36 785 | #define KEY_ADD 37 786 | 787 | #define KEY_F1 38 788 | #define KEY_F2 39 789 | #define KEY_F3 40 790 | #define KEY_F4 41 791 | #define KEY_F5 42 792 | #define KEY_F6 43 793 | 794 | #define KEY_SCREENSHOT 44 795 | #define KEY_SH_UP 45 796 | #define KEY_SH_DOWN 46 797 | 798 | #define KEY_DOUBLE_RELEASE 99 799 | 800 | #define KEY_PAGEUP KEY_DIV 801 | #define KEY_PAGEDOWN KEY_MUL 802 | 803 | 804 | #define IS_EXIT_KEY(k) ( (k) == KEY_EXIT || (k) == KEY_BSP ) 805 | 806 | // ----------------------- 807 | // Bit masks operations 808 | // ----------------------- 809 | #define VAL(x,val) ((x) & (val)) 810 | #define CLR(x,val) val &= ~(x) 811 | #define SET(x,val) val |= (x) 812 | #define MSK(x,val) (~(x) & (val)) 813 | #define SETMSK(x,m,val) val = (MSK(m,val)|(x)) 814 | //#define SETBY(c,x,val) (c) ? SET(x,val) : CLR(x,val) 815 | #define SETBY(c,x,val) if (c) { SET(x,val); } else { CLR(x,val); } 816 | 817 | #define ST(x) VAL(x,calc_state) 818 | #define VAL_ST(x) VAL(x,calc_state) 819 | #define CLR_ST(x) CLR(x,calc_state) 820 | #define SET_ST(x) SET(x,calc_state) 821 | #define SETMSK_ST(x,m) SETMSK(x,m,calc_state) 822 | #define SETBY_ST(c,x) SETBY(c,x,calc_state) 823 | 824 | 825 | 826 | #define STAT_CLEAN_RESET BIT(0) 827 | #define STAT_RUNNING BIT(1) 828 | #define STAT_SUSPENDED BIT(2) 829 | #define STAT_KEYUP_WAIT BIT(3) 830 | #define STAT_OFF BIT(4) 831 | #define STAT_SOFT_OFF BIT(5) 832 | #define STAT_MENU BIT(6) 833 | #define STAT_BEEP_MUTE BIT(7) 834 | #define STAT_SLOW_AUTOREP BIT(8) 835 | #define STAT_PGM_END BIT(9) 836 | #define STAT_CLK_WKUP_ENABLE BIT(10) 837 | #define STAT_CLK_WKUP_SECONDS BIT(11) // 0 - wakeup runner each minute, 1 - each second 838 | #define STAT_CLK_WKUP_FLAG BIT(12) 839 | #define STAT_DMY BIT(13) 840 | #define STAT_CLK24 BIT(14) 841 | #define STAT_POWER_CHANGE BIT(15) 842 | #define STAT_YMD BIT(16) 843 | #define STAT_ALPHA_TAB_Fn BIT(17) // 1 - alpha table contains also Fn keys (First row) 844 | 845 | 846 | #define STAT_HW_BEEP BIT(28) 847 | #define STAT_HW_USB BIT(29) 848 | #define STAT_HW_IR BIT(30) 849 | 850 | #define STAT_HW (STAT_HW_BEEP | STAT_HW_USB | STAT_HW_IR) 851 | 852 | 853 | // Screenshots 854 | #define SCR_DIR "/SCREENS" 855 | 856 | // Power OFF images 857 | #define OFFIMG_DIR "/OFFIMG" 858 | 859 | // Help 860 | #define HELP_INDEX "/HELP/index.htm" 861 | #define HELP_DIR "/HELP" 862 | #define HELP_EXT_MASK "*.htm*" 863 | 864 | // Screenshot 865 | int create_screenshot(int report_error); 866 | 867 | 868 | // --------------------------- 869 | // Key buffer functions 870 | // --------------------------- 871 | int key_empty(); 872 | int key_push(int k1); 873 | int key_tail(); 874 | int key_pop(); 875 | int key_pop_last(); 876 | void key_pop_all(); 877 | 878 | 879 | // Key functions 880 | int key_to_nr(int key); 881 | void wait_for_key_press(); 882 | int runner_get_key(int *repeat); 883 | int runner_get_key_delay(int *repeat, uint timeout, uint rep0, uint rep1, uint rep1tout); 884 | void wait_for_key_release(int tout); 885 | 886 | 887 | 888 | // --------------------------- 889 | // Runner get key 890 | // --------------------------- 891 | 892 | int runner_key_tout_value(const int first); 893 | void runner_key_tout_init(const int slow); 894 | 895 | 896 | // Autorepeat 897 | int toggle_slow_autorepeat(); 898 | int is_slow_autorepeat(); 899 | 900 | // Auto off 901 | void reset_auto_off(); 902 | int is_auto_off(); 903 | int is_menu_auto_off(); 904 | int sys_auto_off_cnt(); 905 | 906 | // Time/date 907 | void print_dmy_date(char * s, int const sz, dt_t *dt, const char * append, int shortmon, char sep_arg); 908 | void print_clk24_time(char * t, int const sz, tm_t *tm, int disp_sec, int disp_dow); 909 | 910 | 911 | // Check and create dir 912 | // returns 0 on success 913 | int check_create_dir(const char * dir); 914 | 915 | // Set disk label 916 | void set_fat_label(const char * label); 917 | 918 | int file_exists(const char * fn); 919 | 920 | // Returns -1 if file doesn't exist 921 | int file_size(const char * fn); 922 | 923 | int sys_disk_ok(); 924 | int sys_disk_write_enable(int val); 925 | void sys_disk_check_valid(); 926 | int sys_is_disk_write_enable(); 927 | 928 | void sys_clear_write_buf_used(); 929 | int sys_write_buf_used(); 930 | 931 | 932 | // System timers 933 | void sys_timer_disable(int timer_ix); 934 | void sys_timer_start(int timer_ix, uint32_t ms_value); 935 | int sys_timer_active(int timer_ix); 936 | int sys_timer_timeout(int timer_ix); 937 | 938 | // Millisecond delay 939 | void sys_delay(uint32_t ms_delay); 940 | 941 | // Current systick count 942 | uint32_t sys_tick_count(); 943 | uint32_t sys_current_ms(); 944 | 945 | // Critical sections 946 | void sys_critical_start(); 947 | void sys_critical_end(); 948 | 949 | // Sleep 950 | void sys_sleep(); 951 | 952 | // Free memory 953 | int sys_free_mem(); 954 | int sys_largest_free_mem(); 955 | 956 | // System 957 | void sys_reset(); 958 | 959 | // Key 960 | int sys_last_key(); 961 | 962 | // Aux file 963 | void make_date_filename(char * str, const char * dir, const char * ext); 964 | 965 | 966 | // --------------------------- 967 | // Flashing 968 | // --------------------------- 969 | 970 | // Enable flashing 971 | void sys_flashing_init(); 972 | // Disable flashing 973 | void sys_flashing_finish(); 974 | 975 | // Expects address and size aligned with flash block size 976 | // Returns 0 on success 977 | int sys_flash_erase_block(void* start_addr, uint32_t size); 978 | 979 | // Expects destination address and size are multiples of 8 980 | // Returns 0 on success 981 | int sys_flash_write_block(void* dst_addr, uint8_t * src_buf, uint32_t size); 982 | 983 | 984 | // --------------------------- 985 | // QR code 986 | // --------------------------- 987 | 988 | void qrcode_disp(QRCode *qr, int xo, int yo, int z); 989 | 990 | 991 | // --------------------------- 992 | // System timers 993 | // --------------------------- 994 | 995 | #define SYSTIM_COUNT 4 996 | 997 | 998 | // ---------------------------------- 999 | 1000 | 1001 | void run_help(); 1002 | void run_help_file(const char * help_file); 1003 | 1004 | 1005 | 1006 | typedef void user_style_fn_t(char *s, disp_stat_t *ds); 1007 | 1008 | void run_help_file_style(const char * help_file, user_style_fn_t *user_style_fn); 1009 | 1010 | 1011 | // ---------------------------------- 1012 | 1013 | 1014 | // Off images 1015 | void draw_power_off_image(int allow_errors); 1016 | void reset_off_image_cycle(); 1017 | 1018 | #define BG_COL_PAPER 0xf4f2dc 1019 | #define BG_COL_LCD 0xdff5cc 1020 | 1021 | int update_bmp_file_header(FIL* fp, int width, int height, uint32_t bg_color); 1022 | 1023 | 1024 | // ---------------------------------- 1025 | 1026 | 1027 | #include "lft_ifc.h" 1028 | 1029 | #endif 1030 | -------------------------------------------------------------------------------- /dm/dm42_menu.cc: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BSD 3-Clause License 4 | 5 | Copyright (c) 2015-2025, SwissMicros 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | The software and related material is released as “NOMAS” (NOt MAnufacturer Supported). 35 | 36 | 1. Info is released to assist customers using, exploring and extending the product 37 | 2. Do NOT contact the manufacturer with questions, seeking support, etc. regarding 38 | NOMAS material as no support is implied or committed-to by the Manufacturer 39 | 3. The Manufacturer may reply and/or update materials if and when needed solely 40 | at their discretion 41 | 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | 48 | #include "core_main.h" 49 | #include "core_aux.h" 50 | 51 | 52 | extern "C" { 53 | 54 | #include 55 | #include 56 | 57 | #include 58 | #include 59 | 60 | 61 | // Possibility to override default 62 | #ifdef printf 63 | //#undef printf 64 | #endif 65 | 66 | 67 | void after_fat_format_dm42() { 68 | if ( sys_disk_ok() ) { 69 | set_fat_label("DM42"); 70 | check_create_dir(PGM_DIR); // Create /PROGRAMS directory 71 | check_create_dir(STATE_DIR); // Create /STATE directory 72 | 73 | check_create_dir(SCR_DIR); // Create /SCREENS directory 74 | check_create_dir(OFFIMG_DIR); // Create /OFFIMG directory 75 | check_create_dir(HELP_DIR); // Create /HELP directory 76 | check_create_dir(PRINT_DIR); // Create /PRINTS directory 77 | } 78 | } 79 | 80 | 81 | 82 | /* 83 | ▄ ▄ ▄▀▀ ▄ ▀ 84 | ██ ██ ▄▄▄ ▄ ▄▄ ▄ ▄ ▄▄█▄▄ ▄ ▄ ▄ ▄▄ ▄▄▄ ▄▄█▄▄ ▄▄▄ ▄▄▄ ▄ ▄▄ ▄▄▄ 85 | █ ██ █ █▀ █ █▀ █ █ █ █ █ █ █▀ █ █▀ ▀ █ █ █▀ ▀█ █▀ █ █ ▀ 86 | █ ▀▀ █ █▀▀▀▀ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ▀▀▀▄ 87 | █ █ ▀█▄▄▀ █ █ ▀▄▄▀█ █ ▀▄▄▀█ █ █ ▀█▄▄▀ ▀▄▄ ▄▄█▄▄ ▀█▄█▀ █ █ ▀▄▄▄▀ */ 88 | 89 | 90 | #ifndef TESTL 91 | 92 | int lcd_for_dm42(int what) { 93 | int refresh = 1; 94 | 95 | lcd_clear_buf(); 96 | lcd_writeClr(t24); 97 | 98 | switch ( what ) { 99 | case DISP_CALC: 100 | refresh = 0; // Just empty screen 101 | break; 102 | 103 | case DISP_ALLOC_FAIL: 104 | lcd_putsR(t24, "Free42 Memory Allocation Fail"); 105 | t24->y += 4; 106 | lcd_puts(t24, "Unhandled memory allocation:"); 107 | break; 108 | 109 | case DISP_PRBUF_ALLOC_FAIL: 110 | lcd_putsR(t24, "Print Buffer Fail"); 111 | t24->y += 4; 112 | lcd_puts(t24, "Cannot prepare buffer for"); 113 | lcd_puts(t24, "printing to file."); 114 | lcd_puts(t24, "ERROR:"); 115 | break; 116 | 117 | 118 | case DISP_NO_PGM_SEL: 119 | lcd_putsR(t24, "Select Programs"); 120 | t24->y += 4; 121 | lcd_putsAt(t24, 3, "No program selected"); 122 | lcd_putsAt(t24, 7, "Press any key to continue..."); 123 | break; 124 | 125 | case DISP_LOADING_STATE: 126 | lcd_putsR(t24, "Loading from File"); 127 | lcd_putsAt(t24, 3, "Loading calculator state ..."); 128 | break; 129 | 130 | case DISP_SAVING_STATE: 131 | lcd_putsR(t24, "Saving to File"); 132 | lcd_putsAt(t24, 3, "Saving calculator state ..."); 133 | break; 134 | 135 | case DISP_SAVE_FAILED: 136 | lcd_putsR(t24, "Save State Error"); 137 | lcd_putsAt(t24, 2,"Calculator state save failed."); 138 | lcd_putsAt(t24, 3,"Check the FAT filesystem."); 139 | lcd_putsAt(t24, 4,"Disk full or too many"); 140 | lcd_putsAt(t24, 5,"root directory items?"); 141 | lcd_putsAt(t24, 7," Press EXIT key to continue..."); 142 | break; 143 | #if 0 144 | case DISP_NEW_HELP: 145 | lcd_putsR(t24, "Missing help file"); 146 | lcd_puts(t24, ""); 147 | lcd_puts(t24, "Help file /HELP/dm42help.htm is"); 148 | lcd_puts(t24, "missing. Please, download it from"); 149 | lcd_puts(t24, "https://www.swissmicros.com/dm42/"); 150 | lcd_puts(t24, "fat/HELP/"); 151 | lcd_puts(t24, "and place it into /HELP/ directory."); 152 | t24->y = LCD_Y; lcd_prevLn(t24); 153 | lcd_puts(t24, " Press any key to continue..."); 154 | break; 155 | #endif 156 | case DISP_ABOUT: 157 | // Just base of original system about 158 | t24->y = lcd_for_calc(DISP_ABOUT); 159 | lcd_puts(t24,""); //4 160 | lcd_prevLn(t24); 161 | // -- 162 | 163 | int h2 = lcd_lineHeight(t20)/2; 164 | lcd_setXY(t20, t24->x, t24->y); 165 | t20->y += h2-5; 166 | lcd_print(t20, "DM42 v" DM42_VERSION " (C) SwissMicros GmbH"); 167 | t20->y += h2; 168 | lcd_print(t20, "%s (C) 2004-2025, Thomas Okken", free42_version_str()); 169 | t20->y += h2; 170 | lcd_puts(t20, "Intel Decimal FloatingPointMath Lib v2.0u1"); 171 | lcd_puts(t20, " (C) 2007-2018, Intel Corp."); 172 | 173 | t20->y = LCD_Y - lcd_lineHeight(t20); 174 | lcd_putsR(t20, " Press EXIT key to continue..."); 175 | break; 176 | 177 | } 178 | 179 | if (refresh) 180 | lcd_refresh(); 181 | 182 | return t24->y; 183 | } 184 | 185 | 186 | // --------------------------------------------------- 187 | // Help File 188 | // --------------------------------------------------- 189 | 190 | 191 | void draw_helpfile_qrcode() { 192 | const int QRver = 4; 193 | const int QRecc = ECC_MEDIUM; 194 | QRCode qrcode; 195 | uint8_t *qrcodeBytes = (uint8_t*)aux_buf_ptr()+512; 196 | 197 | char *buf = aux_buf_ptr(); 198 | strcpy(buf, "https://technical.swissmicros.com/dm42/fat/HELP/"); 199 | 200 | // Encode and display 201 | qrcode_initText(&qrcode, qrcodeBytes, QRver, QRecc, buf); 202 | qrcode_disp(&qrcode, 208,36, 5); 203 | } 204 | 205 | 206 | #define DM42_HELP_FILE "/HELP/dm42help.htm" 207 | 208 | 209 | void no_help_file() { 210 | int upd = 1; 211 | 212 | for(;;) { 213 | if (upd) { 214 | lcd_writeClr(t24); 215 | lcd_clear_buf(); 216 | 217 | lcd_putsR(t24, "Missing help file"); 218 | t24->y += 8; 219 | 220 | if (upd == 1) { 221 | // |012345678901234567| 222 | lcd_puts(t24, "File dm42help.htm"); 223 | lcd_puts(t24, "is missing. Please,"); 224 | lcd_puts(t24, "download it and "); 225 | lcd_puts(t24, "place it into "); 226 | lcd_puts(t24, "/HELP/ directory."); 227 | draw_helpfile_qrcode(); 228 | } else { 229 | lcd_puts(t24, "Help file /HELP/dm42help.htm is"); 230 | lcd_puts(t24, "missing. Please, download it from"); 231 | lcd_puts(t24, "https://technical.swissmicros.com/"); 232 | lcd_puts(t24, "dm42/fat/HELP/"); 233 | lcd_puts(t24, "and place it into /HELP/ directory."); 234 | } 235 | //t24->y = LCD_Y; lcd_prevLn(t24); 236 | //lcd_puts(t24, " Press any key to continue..."); 237 | 238 | const char * menu[] = {"QR","URL","","","",""}; 239 | lcd_draw_menu_keys(menu); 240 | lcd_refresh(); 241 | 242 | upd = 0; 243 | wait_for_key_release(-1); 244 | } 245 | 246 | int k1 = runner_get_key(NULL); 247 | if ( IS_EXIT_KEY(k1) || k1 == KEY_ENTER) 248 | return; 249 | if ( is_menu_auto_off() ) 250 | return; 251 | if ( k1 == KEY_F1 ) upd = 1; 252 | if ( k1 == KEY_F2 ) upd = 2; 253 | } 254 | } 255 | 256 | 257 | 258 | 259 | void start_help() { 260 | 261 | // Check whether DM42_HELP_FILE exists 262 | if (!file_exists(DM42_HELP_FILE)) { 263 | if (file_exists(HELP_INDEX)) { 264 | // Rename old help file to new one 265 | sys_disk_write_enable(1); 266 | f_rename(HELP_INDEX, DM42_HELP_FILE); 267 | sys_disk_write_enable(0); 268 | } else { 269 | // No help file -> display note 270 | //lcd_for_dm42(DISP_NEW_HELP); wait_for_key_press(); 271 | no_help_file(); 272 | return; 273 | } 274 | } 275 | run_help_file(DM42_HELP_FILE); 276 | } 277 | 278 | 279 | 280 | int pgm_import_enter(const char * fpath, const char * fname, void * data) { 281 | FRESULT res; 282 | 283 | lcd_puts(t24,"Loading ..."); 284 | lcd_puts(t24, fname); lcd_refresh(); 285 | res = f_open(ppgm_fp, fpath, FA_READ); 286 | if ( res != FR_OK ) { 287 | // Print fail 288 | lcd_puts(t24,"Fail to open."); lcd_refresh(); 289 | lcd_refresh(); 290 | wait_for_key_press(); 291 | } else { 292 | 293 | #ifdef FREE42_PRE_2016_IFC 294 | core_import_programs(NULL); 295 | #else 296 | init_sf_buf(); 297 | core_import_programs(0, NULL); 298 | deinit_sf_buf(); 299 | #endif 300 | 301 | f_close(ppgm_fp); 302 | if (pgm_res) { 303 | lcd_print(t24, "Fail - %i", pgm_res); 304 | lcd_refresh(); 305 | wait_for_key_press(); 306 | } else { 307 | lcd_puts(t24, "Success"); 308 | lcd_refresh(); 309 | sys_delay(1500); 310 | } 311 | } 312 | 313 | return 0; // Continue in the file list 314 | } 315 | 316 | 317 | 318 | 319 | int pgm_export_enter(const char * fpath, const char * fname, void * data) { 320 | 321 | pgm_import_sel_t * pgm_sel = (pgm_import_sel_t*)data; 322 | int res; 323 | 324 | lcd_writeClr(t24); 325 | lcd_clear_buf(); 326 | lcd_putsR(t24,"Program Export"); 327 | t24->ln_offs = 8; 328 | 329 | lcd_putsAt(t24,3,"Saving ..."); 330 | lcd_puts(t24, fpath); 331 | lcd_refresh(); 332 | 333 | sys_disk_write_enable(1); 334 | res = f_open(ppgm_fp, fpath, FA_WRITE|FA_CREATE_ALWAYS); 335 | if ( res != FR_OK ) { 336 | sys_disk_write_enable(0); 337 | lcd_puts(t24,"Fail to open."); lcd_refresh(); 338 | lcd_refresh(); 339 | if ( sys_disk_ok() ) 340 | wait_for_key_press(); 341 | } else { 342 | #ifdef FREE42_PRE_2016_IFC 343 | res = core_export_programs(pgm_sel->pgm_cnt, pgm_sel->pgm_indices, NULL); 344 | #else 345 | init_sf_buf(); 346 | core_export_programs(pgm_sel->pgm_cnt, pgm_sel->pgm_indices, NULL); 347 | deinit_sf_buf(); 348 | res = 0; 349 | #endif 350 | f_close(ppgm_fp); 351 | sys_disk_write_enable(0); 352 | if (res || pgm_res) { 353 | lcd_print(t24, "Fail - %i", pgm_res); 354 | lcd_refresh(); 355 | if ( sys_disk_ok() ) 356 | wait_for_key_press(); 357 | } else { 358 | lcd_puts(t24,"Success"); 359 | lcd_refresh(); 360 | sys_delay(1000); 361 | } 362 | } 363 | 364 | return MRET_EXIT; 365 | } 366 | 367 | 368 | 369 | 370 | void run_reset_state_file() { 371 | lcd_writeClr(t24); 372 | lcd_clear_buf(); 373 | lcd_putsR(t24,"Calculator State"); 374 | t24->ln_offs = 8; 375 | 376 | lcd_puts(t24, "You are about to reset calculator"); 377 | lcd_puts(t24, "state."); 378 | lcd_puts(t24, ""); 379 | lcd_puts(t24, "WARNING: Current calculator state"); 380 | lcd_puts(t24, "will be lost."); 381 | lcd_puts(t24, ""); 382 | lcd_puts(t24, ""); 383 | //lcd_puts(t24, "Are you sure to proceed?"); 384 | lcd_puts(t24, "Press [ENTER] to confirm."); 385 | lcd_refresh(); 386 | 387 | wait_for_key_release(-1); 388 | 389 | for(;;) { 390 | int k1 = runner_get_key(NULL); 391 | if ( IS_EXIT_KEY(k1) ) 392 | return; 393 | if ( is_menu_auto_off() ) 394 | return; 395 | if ( k1 == KEY_ENTER ) 396 | break; // Proceed with reset 397 | } 398 | 399 | // Reset statefile name for next load 400 | set_reset_state_file(""); 401 | 402 | // Reset the system to force new statefile load 403 | set_reset_magic(NO_SPLASH_MAGIC); 404 | sys_reset(); 405 | } 406 | 407 | 408 | int load_statefile(const char * fpath, const char * fname, void * data) { 409 | 410 | lcd_puts(t24, "Calculator state file:"); 411 | lcd_puts(t24, fname); 412 | 413 | int res = savestat_check_read(fpath); 414 | if (res < 0) { 415 | // Bad file or read/write problem 416 | 417 | lcd_puts(t24, ""); 418 | lcd_puts(t24, "ERROR: Cannot read the file"); 419 | lcd_puts(t24, "Not a state file or filesystem error."); 420 | lcd_puts(t24, ""); 421 | lcd_puts(t24, ""); 422 | lcd_puts(t24, "Press any key to continue"); 423 | lcd_refresh(); 424 | 425 | wait_for_key_press(); 426 | 427 | return 0; 428 | } 429 | 430 | 431 | // 'Sure' dialog 432 | lcd_puts(t24, ""); 433 | lcd_puts(t24, "WARNING: Current calculator state"); 434 | lcd_puts(t24, "will be lost."); 435 | lcd_puts(t24, ""); 436 | lcd_puts(t24, ""); 437 | //lcd_puts(t24, "Are you sure to load this file?"); 438 | lcd_puts(t24, "Press [ENTER] to confirm."); 439 | lcd_refresh(); 440 | 441 | wait_for_key_release(-1); 442 | 443 | for(;;) { 444 | int k1 = runner_get_key(NULL); 445 | if ( IS_EXIT_KEY(k1) ) 446 | return 0; // Continue the selection screen 447 | if ( is_menu_auto_off() ) 448 | return MRET_EXIT; // Leave selection screen 449 | if ( k1 == KEY_ENTER ) 450 | break; // Proceed with load 451 | } 452 | 453 | lcd_putsRAt(t24, 6, " Loading ..."); 454 | lcd_refresh_wait(); 455 | 456 | 457 | // Store statefile name for next load 458 | set_reset_state_file(fpath); 459 | 460 | // Reset the system to force new statefile load 461 | set_reset_magic(NO_SPLASH_MAGIC); 462 | sys_reset(); 463 | 464 | // Never return here... 465 | return 0; 466 | } 467 | 468 | #endif 469 | 470 | 471 | #define RESET_STATE_FILE_SIZE 0x38 472 | 473 | 474 | int save_statefile(const char * fpath, const char * fname, void * data) { 475 | 476 | lcd_puts(t24,"Saving state ..."); 477 | 478 | char ff[RESET_STATE_FILE_SIZE]; 479 | const char *fp = fpath; 480 | 481 | // Display correct short name 482 | strcpy(ff, fname); 483 | ff[strlen(fname)-3] = 'f'; 484 | lcd_puts(t24, ff); lcd_refresh(); 485 | 486 | int flen = strlen(fpath); 487 | if (flen < RESET_STATE_FILE_SIZE && fpath[flen-3] != 'f') { 488 | // Fix filename: .s42 -> .f42 489 | strcpy(ff, fpath); 490 | ff[flen-3] = 'f'; 491 | 492 | if (file_exists(fpath)) { 493 | sys_disk_write_enable(1); 494 | f_rename(fpath, ff); 495 | sys_disk_write_enable(0); 496 | } 497 | fp = ff; 498 | } 499 | 500 | // Store the state file name 501 | set_reset_state_file(fp); 502 | 503 | wait_for_key_release(-1); 504 | 505 | // Exit with appropriate code to force statefile save 506 | return MRET_SAVESTATE; 507 | } 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | STATIC_ASSERT( (AUX_BUF_PGM_LIST_SIZE+AUX_BUF_SELS_SIZE) <= AUX_BUF_SIZE, "(AUX_BUF_PGM_LIST_SIZE+AUX_BUF_SELS_SIZE) <= AUX_BUF_SIZE"); 517 | 518 | 519 | 520 | #ifndef TESTL 521 | 522 | int select_programs(const char * title, int * pgm_indices, int * pgm_cnt) { 523 | char bb[32]; 524 | int k1; 525 | int upd = 1; // Repaint at first pass 526 | 527 | // Disp state 528 | int first_ix = 0, cur_ix = 0, a, ix; 529 | int pix; // Program index in display loop 530 | char * p; // Program name in display loop 531 | int sel_ln = 0; 532 | 533 | // We need rather big buffer ... use aux memory buffer for that 534 | const uint pgm_list_size = AUX_BUF_PGM_LIST_SIZE; 535 | const uint sels_size = AUX_BUF_SELS_SIZE; 536 | const uint max_disp_pgm_char = 24; 537 | const int pgm_lines = 7; 538 | 539 | char * buf = aux_buf_ptr(); 540 | char * sels = buf + pgm_list_size; 541 | 542 | // Read program list 543 | int pgm_count = core_list_programs(buf,pgm_list_size); 544 | 545 | // Clear selections 546 | *pgm_cnt = 0; 547 | bzero(sels, sels_size); 548 | 549 | // Display title 550 | lcd_writeClr(t24); 551 | lcd_clear_buf(); 552 | lcd_putsR(t24,title); 553 | t24->ln_offs = 8; 554 | 555 | for(;;) { 556 | k1 = runner_get_key(NULL); 557 | if ( IS_EXIT_KEY(k1) ) break; 558 | if ( is_menu_auto_off() ) break; 559 | 560 | switch (k1) { 561 | case KEY_F1: // A - Sel 562 | case KEY_F6: // F - Sel 563 | if ( *pgm_cnt == MAX_PGM_SEL && !sels[cur_ix] ) { 564 | // Too much selections 565 | lcd_putsRAt(t24,sel_ln,"Max. nr. of selections is " STR(MAX_PGM_SEL)); 566 | lcd_refresh(); 567 | sys_delay(1000); 568 | } else { 569 | sels[cur_ix] = !sels[cur_ix]; 570 | if(sels[cur_ix]) pgm_cnt[0]++; else pgm_cnt[0]--; 571 | } 572 | upd=1; 573 | break; 574 | case KEY_F2: // B - 575 | break; 576 | case KEY_F3: // C - C-All 577 | // Clear selections 578 | *pgm_cnt = 0; 579 | bzero(sels,sels_size); 580 | upd=1; 581 | break; 582 | case KEY_F4: // D - S-All 583 | if ( pgm_count > MAX_PGM_SEL ) { 584 | lcd_putsRAt(t24,sel_ln,"Max. nr. of selections is " STR(MAX_PGM_SEL)); 585 | lcd_refresh(); 586 | sys_delay(1000); 587 | } else { 588 | *pgm_cnt = pgm_count; 589 | for(a=0; a 0) { 599 | cur_ix--; 600 | } else { 601 | cur_ix = pgm_count-1; 602 | } 603 | upd=1; 604 | break; 605 | 606 | case KEY_DOWN: 607 | if (cur_ix+1 < pgm_count) { 608 | cur_ix++; 609 | } else { 610 | cur_ix = 0; 611 | } 612 | upd=1; 613 | break; 614 | 615 | case KEY_PAGEUP: 616 | if (cur_ix == 0) { 617 | cur_ix = pgm_count-1; 618 | } else { 619 | cur_ix--; 620 | cur_ix -= cur_ix % pgm_lines; 621 | } 622 | upd=1; 623 | break; 624 | 625 | case KEY_PAGEDOWN: 626 | if ( cur_ix == pgm_count-1) { 627 | cur_ix = 0; 628 | } else { 629 | cur_ix += pgm_lines; 630 | cur_ix -= cur_ix % pgm_lines; 631 | if ( cur_ix >= pgm_count ) 632 | cur_ix = pgm_count-1; 633 | else 634 | first_ix = cur_ix; 635 | } 636 | upd=1; 637 | break; 638 | 639 | case KEY_ENTER: 640 | // Fill output data 641 | ix=0; 642 | for(a=0; a (pgm_lines-1)) first_ix = cur_ix - (pgm_lines-1); 655 | if (first_ix + pgm_lines >= pgm_count ) first_ix = pgm_count - pgm_lines; 656 | if (first_ix < 0) first_ix = 0; 657 | 658 | p = buf; pix = 0; sel_ln = 0; 659 | for(a=0; a max_disp_pgm_char ) { 669 | ix = strlen(bb); 670 | memcpy(bb+ix,p,max_disp_pgm_char); 671 | strcpy(bb+ix+max_disp_pgm_char, "..."); 672 | } else { 673 | strcat(bb,p); 674 | } 675 | 676 | if ( pix == cur_ix ) { 677 | lcd_putsRAt(t24,a,bb); 678 | sel_ln = a; 679 | } else { 680 | lcd_putsAt(t24,a,bb); 681 | } 682 | 683 | } 684 | 685 | // DEBUG 686 | printf("pgm_cnt=%i sel_ln=%i\n", *pgm_cnt, sel_ln); 687 | 688 | // Menu line 689 | //t24->y = LCD_Y - lcd_lineHeight(t24); 690 | //lcd_putsR(t24, " Sel | |C-All|S-All| | Sel"); 691 | const char * menu[] = {" Sel","","C-All","S-All","","Sel"}; 692 | lcd_draw_menu_keys(menu); 693 | 694 | // display 695 | lcd_refresh(); 696 | } 697 | } 698 | return 1; 699 | } 700 | 701 | 702 | 703 | 704 | void pgm_export() { 705 | int res; 706 | 707 | // Don't pass through if the power is insufficient 708 | if ( power_check_screen() ) 709 | return; 710 | 711 | wait_for_key_release(-1); 712 | 713 | if ( check_create_dir(PGM_DIR) ) { 714 | lcd_puts(t24,"Cannot access " PGM_DIR); lcd_refresh(); 715 | wait_for_key_press(); 716 | return; 717 | } 718 | 719 | if ( !sys_disk_ok() ) goto pgm_exp_fail; 720 | 721 | char pgm_fn[11+MAX_PGM_FN_LEN+1]; 722 | pgm_import_sel_t pgm_sel; 723 | 724 | strcpy(pgm_fn,PGM_DIR); 725 | strcat(pgm_fn,"/"); 726 | 727 | res = select_programs("Select Programs", pgm_sel.pgm_indices, &pgm_sel.pgm_cnt); 728 | if ( res != 0 || pgm_sel.pgm_cnt == 0 ) { 729 | lcd_for_dm42(DISP_NO_PGM_SEL); 730 | wait_for_key_press(); 731 | return; 732 | } 733 | 734 | //void file_selection_screen(const char * title, const char * base_dir, const char * ext, file_sel_fn_t sel_fn, int disp_new, void * data) 735 | file_selection_screen("Program Export Filename", PGM_DIR, PGM_EXT, pgm_export_enter, 1, 1, &pgm_sel); 736 | 737 | pgm_exp_fail: 738 | sys_disk_check_valid(); // Unmount drive if disk is invalid 739 | if ( !sys_disk_ok() ) { 740 | disp_disk_info("Program Export"); 741 | wait_for_key_press(); 742 | } 743 | } 744 | 745 | 746 | #endif 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | /* 756 | ▄ ▄ ▄ 757 | ██ ██ ▄▄▄ ▄ ▄▄ ▄ ▄ ▄▄▄ ▄ ▄ ▄▄▄ ▄▄█▄▄ ▄▄▄ ▄▄▄▄▄ 758 | █ ██ █ █▀ █ █▀ █ █ █ █ ▀ ▀▄ ▄▀ █ ▀ █ █▀ █ █ █ █ 759 | █ ▀▀ █ █▀▀▀▀ █ █ █ █ ▀▀▀▄ █▄█ ▀▀▀▄ █ █▀▀▀▀ █ █ █ 760 | █ █ ▀█▄▄▀ █ █ ▀▄▄▀█ ▀▄▄▄▀ ▀█ ▀▄▄▄▀ ▀▄▄ ▀█▄▄▀ █ █ █ 761 | ▄▀ 762 | ▀▀ */ 763 | 764 | 765 | 766 | 767 | const uint8_t mid_menu[] = { 768 | MI_FILE, 769 | MI_STATEFILE, 770 | MI_PRINT_MENU, 771 | MI_SETTINGS, 772 | MI_SYSTEM_ENTER, 773 | MI_ABOUT_PGM, 774 | // MI_DEVEL_TEST, 775 | 0 }; // Terminator 776 | 777 | 778 | const uint8_t mid_file[] = { 779 | MI_LOAD_PGM, 780 | MI_SAVE_PGM, 781 | MI_MSC, 782 | MI_DISK_INFO, 783 | 0 }; // Terminator 784 | 785 | 786 | const uint8_t mid_print[] = { 787 | MI_PRTOF_GRAPH, 788 | MI_PRTOF_TEXT, 789 | MI_PRTOF_GR_IN_TXT, 790 | #ifndef TESTL 791 | MI_PRTOF_NOIR, 792 | #endif 793 | MI_PRINT_DBLNL, 794 | 0 }; // Terminator 795 | 796 | 797 | const uint8_t mid_statefile[] = { 798 | MI_LOAD_STATE, 799 | MI_SAVE_STATE, 800 | MI_CLEAN_RESET, 801 | 0 }; // Terminator 802 | 803 | 804 | 805 | 806 | const uint8_t mid_settings[] = { 807 | MI_SET_TIME, 808 | MI_SET_DATE, 809 | #ifndef TESTL 810 | MI_TOPBAR_MENU, 811 | MI_STACK_AREA, 812 | #endif 813 | MI_BEEP_MUTE, 814 | MI_SLOW_AUTOREP, 815 | #ifndef TESTL 816 | MI_STACK_CONFIG, 817 | #endif 818 | MI_F42CONF_MENU, 819 | 0 }; // Terminator 820 | 821 | 822 | const uint8_t mid_f42conf[] = { 823 | MI_DYNSTACKEXT, 824 | MI_F42C_MXSING, 825 | MI_F42C_MXOVFL, 826 | 0 }; // Terminator 827 | 828 | 829 | const uint8_t mid_topbar[] = { 830 | MI_DISP_STATFN, 831 | MI_DISP_DOW, 832 | MI_DISP_DATE, 833 | MI_DISP_DATE_SEP, 834 | MI_DISP_SHORTMON, 835 | MI_DISP_TIME, 836 | MI_DISP_VOLTAGE, 837 | 0 }; // Terminator 838 | 839 | 840 | const uint8_t mid_stack_area[] = { 841 | MI_SA_REG_X, 842 | MI_SA_REG_Y, 843 | MI_SA_REG_Z, 844 | MI_SA_REG_T, 845 | MI_SA_REG_L, 846 | MI_SA_REG_A, 847 | 0 }; // Terminator 848 | 849 | 850 | const uint8_t mid_stack[] = { 851 | MI_STACK_XYZTL, 852 | MI_STACK_XYZTA, 853 | MI_STACK_XYZT, 854 | MI_STACK_XYL, 855 | MI_STACK_XYA, 856 | MI_STACK_XY, 857 | MI_STACK_LXYZT, 858 | 0 }; // Terminator 859 | 860 | 861 | 862 | 863 | int stack_menu_index() { 864 | const uint8_t ixs[] = { 865 | STACK_XYZTL, 866 | STACK_XYZTA, 867 | STACK_XYZT, 868 | STACK_XYL, 869 | STACK_XYA, 870 | STACK_XY, 871 | STACK_LXYZT, 872 | 0 }; // Terminator 873 | int ix = 0; 874 | int sl = get_stack_layout(); 875 | 876 | for(ix=0; ixs[ix]; ix++) 877 | if (ixs[ix] == sl) 878 | return ix; 879 | 880 | return 0; 881 | } 882 | 883 | 884 | 885 | const char* const f42conf_info[] = { 886 | // 123456789012345678901234567890| 887 | "NSTK activates Big Stack", 888 | "4STK returns to the XYZT mode", 889 | NULL 890 | }; 891 | 892 | 893 | const smenu_t MID_MENU = { "Setup", mid_menu, NULL, NULL }; 894 | const smenu_t MID_FILE = { "File", mid_file, NULL, NULL }; 895 | const smenu_t MID_PRINT = { "Printing", mid_print, NULL, NULL }; 896 | const smenu_t MID_SETTINGS = { "Settings", mid_settings, NULL, NULL}; 897 | const smenu_t MID_F42CONF = { "Free42 configuration", mid_f42conf, f42conf_info, NULL}; 898 | const smenu_t MID_STACK_CONFIG = { "Stack Layout", mid_stack, NULL, NULL}; 899 | const smenu_t MID_STATEFILE = { "Calculator State", mid_statefile, NULL, NULL}; 900 | const smenu_t MID_TOPBAR = { "Status Bar", mid_topbar, NULL, NULL}; 901 | const smenu_t MID_STACK_AREA = { "Stack Area", mid_stack_area, NULL, NULL}; 902 | 903 | 904 | // ---------------------------------------------------------------------------------- 905 | 906 | 907 | 908 | 909 | 910 | // Prototypes 911 | 912 | 913 | 914 | 915 | int run_menu_item(uint8_t line_id) { 916 | int ret = 0; 917 | 918 | switch(line_id) { 919 | //void file_selection_screen(const char * title, const char * base_dir, const char * ext, file_sel_fn_t sel_fn, int disp_new, void * data) 920 | case MI_LOAD_PGM: 921 | //pgm_import(); 922 | ret = file_selection_screen("Program Import", PGM_DIR, PGM_EXT, pgm_import_enter, 0, 0, NULL); 923 | if (ret == MRET_EXIT) ret = 0; 924 | break; 925 | case MI_SAVE_PGM: 926 | pgm_export(); 927 | break; 928 | case MI_LOAD_STATE: 929 | ret = file_selection_screen("Load Calculator State", STATE_DIR, STATE_EXT_MASK, load_statefile, 0, 0, NULL); 930 | if (ret == MRET_EXIT) ret = 0; 931 | break; 932 | case MI_SAVE_STATE: 933 | // Don't pass through if the power is insufficient 934 | if ( power_check_screen() ) break; 935 | ret = file_selection_screen("Save Calculator State", STATE_DIR, STATE_EXT_MASK, save_statefile, 1, 1, NULL); 936 | if (ret == MRET_EXIT) ret = 0; 937 | break; 938 | 939 | case MI_CLEAN_RESET: 940 | run_reset_state_file(); 941 | //ret = MRET_EXIT; 942 | break; 943 | 944 | //case MI_SAVE_STAT: 945 | // ret = MRET_SAVESTATE; 946 | // break; 947 | 948 | 949 | case MI_FILE: 950 | ret = handle_menu(&MID_FILE,MENU_ADD, 0); 951 | break; 952 | case MI_STATEFILE: 953 | ret = handle_menu(&MID_STATEFILE,MENU_ADD, 0); 954 | break; 955 | 956 | case MI_MSC: 957 | // Flush printer buffers before entering MSC 958 | prtof_buf_flush(PRTOF_GRAPHICS, PRTOF_FULL_FLUSH); 959 | prtof_buf_flush(PRTOF_TEXT, PRTOF_FULL_FLUSH); 960 | ret = MRET_UNIMPL; // Leave the action to core 961 | break; 962 | 963 | case MI_PRINT_MENU: 964 | ret = handle_menu(&MID_PRINT,MENU_ADD, 0); 965 | break; 966 | 967 | case MI_PRTOF_GRAPH: 968 | set_print_to_file(PRTOF_GRAPHICS, !is_print_to_file(PRTOF_GRAPHICS), 1); 969 | break; 970 | case MI_PRTOF_TEXT: 971 | set_print_to_file(PRTOF_TEXT, !is_print_to_file(PRTOF_TEXT), 1); 972 | break; 973 | case MI_PRTOF_NOIR: 974 | set_print_to_file(PRTOF_NOIR, !is_print_to_file(PRTOF_NOIR), 1); 975 | break; 976 | case MI_PRTOF_GR_IN_TXT: 977 | set_print_to_file(PRTOF_GR_IN_TXT, !is_print_to_file(PRTOF_GR_IN_TXT), 1); 978 | break; 979 | case MI_PRINT_DBLNL: 980 | set_print_to_file(PRINT_DBLNL, !is_print_to_file(PRINT_DBLNL), 1); 981 | break; 982 | 983 | /* Stack */ 984 | case MI_STACK_CONFIG: 985 | handle_menu(&MID_STACK_CONFIG,MENU_ADD,stack_menu_index()); 986 | break; 987 | case MI_F42CONF_MENU: 988 | handle_menu(&MID_F42CONF, MENU_ADD, 0); 989 | break; 990 | case MI_DYNSTACKEXT: 991 | set_dynstackext(!get_dynstackext()); 992 | break; 993 | case MI_F42C_MXSING: 994 | set_f42conf_mxsing(!get_f42conf_mxsing()); 995 | break; 996 | case MI_F42C_MXOVFL: 997 | set_f42conf_mxovfl(!get_f42conf_mxovfl()); 998 | break; 999 | 1000 | case MI_STACK_XYZTL: 1001 | set_stack_layout(STACK_XYZTL); 1002 | ret = MRET_EXIT; 1003 | break; 1004 | case MI_STACK_XYZTA: 1005 | set_stack_layout(STACK_XYZTA); 1006 | ret = MRET_EXIT; 1007 | break; 1008 | case MI_STACK_XYZT: 1009 | set_stack_layout(STACK_XYZT); 1010 | ret = MRET_EXIT; 1011 | break; 1012 | case MI_STACK_XYL: 1013 | set_stack_layout(STACK_XYL); 1014 | ret = MRET_EXIT; 1015 | break; 1016 | case MI_STACK_XYA: 1017 | set_stack_layout(STACK_XYA); 1018 | ret = MRET_EXIT; 1019 | break; 1020 | case MI_STACK_XY: 1021 | set_stack_layout(STACK_XY); 1022 | ret = MRET_EXIT; 1023 | break; 1024 | case MI_STACK_LXYZT: 1025 | set_stack_layout(STACK_LXYZT); 1026 | ret = MRET_EXIT; 1027 | break; 1028 | 1029 | /* Top Bar */ 1030 | case MI_TOPBAR_MENU: 1031 | ret = handle_menu(&MID_TOPBAR, MENU_ADD, 0); 1032 | break; 1033 | case MI_DISP_STATFN: toggle_disp(DISP_STATFN); break; 1034 | case MI_DISP_DOW: toggle_disp(DISP_DOW); break; 1035 | case MI_DISP_DATE: toggle_disp(DISP_DATE); break; 1036 | case MI_DISP_DATE_SEP: toggle_disp(DISP_DATE_SEP); break; 1037 | case MI_DISP_SHORTMON: toggle_disp(DISP_SHORTMON); break; 1038 | case MI_DISP_TIME: toggle_disp(DISP_TIME); break; 1039 | case MI_DISP_VOLTAGE: toggle_disp(DISP_VOLTAGE); break; 1040 | 1041 | case MI_SETTINGS: 1042 | ret = handle_menu(&MID_SETTINGS,MENU_ADD, 0); 1043 | break; 1044 | 1045 | case MI_STACK_AREA: 1046 | ret = handle_menu(&MID_STACK_AREA,MENU_ADD, 0); 1047 | break; 1048 | 1049 | case MI_SA_REG_X: inc_reg_font_offset(LINE_REG_X); break; 1050 | case MI_SA_REG_Y: inc_reg_font_offset(LINE_REG_Y); break; 1051 | case MI_SA_REG_Z: inc_reg_font_offset(LINE_REG_Z); break; 1052 | case MI_SA_REG_T: inc_reg_font_offset(LINE_REG_T); break; 1053 | case MI_SA_REG_L: inc_reg_font_offset(LINE_REG_L); break; 1054 | case MI_SA_REG_A: inc_reg_font_offset(LINE_REG_A); break; 1055 | 1056 | 1057 | case MI_ABOUT_PGM: 1058 | lcd_for_dm42(DISP_ABOUT); 1059 | wait_for_key_press(); 1060 | break; 1061 | 1062 | case MI_DEVEL_TEST: 1063 | devel_test(); 1064 | break; 1065 | 1066 | default: 1067 | ret = MRET_UNIMPL; 1068 | break; 1069 | } 1070 | 1071 | return ret; 1072 | } 1073 | 1074 | 1075 | 1076 | 1077 | char * sep_str(char * s, char const *txt, char c) { 1078 | sprintf(s,"[ ] %s", txt); 1079 | s[1] = c; 1080 | return s; 1081 | } 1082 | 1083 | 1084 | char * orb_str(char * s, char const *txt, int val) { 1085 | strcpy(s, rb_str(val)); 1086 | strcat(s, " "); 1087 | strcat(s, txt); 1088 | return s; 1089 | } 1090 | 1091 | 1092 | char * b_str(char * s, char const *txt, int val) { 1093 | s[0]=0; 1094 | if(val) 1095 | strcpy(s, "\xff"); 1096 | strcat(s, txt); 1097 | return s; 1098 | } 1099 | 1100 | 1101 | 1102 | 1103 | char * layout_str(char * s, const char * txt) { 1104 | sprintf(s, "%s [ ", txt); 1105 | get_stack_layout_str(s+strlen(s), get_stack_layout()); 1106 | strcat(s, " ]"); 1107 | return s; 1108 | } 1109 | 1110 | 1111 | char * state_str(char *s, const char * txt) { 1112 | const int maxlen = 30; 1113 | sprintf(s, "%s [", txt); 1114 | copy_reset_state_filename(s,maxlen); 1115 | strcat(s, "]"); 1116 | return s; 1117 | } 1118 | 1119 | 1120 | char * nr_str(char *s, const char * txt, int nr) { 1121 | sprintf(s, "%s: %i", txt, nr); 1122 | return s; 1123 | } 1124 | 1125 | 1126 | 1127 | // Returns NULL if not found 1128 | const char * menu_line_str(uint8_t line_id, char * s, const int slen) { 1129 | const char * ln; 1130 | 1131 | switch(line_id) { 1132 | case MI_LOAD_PGM: ln = "Load Program >"; break; 1133 | case MI_SAVE_PGM: ln = "Save Program >"; break; 1134 | case MI_SAVE_STAT: ln = "Save Calculator State";break; 1135 | case MI_FILE: ln = "File >"; break; 1136 | case MI_STATEFILE: ln = state_str(s, "Calc. State >"); break; 1137 | case MI_LOAD_STATE: ln = "Load State"; break; 1138 | case MI_SAVE_STATE: ln = "Save State"; break; 1139 | case MI_CLEAN_RESET: ln = "Load Clean State"; break; 1140 | 1141 | case MI_STACK_CONFIG: 1142 | ln = layout_str(s, "Stack Layout"); break; 1143 | 1144 | case MI_F42CONF_MENU: ln = "Free42 Configuration >"; break; 1145 | case MI_DYNSTACKEXT: ln = opt_str(s, " Dynamic Stack Extension", get_dynstackext()); break; 1146 | case MI_F42C_MXSING: ln = opt_str(s, " Singular Matrix Error", get_f42conf_mxsing()); break; 1147 | case MI_F42C_MXOVFL: ln = opt_str(s, " Matrix Overflow Error", get_f42conf_mxovfl()); break; 1148 | 1149 | case MI_STACK_XYZTL: ln = orb_str(s, "XYZTL", get_stack_layout() == STACK_XYZTL); break; 1150 | case MI_STACK_XYZTA: ln = orb_str(s, "XYZTA", get_stack_layout() == STACK_XYZTA); break; 1151 | case MI_STACK_XYZT: ln = orb_str(s, "XYZT", get_stack_layout() == STACK_XYZT); break; 1152 | case MI_STACK_XYL: ln = orb_str(s, "XYL", get_stack_layout() == STACK_XYL); break; 1153 | case MI_STACK_XYA: ln = orb_str(s, "XYA", get_stack_layout() == STACK_XYA); break; 1154 | case MI_STACK_XY: ln = orb_str(s, "XY", get_stack_layout() == STACK_XY); break; 1155 | case MI_STACK_LXYZT: ln = orb_str(s, "LXYZT", get_stack_layout() == STACK_LXYZT); break; 1156 | 1157 | case MI_TOPBAR_MENU: ln = "Status Bar >"; break; 1158 | case MI_DISP_STATFN: ln = opt_str(s, " State Filename", is_disp(DISP_STATFN)); break; 1159 | case MI_DISP_DOW: ln = opt_str(s, " Day of Week", is_disp(DISP_DOW)); break; 1160 | case MI_DISP_DATE: ln = opt_str(s, " Date", is_disp(DISP_DATE)); break; 1161 | case MI_DISP_DATE_SEP:ln = sep_str(s, " Date Separator", get_disp_date_sep()); break; 1162 | case MI_DISP_SHORTMON:ln = opt_str(s, " Month Shortcut", is_disp(DISP_SHORTMON));break; 1163 | case MI_DISP_TIME: ln = opt_str(s, " Time", is_disp(DISP_TIME)); break; 1164 | case MI_DISP_VOLTAGE: 1165 | ln = opt_str(s, " Power Voltage in Header", is_disp(DISP_VOLTAGE)); break; 1166 | 1167 | case MI_SETTINGS: ln = "Settings >"; break; 1168 | case MI_ABOUT_PGM: ln = "About >"; break; 1169 | case MI_DEVEL_TEST: ln = "Devel Test >"; break; 1170 | 1171 | case MI_STACK_AREA: ln = "Stack Font Sizes >"; break; 1172 | case MI_SA_REG_X: ln = nr_str(s, "Font Size Offset Reg X", get_reg_font_offset(LINE_REG_X) ); break; 1173 | case MI_SA_REG_Y: ln = nr_str(s, "Font Size Offset Reg Y", get_reg_font_offset(LINE_REG_Y) ); break; 1174 | case MI_SA_REG_Z: ln = nr_str(s, "Font Size Offset Reg Z", get_reg_font_offset(LINE_REG_Z) ); break; 1175 | case MI_SA_REG_T: ln = nr_str(s, "Font Size Offset Reg T", get_reg_font_offset(LINE_REG_T) ); break; 1176 | case MI_SA_REG_L: ln = nr_str(s, "Font Size Offset Reg L", get_reg_font_offset(LINE_REG_L) ); break; 1177 | case MI_SA_REG_A: ln = nr_str(s, "Font Size Offset Reg A", get_reg_font_offset(LINE_REG_A) ); break; 1178 | 1179 | case MI_PRINT_MENU: ln = "Printing >"; break; 1180 | case MI_PRTOF_GRAPH: ln = opt_str(s, " Graphics Print", is_print_to_file(PRTOF_GRAPHICS)); break; 1181 | case MI_PRTOF_TEXT: ln = opt_str(s, " Text Print", is_print_to_file(PRTOF_TEXT)); break; 1182 | case MI_PRTOF_NOIR: ln = opt_str(s, " Don't print to IR", is_print_to_file(PRTOF_NOIR)); break; 1183 | case MI_PRTOF_GR_IN_TXT: ln = opt_str(s, " Graphics in Text", is_print_to_file(PRTOF_GR_IN_TXT)); break; 1184 | case MI_PRINT_DBLNL: ln = opt_str(s, " Double Newline", is_print_to_file(PRINT_DBLNL)); break; 1185 | 1186 | default: 1187 | ln = NULL; 1188 | break; 1189 | } 1190 | 1191 | return ln; 1192 | } 1193 | 1194 | 1195 | // ------------------------------------------------------------------- 1196 | 1197 | 1198 | 1199 | } // C 1200 | --------------------------------------------------------------------------------