├── .gitignore ├── makefile ├── readme.md └── src ├── hook.asm ├── main.c └── capnhook.inc /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | 4 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # ---------------------------- 2 | # Makefile Options 3 | # ---------------------------- 4 | 5 | NAME = SPACES 6 | DESCRIPTION = "Adds commas as thousands separators." 7 | COMPRESSED = NO 8 | ARCHIVED = YES 9 | 10 | CFLAGS = -Wall -Wextra -Oz 11 | CXXFLAGS = -Wall -Wextra -Oz 12 | 13 | # ---------------------------- 14 | 15 | include $(shell cedev-config --makefile) 16 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Commas 2 | 3 | Adds commas (or spaces) to real numbers displayed on the homescreen in TI-OS. 4 | 5 | Can also replace the decimal point. 6 | 7 | ## Installation 8 | You will need [TI Connect CE](https://education.ti.com/en/products/computer-software/ti-connect-ce-sw) (on Windows or Mac) or TiLP (on Linux) to transfer programs to the calculator. 9 | Transfer either COMMAS.8xp, SPACES.8xp, or DOTS.8xp from the release ZIP. 10 | You will also need to transfer [the CE C libraries](https://github.com/CE-Programming/libraries/releases/tag/v9.2.2) and [capnhook](https://github.com/commandblockguy/capnhook/releases/latest/download/capnhook.8xv) to the calculator. 11 | Press prgm and run either COMMAS, SPACES, or DOTS. 12 | On calculators with more recent OS versions, you might need to run the program from [arTIfiCE](https://yvantt.github.io/arTIfiCE/) or Cesium instead. 13 | To disable the program, simply run it again. 14 | -------------------------------------------------------------------------------- /src/hook.asm: -------------------------------------------------------------------------------- 1 | include 'capnhook.inc' 2 | include '../../toolchain/src/include/ti84pceg.inc' 3 | 4 | section .text,"ax",@progbits 5 | public _hook 6 | 7 | SEPARATOR = ',' 8 | DECIMAL = '.' 9 | 10 | _hook: 11 | db $83 12 | set 0,(iy-flag_continue) 13 | or a,a 14 | ret nz 15 | 16 | ld a,(ti.OP1) 17 | and a,$3f 18 | ret nz 19 | 20 | push hl 21 | scf 22 | sbc hl,hl 23 | ld (hl),2 24 | pop hl 25 | 26 | ld a,20 27 | call ti.FormReal 28 | 29 | ld e,-1 30 | ld hl,ti.OP3-1 31 | .find_period_loop: 32 | inc hl 33 | inc e 34 | ld a,(hl) 35 | or a,a 36 | jr z,.found 37 | cp a,'.' 38 | jr nz,.find_period_loop 39 | if DECIMAL <> '.' 40 | ld (hl),DECIMAL 41 | end if 42 | 43 | .found: 44 | 45 | ld a,e 46 | .insert_loop: 47 | dec hl 48 | dec hl 49 | dec hl 50 | sub a,3 51 | jr z,.done 52 | jr c,.done 53 | push bc 54 | ld bc,24 55 | add hl,bc 56 | push hl 57 | pop de 58 | dec hl 59 | lddr 60 | pop bc 61 | inc hl 62 | ld (hl),SEPARATOR 63 | ld b,1 64 | inc c 65 | jr .insert_loop 66 | .done: 67 | ld hl,ti.OP3 68 | ld a,b 69 | ld b,0 70 | ld iy,ti.flags 71 | call $21890 72 | 73 | res 0,(iy-flag_continue) 74 | res ti.donePrgm,(iy+ti.doneFlags) 75 | 76 | xor a,a 77 | inc a 78 | 79 | ret 80 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | *-------------------------------------- 3 | * Program Name: 4 | * Author: 5 | * License: 6 | * Description: 7 | *-------------------------------------- 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | extern void hook; 15 | 16 | #define RAM_START ((void*)0xD00000) 17 | #define PRGM_ADDR ((void*)0xD1A87F) 18 | 19 | #define HOOK_ID 0x000910 20 | 21 | int main(int argc, const char **argv) 22 | { 23 | if(!argc) return 1; 24 | 25 | // It's time to reflect upon one of the great mysteries of life 26 | // How does one find themselves? 27 | ti_var_t slot = ti_OpenVar(argv[0], "r", TI_PRGM_TYPE); 28 | if(!slot) return 1; 29 | void *self = ti_GetDataPtr(slot); 30 | if(!self) return 1; 31 | ti_Close(slot); 32 | // It's that simple. 33 | 34 | if(self >= RAM_START) { 35 | // Sometimes you find yourself in RAM. 36 | // RAM is a terrible place to be, let's not be there. 37 | return 1; 38 | } 39 | 40 | dbg_printf("Program at %p, running at %p, hook at %p/%p\n", self, PRGM_ADDR, &hook - PRGM_ADDR + self, &hook); 41 | 42 | hook_error_t err; 43 | bool was_enabled = false; 44 | 45 | err = hook_IsEnabled(HOOK_ID, &was_enabled); 46 | dbg_printf("Err %u checking hook status\n", err); 47 | 48 | if (was_enabled) { 49 | err = hook_Disable(HOOK_ID); 50 | dbg_printf("Err %u disabling hook\n", err); 51 | } else { 52 | err = hook_Install(HOOK_ID, &hook - PRGM_ADDR + self, 0, HOOK_TYPE_HOMESCREEN, 5, "Comma display hook"); 53 | dbg_printf("Err %u installing hook at %p\n", err, &hook - PRGM_ADDR + self); 54 | } 55 | 56 | hook_Sync(); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /src/capnhook.inc: -------------------------------------------------------------------------------- 1 | ; Note - this file does not contain actual functions, only equates. 2 | ; Include "include_library.inc" and then include the LibLoad library by 3 | ; doing `include_library 'capnhook.lib'` in order to use capnhook functions. 4 | 5 | ; A negative flag location that should be set before returning if you want 6 | ; to ignore event that triggered the hook. 7 | ; Returning with this bit reset will return a value to TI-OS, and no other 8 | ; hooks will be called afterwards. 9 | ; Returning with this bit set will restore the processor registers to their 10 | ; previous values, and the hook with the next lowest priority value will be 11 | ; called. 12 | ; If there are no hooks after yours, and you return with this bit set, capnhook 13 | ; will call a "no-op" hook that behaves as though no hook was called in the 14 | ; first place. In effect, this means that you can return with this bit set if 15 | ; you wish to ignore a hook that is not called with a particular condition, 16 | ; without requiring you to handle other conditions. 17 | ; 18 | ; Unless you want to return a value to TI-OS, you should *always* set this bit 19 | ; by doing `set 0,(iy-flag_continue)`. 20 | flag_continue equ 10 21 | 22 | ; Hook types 23 | virtual at 0 24 | HOOK_TYPE_CURSOR rb 1 25 | HOOK_TYPE_LIBRARY rb 1 26 | HOOK_TYPE_RAW_KEY rb 1 27 | HOOK_TYPE_GET_CSC rb 1 28 | HOOK_TYPE_HOMESCREEN rb 1 29 | HOOK_TYPE_WINDOW rb 1 30 | HOOK_TYPE_GRAPH rb 1 31 | HOOK_TYPE_Y_EQUALS rb 1 32 | HOOK_TYPE_FONT rb 1 33 | HOOK_TYPE_REGRAPH rb 1 34 | HOOK_TYPE_GRAPHICS rb 1 35 | HOOK_TYPE_TRACE rb 1 36 | HOOK_TYPE_PARSER rb 1 37 | HOOK_TYPE_APP_CHANGE rb 1 38 | HOOK_TYPE_CATALOG1 rb 1 39 | HOOK_TYPE_HELP rb 1 40 | HOOK_TYPE_CX_REDISP rb 1 41 | HOOK_TYPE_MENU rb 1 42 | HOOK_TYPE_CATALOG2 rb 1 43 | HOOK_TYPE_TOKEN rb 1 44 | HOOK_TYPE_LOCALIZE rb 1 45 | HOOK_TYPE_SILENT_LINK rb 1 46 | HOOK_TYPE_USB_ACTIVITY rb 1 47 | end virtual 48 | --------------------------------------------------------------------------------