Compare commits

...

20 commits

Author SHA1 Message Date
Jacob Young
54b210eb14 Tag v0.0.4b release. 2022-02-12 17:37:58 -05:00
Jacob Young
7f6c87fcc7 Update artifact url. 2021-07-05 21:53:52 -04:00
Jacob Young
b5116f962d Fix #2. 2021-05-04 20:29:44 -04:00
Jacob Young
e2d275945f Set device version to OS version. 2021-04-23 18:52:20 -04:00
Jacob Young
a65a8a2e46 Bump version. 2021-04-18 07:46:04 -04:00
Jacob Young
ecafcfadfe Tag v0.0.3b release. 2021-04-18 07:46:04 -04:00
Jacob Young
908e208529 Improve display of title and version. 2021-04-18 07:46:04 -04:00
Jacob Young
930d5a634a Improve makefile. 2021-04-18 06:45:02 -04:00
Jacob Young
6048945f1a Use new upstream usbdrvce features. 2021-04-18 06:39:20 -04:00
Jacob Young
0b40c0d4a9 Remove cruft not needed with fixed upstream makefile. 2021-04-18 06:39:20 -04:00
Jacob Young
0b3b3dbe34 Mac compatibility I guess. 2021-04-18 06:39:20 -04:00
Jacob Young
5ed318f894 Tag v0.0.2b release. 2021-04-18 06:39:19 -04:00
Jacob Young
d8f0a1f986 Fix image file names. 2021-04-18 06:39:19 -04:00
Jacob Young
c02c473377 Update readme. 2021-04-18 06:39:19 -04:00
Jacob Young
fee2ba9b6f Add some missing checks. 2021-04-18 06:39:19 -04:00
Jacob Young
3210d78938 Fix receiving archived unnamed variables. 2021-04-18 06:39:19 -04:00
Jacob Young
397ab473a9 Fix sending in data that is a multiple of the max packet size. 2021-04-18 06:39:19 -04:00
Jacob Young
42e90a92f7 Add nautilus as a supported ubuntu file browser. 2021-04-18 06:39:19 -04:00
Jacob Young
cd6d57b020 Add license. 2021-04-18 06:39:19 -04:00
Jacob Young
33c9f0a57e Add known working computer OS instructions to README. 2021-04-18 06:39:19 -04:00
10 changed files with 266 additions and 129 deletions

15
CHANGELOG.md Normal file
View file

@ -0,0 +1,15 @@
# prgmTRANSFER
## v0.0.1b
- Initial beta release
## v0.0.2b
- Fix corrupted screen, crash, or garbage data when receiving some variables from Archive.
- Fix incorrect file names for images.
## v0.0.3b
- Use new usbdrvce error handling features.
- Improve build system.
## v0.0.4b
- Recompile for new usbdrvce.

19
LICENSE Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2019 - 2021 Jacob "jacobly" Young
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,4 +1,4 @@
# prgmTRANSFER v0.0.1b # prgmTRANSFER v0.0.4b
### This software is still in beta, no liability for corrupted or lost files, etc! ### This software is still in beta, no liability for corrupted or lost files, etc!
@ -7,8 +7,13 @@ Running this program on the calculator will allow you to transfer variable files
Windows 10/Ubuntu 20.04/Android with preinstalled software, or other OSes with various Windows 10/Ubuntu 20.04/Android with preinstalled software, or other OSes with various
PTP or MTP transfer software. PTP or MTP transfer software.
## Known Working Computer OSes
- Windows 10 using the default file explorer, check under Computer after connecting.
- Ubuntu 20.04 using the default Gnome Files (nautilus) or Dolphin.
- Android 11 using the builtin Files application, check notifications after connecting to open.
## Installation ## Installation
1. Send [TRANSFER.8xp release](https://github.com/jacobly0/transfer/releases/latest) and [nightly clibs.8xg from usbdrvce branch](https://jacobly.com/a/toolchain/usbdrvce/clibs.zip) to your calculator using other transfer software. 1. Send [TRANSFER.8xp release](https://github.com/jacobly0/transfer/releases/latest) and [nightly clibs.8xg from usbdrvce branch](https://jacobly.com/artifact?repo=toolchain&branch=usbdrvce&file=clibs) to your calculator using other transfer software.
1. Run `Asm(prgmTRANSFER)` and then plug-and-play with a usb cable to supported OSes, or using supported software. 1. Run `Asm(prgmTRANSFER)` and then plug-and-play with a usb cable to supported OSes, or using supported software.
1. The screen should display a debug log that can be ignored unless things go wrong, in which case the last few lines should be reported if there is an issue. 1. The screen should display a debug log that can be ignored unless things go wrong, in which case the last few lines should be reported if there is an issue.
1. Press `clear` to exit. 1. Press `clear` to exit.
@ -23,7 +28,8 @@ PTP or MTP transfer software.
- [ ] Receiving a rom dump. - [ ] Receiving a rom dump.
- [ ] Copying variables in either RAM or Archive to another name in either RAM or Archive. - [ ] Copying variables in either RAM or Archive to another name in either RAM or Archive.
- [x] Getting free space in RAM or Archive. - [x] Getting free space in RAM or Archive.
- [x] Geting and seting the current time. - [x] Getting the current time.
- [x] Geting the current battery level. - [ ] Setting the current time.
- [ ] Geting a device icon for displaying in MTP program UIs. - [x] Getting the current battery level.
- [ ] ~~Getting a device icon for displaying in MTP program UIs.~~
- [ ] Optimize for a smaller program size. - [ ] Optimize for a smaller program size.

View file

@ -5,14 +5,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <uchar.h>
int main(int argc, char **argv) { int main(int argc, char **argv) {
FT_Library library; FT_Library library;
FT_Error error; FT_Error error;
FT_Face face; FT_Face face;
if ((error = FT_Init_FreeType(&library)) || if ((error = FT_Init_FreeType(&library)) ||
(error = FT_New_Face(library, "/usr/share/fonts/fonts-master/apache/robotomono/RobotoMono-Medium.ttf", 0, &face)) || ((error = FT_New_Face(library, "/usr/share/fonts/fonts-master/apache/robotomono/RobotoMono-Medium.ttf", 0, &face)) &&
(error = FT_New_Face(library, "/Library/Fonts/RobotoMono-Medium.ttf", 0, &face))) ||
(error = FT_Set_Char_Size(face, 0, 550, 0, 141)) || (error = FT_Set_Char_Size(face, 0, 550, 0, 141)) ||
(error = FT_Load_Char(face, U'w', FT_LOAD_DEFAULT))) return error; (error = FT_Load_Char(face, U'w', FT_LOAD_DEFAULT))) return error;
int width = face->glyph->advance.x >> 6, height = face->size->metrics.height >> 6, height_bytes = (height + 1) >> 1; int width = face->glyph->advance.x >> 6, height = face->size->metrics.height >> 6, height_bytes = (height + 1) >> 1;
@ -45,7 +45,7 @@ int main(int argc, char **argv) {
"const uint8_t font[0x100][FONT_WIDTH][FONT_HEIGHT_BYTES] = {\n"); "const uint8_t font[0x100][FONT_WIDTH][FONT_HEIGHT_BYTES] = {\n");
uint8_t *bitmap = calloc(width, height_bytes); uint8_t *bitmap = calloc(width, height_bytes);
if (!bitmap) return 1; if (!bitmap) return 1;
for (char32_t c = U'\0'; c <= U'\xFF'; ++c) { for (uint32_t c = U'\0'; c <= U'\xFF'; ++c) {
memset(bitmap, 0, width * height_bytes); memset(bitmap, 0, width * height_bytes);
if ((error = FT_Load_Char(face, c, FT_LOAD_DEFAULT)) || if ((error = FT_Load_Char(face, c, FT_LOAD_DEFAULT)) ||
(error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL))) return error; (error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL))) return error;

View file

@ -2,29 +2,47 @@
# Makefile Options # Makefile Options
# ---------------------------- # ----------------------------
NAME ?= TRANSFER NATIVECC = clang
ICON ?= transfer.png
DESCRIPTION ?= "Variable Transfer Program"
COMPRESSED ?= YES
ARCHIVED ?= YES
CFLAGS ?= -Wall -Wextra -Oz NAME = TRANSFER
CXXFLAGS ?= -Wall -Wextra -Oz MAJOR_VERSION = 0
MINOR_VERSION = 0
PATCH_VERSION = 4
KIND_VERSION = n
BUILD_VERSION = -$(shell git rev-parse --short HEAD)
FULL_VERSION = v$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION)$(KIND_VERSION)$(BUILD_VERSION)
ICON = transfer.png
DESCRIPTION = "Variable Transfer Program $(FULL_VERSION)"
COMPRESSED = YES
ARCHIVED = YES
EXTRA_CSOURCES ?= $(if $(wildcard src/font.c),,src/font.c) FLAGS = -Wall -Wextra -Oz -DVERSION='"$(FULL_VERSION)"'
EXTRA_USERHEADERS ?= src/ti84pceg.inc src/font.h CFLAGS = $(FLAGS)
EXTRA_CLEAN ?= src/font.c src/font.h font/genfont CXXFLAGS = $(FLAGS)
EXTRA_CSOURCES = src/font.c
EXTRA_USERHEADERS = src/ti84pceg.inc src/font.h
EXTRA_CLEAN = src/font.c src/font.h font/genfont
# ---------------------------- # ----------------------------
ifndef CEDEV include $(shell cedev-config --makefile)
$(error CEDEV environment path variable is not set)
endif
include $(CEDEV)/meta/makefile.mk all:
$(Q)echo [done] prgm$(NAME) $(FULL_VERSION)
src/font.h src/font.c: font/genfont beta: KIND_VERSION = b
@$< beta: BUILD_VERSION =
beta: all
font/genfont: font/genfont.c release: BUILD_VERSION =
@clang -O3 -flto $< `pkg-config --cflags --libs freetype2` -o $@ release: REV_VERSION =
release: all
src/font.h src/font.c: font/genfont makefile
$(Q)echo [running] $<
$(Q)$<
font/genfont: font/genfont.c makefile
$(Q)echo [compiling] $<
$(Q)$(NATIVECC) -O3 -flto $< `pkg-config --cflags --libs freetype2` -o $@

View file

@ -14,6 +14,7 @@ typedef struct mtp_global mtp_global_t;
#define usb_transfer_data_t mtp_global_t #define usb_transfer_data_t mtp_global_t
/* Includes */ /* Includes */
#include "font.h"
#include "ui.h" #include "ui.h"
#include "var.h" #include "var.h"
@ -36,6 +37,8 @@ typedef struct mtp_global mtp_global_t;
#define lengthof(array) (sizeof(array) / sizeof(*(array))) #define lengthof(array) (sizeof(array) / sizeof(*(array)))
#define charsof(literal) (lengthof(literal) - 1)
#define COUNT_EACH(...) +1 #define COUNT_EACH(...) +1
#define OBJECT_BUFFER \ #define OBJECT_BUFFER \
@ -59,7 +62,9 @@ typedef struct mtp_global mtp_global_t;
X(SET_DEVICE_PROP_VALUE) \ X(SET_DEVICE_PROP_VALUE) \
X(MOVE_OBJECT) X(MOVE_OBJECT)
#define FOR_EACH_SUPP_EVT(X) #define FOR_EACH_SUPP_EVT(X) \
X(OBJECT_ADDED) \
X(OBJECT_REMOVED)
#define FOR_EACH_SUPP_DP(X) \ #define FOR_EACH_SUPP_DP(X) \
X(uint8, BATTERY_LEVEL, RANGE) \ X(uint8, BATTERY_LEVEL, RANGE) \
@ -123,13 +128,13 @@ typedef struct mtp_global mtp_global_t;
} }
#define DATE_TIME_GET_SET 1 #define DATE_TIME_GET_SET 1
#define DATE_TIME_GET(current) \ #define DATE_TIME_GET(current) \
get_datetime(current.string) get_datetime(&current)
#define DATE_TIME_SET(new) #define DATE_TIME_SET(new)
#define PERCEIVED_DEVICE_TYPE_DEF 0 #define PERCEIVED_DEVICE_TYPE_DEF 0
#define PERCEIVED_DEVICE_TYPE_GET_SET 0 #define PERCEIVED_DEVICE_TYPE_GET_SET 0
#define PERCEIVED_DEVICE_TYPE_GET(current) \ #define PERCEIVED_DEVICE_TYPE_GET(current) \
current = 3 current = 5
#define PERCEIVED_DEVICE_TYPE_SET(new) #define PERCEIVED_DEVICE_TYPE_SET(new)
/* MTP Types */ /* MTP Types */
@ -162,16 +167,16 @@ typedef usb_error_t(*mtp_transaction_callback_t)(
#define Los_specific L"MSFT100\1" #define Los_specific L"MSFT100\1"
#define Lmtp_extensions L"microsoft.com: 1.0;" #define Lmtp_extensions L"microsoft.com: 1.0;"
#define Lmanufacturer L"Texas Instruments Incorporated" #define Lmanufacturer L"Texas Instruments Incorporated"
#define Lproduct L"TI-83 Premium CE" /* default must be longer than alt */ #define Lproduct L"TI-84 Plus CE"
#define Lproduct84 L"TI-84 Plus CE" #define Lproduct83 L"TI-83 Premium CE"
#define Ldevice_version L"2.20" #define Ldevice_version L"255.255.255.65535"
#define Lserial_number L"0000000000000000" #define Lserial_number L"0000000000000000"
#define Lcharging_cfg L"Charging" #define Lcharging_cfg L"Charging"
#define Lmtp_interface L"MTP" /* magic string to aid detection */ #define Lmtp_interface L"MTP" /* magic string to aid detection */
#define Lram_storage_desc L"RAM" #define Lram_storage_desc L"RAM"
#define Lram_volume_id Lserial_number"R" #define Lram_volume_id Lserial_number "R"
#define Larc_storage_desc L"Archive" #define Larc_storage_desc L"Archive"
#define Larc_volume_id Lserial_number"A" #define Larc_volume_id Lserial_number "A"
#define Lfactory_datetime L"20150101T000000" #define Lfactory_datetime L"20150101T000000"
typedef enum string_id { typedef enum string_id {
@ -712,7 +717,8 @@ typedef struct mtp_device_info {
mtp_byte_t manufacturer_length; mtp_byte_t manufacturer_length;
wchar_t manufacturer[lengthof(Lmanufacturer)]; wchar_t manufacturer[lengthof(Lmanufacturer)];
mtp_byte_t model_length; mtp_byte_t model_length;
wchar_t model[lengthof(Lproduct)]; wchar_t model[lengthof(Lproduct) > lengthof(Lproduct83) ?
lengthof(Lproduct) : lengthof(Lproduct83)];
mtp_byte_t device_version_length; mtp_byte_t device_version_length;
wchar_t device_version[lengthof(Ldevice_version)]; wchar_t device_version[lengthof(Ldevice_version)];
mtp_byte_t serial_number_length; mtp_byte_t serial_number_length;
@ -819,6 +825,7 @@ DECLARE_CALLBACK(get_object);
DECLARE_CALLBACK(send_object_info); DECLARE_CALLBACK(send_object_info);
DECLARE_CALLBACK(send_object_container); DECLARE_CALLBACK(send_object_container);
DECLARE_CALLBACK(send_object); DECLARE_CALLBACK(send_object);
DECLARE_CALLBACK(zlp_data_in);
DECLARE_CALLBACK(final_data_in); DECLARE_CALLBACK(final_data_in);
DECLARE_CALLBACK(response); DECLARE_CALLBACK(response);
DECLARE_CALLBACK(event); DECLARE_CALLBACK(event);
@ -839,18 +846,12 @@ static usb_endpoint_t get_endpoint(
static usb_error_t stall_data_endpoints( static usb_error_t stall_data_endpoints(
usb_endpoint_t endpoint) { usb_endpoint_t endpoint) {
printf("stalling data endpoints\n"); printf("stalling data endpoints\n");
#if 0 usb_error_t error = usb_SetEndpointHalt(
usb_error_t error;
error = usb_StallEndpoint(
get_endpoint(endpoint, MTP_EP_DATA_IN)); get_endpoint(endpoint, MTP_EP_DATA_IN));
if (error == USB_SUCCESS) if (error == USB_SUCCESS)
error = usb_StallEndpoint( error = usb_SetEndpointHalt(
get_endpoint(endpoint, MTP_EP_DATA_OUT)); get_endpoint(endpoint, MTP_EP_DATA_OUT));
return error; return error;
#else
(void)endpoint;
return USB_ERROR_FAILED;
#endif
} }
static usb_error_t schedule_event( static usb_error_t schedule_event(
@ -955,33 +956,6 @@ static usb_error_t schedule_ok_response(
params, param_count, global); params, param_count, global);
} }
static usb_error_t schedule_data_in_response(
usb_endpoint_t endpoint,
const void *data,
size_t data_size,
mtp_global_t *global) {
usb_error_t error;
global->transaction.container.length.size =
sizeof(mtp_container_t) +
data_size;
global->transaction.container.type =
MTP_BT_DATA;
error = usb_ScheduleBulkTransfer(
endpoint = get_endpoint(
endpoint, MTP_EP_DATA_IN),
&global->transaction,
sizeof(mtp_container_t),
NULL,
global);
if (error) return error;
return usb_ScheduleBulkTransfer(
endpoint,
(void *)data,
data_size,
final_data_in_complete,
global);
}
static usb_error_t schedule_data_in( static usb_error_t schedule_data_in(
usb_endpoint_t endpoint, usb_endpoint_t endpoint,
size_t data_size, size_t data_size,
@ -1001,6 +975,27 @@ static usb_error_t schedule_data_in(
global); global);
} }
static usb_error_t schedule_data_in_response(
usb_endpoint_t endpoint,
const void *data,
size_t data_size,
mtp_global_t *global) {
usb_error_t error = schedule_data_in(
endpoint, data_size, NULL, global);
if (error == USB_SUCCESS)
error = usb_ScheduleBulkTransfer(
get_endpoint(endpoint,
MTP_EP_DATA_IN),
(void *)data,
data_size,
data_size &&
!(data_size % MTP_MAX_BULK_PKT_SZ)
? zlp_data_in_complete
: final_data_in_complete,
global);
return error;
}
static usb_error_t status_error( static usb_error_t status_error(
usb_transfer_status_t status) { usb_transfer_status_t status) {
printf("transfer status = %02X\n", status); printf("transfer status = %02X\n", status);
@ -1056,21 +1051,19 @@ static uint16_t compute_checksum(
} }
static void get_datetime( static void get_datetime(
wchar_t result[lengthof(Lfactory_datetime)]) { datetime_t *result) {
uint16_t year; uint16_t year;
uint8_t month, day, hour, minute, second, uint8_t month, day, hour, minute, second;
i = lengthof(Lfactory_datetime); char string[lengthof(Lfactory_datetime)];
char string[lengthof(Lfactory_datetime)],
*pointer = string;
boot_GetDate(&day, &month, &year); boot_GetDate(&day, &month, &year);
boot_GetTime(&second, &minute, &hour); boot_GetTime(&second, &minute, &hour);
sprintf(string, "%04u%02u%02uT%02u%02u%02u", int count =
year, month, day, hour, minute, second); snprintf(string, lengthof(string),
do { "%04u%02u%02uT%02u%02u%02u",
*(char *)result = *pointer; year, month, day, hour, minute, second);
++result; result->length = count <= 0 ? 0 : count + 1;
++pointer; for (mtp_byte_t i = 0; i != result->length; ++i)
} while (--i); result->string[i] = string[i];
} }
static int delete_object( static int delete_object(
@ -1188,6 +1181,7 @@ static int send_object(
version = entry->version; version = entry->version;
flag = entry->flag; flag = entry->flag;
} }
(void)version;
flag &= global->transaction.pending flag &= global->transaction.pending
.send_object.mask; .send_object.mask;
flag |= global->transaction.pending flag |= global->transaction.pending
@ -1754,6 +1748,7 @@ DEFINE_CALLBACK(command) {
MTP_RSP_DEVICE_PROP_NOT_SUPPORTED, MTP_RSP_DEVICE_PROP_NOT_SUPPORTED,
global); global);
case MTP_OPR_GET_DEVICE_PROP_VALUE: case MTP_OPR_GET_DEVICE_PROP_VALUE:
MAX_PARAMS(1);
#define GET_DEVICE_PROP_VALUE_RESPONSE(type, name, form) \ #define GET_DEVICE_PROP_VALUE_RESPONSE(type, name, form) \
if (global->transaction.payload.params[0] == \ if (global->transaction.payload.params[0] == \
MTP_DP_##name) { \ MTP_DP_##name) { \
@ -1769,6 +1764,7 @@ DEFINE_CALLBACK(command) {
MTP_RSP_DEVICE_PROP_NOT_SUPPORTED, MTP_RSP_DEVICE_PROP_NOT_SUPPORTED,
global); global);
case MTP_OPR_SET_DEVICE_PROP_VALUE: case MTP_OPR_SET_DEVICE_PROP_VALUE:
MAX_PARAMS(1);
usb_ScheduleBulkTransfer( usb_ScheduleBulkTransfer(
endpoint, endpoint,
&global->transaction.payload, &global->transaction.payload,
@ -2144,6 +2140,18 @@ DEFINE_CALLBACK(send_object) {
endpoint, response, NULL, 0, global); endpoint, response, NULL, 0, global);
} }
DEFINE_CALLBACK(zlp_data_in) {
(void)transferred;
if (status != USB_TRANSFER_COMPLETED)
return status_error(status);
if (global->reset)
return schedule_command(endpoint, global);
return usb_ScheduleBulkTransfer(
endpoint, NULL, 0,
final_data_in_complete,
global);
}
DEFINE_CALLBACK(final_data_in) { DEFINE_CALLBACK(final_data_in) {
(void)transferred; (void)transferred;
if (status != USB_TRANSFER_COMPLETED) if (status != USB_TRANSFER_COMPLETED)
@ -2190,7 +2198,7 @@ static usb_error_t usb_event(usb_event_t event,
(USB_DEVICE_TO_HOST | (USB_DEVICE_TO_HOST |
USB_STANDARD_REQUEST | USB_STANDARD_REQUEST |
USB_RECIPIENT_DEVICE) && USB_RECIPIENT_DEVICE) &&
setup->bRequest == USB_GET_DESCRIPTOR && setup->bRequest == USB_GET_DESCRIPTOR_REQUEST &&
setup->wValue == 0x03EE && !setup->wIndex) { setup->wValue == 0x03EE && !setup->wIndex) {
DEFINE_STRING_DESCRIPTOR(const, os_specific); DEFINE_STRING_DESCRIPTOR(const, os_specific);
error = usb_ScheduleTransfer( error = usb_ScheduleTransfer(
@ -2263,10 +2271,19 @@ int main(void) {
static mtp_global_t global; static mtp_global_t global;
usb_error_t error; usb_error_t error;
ui_Init(); ui_Init();
printf(" TRANSFER v0.0.1b\n" #define CENTER(string) \
" Connect USB to PC.\n" printf("%*s%.*s", \
" Press [clear] to exit.\n" (LCD_WIDTH / FONT_WIDTH + \
"--------------------------------"); charsof(string)) / 2, \
string, \
charsof(string) % \
(LCD_WIDTH / FONT_WIDTH) != 0, \
"\n");
CENTER("TRANSFER " VERSION);
CENTER("Connect USB to PC.");
CENTER("Press [clear] to exit.");
CENTER("--------------------------------");
ui_Lock();
static mtp_device_info_t device_info = { static mtp_device_info_t device_info = {
.standard_version = 100, /* 1.00 */ .standard_version = 100, /* 1.00 */
.mtp_vendor_extension_id = 6, .mtp_vendor_extension_id = 6,
@ -2282,7 +2299,11 @@ int main(void) {
FOR_EACH_SUPP_OPR(LIST_SUPP_OPR) FOR_EACH_SUPP_OPR(LIST_SUPP_OPR)
}, },
.events_supported_length = lengthof(device_info.events_supported), .events_supported_length = lengthof(device_info.events_supported),
.events_supported = {}, .events_supported = {
#define LIST_SUPP_EVT(name) \
MTP_EVT_##name,
FOR_EACH_SUPP_EVT(LIST_SUPP_EVT)
},
.device_properties_length = lengthof(device_info.device_properties), .device_properties_length = lengthof(device_info.device_properties),
.device_properties = { .device_properties = {
#define LIST_SUPP_DP(type, name, form) \ #define LIST_SUPP_DP(type, name, form) \
@ -2303,14 +2324,8 @@ int main(void) {
}, },
.manufacturer_length = lengthof(device_info.manufacturer), .manufacturer_length = lengthof(device_info.manufacturer),
.manufacturer = Lmanufacturer, .manufacturer = Lmanufacturer,
.model_length = lengthof(Lproduct),
.model = Lproduct,
.device_version_length = lengthof(device_info.device_version),
.device_version = Ldevice_version,
.serial_number_length = lengthof(device_info.serial_number),
.serial_number = Lserial_number Lserial_number,
}; };
#define DEFINE_STORAGE_INFO(name) \ #define DEFINE_STORAGE_INFO(name) \
static name##_mtp_storage_info_t name##_storage_info = { \ static name##_mtp_storage_info_t name##_storage_info = { \
.storage_type = MTP_ST_FIXED_RAM, \ .storage_type = MTP_ST_FIXED_RAM, \
.filesystem_type = MTP_FT_GENERIC_FLAT, \ .filesystem_type = MTP_FT_GENERIC_FLAT, \
@ -2328,7 +2343,7 @@ int main(void) {
FOR_EACH_STORAGE(DEFINE_STORAGE_INFO) FOR_EACH_STORAGE(DEFINE_STORAGE_INFO)
/* Standard USB Descriptors */ /* Standard USB Descriptors */
FOR_EACH_STRING_DESCRIPTOR(DEFINE_STRING_DESCRIPTOR) FOR_EACH_STRING_DESCRIPTOR(DEFINE_STRING_DESCRIPTOR)
DEFINE_STRING_DESCRIPTOR(const, product84) DEFINE_STRING_DESCRIPTOR(const, product83)
const static usb_string_descriptor_t *strings[] = { const static usb_string_descriptor_t *strings[] = {
#define ADDRESSOF_STRING_DESCRIPTOR(const, name) &name, #define ADDRESSOF_STRING_DESCRIPTOR(const, name) &name,
FOR_EACH_STRING_DESCRIPTOR(ADDRESSOF_STRING_DESCRIPTOR) FOR_EACH_STRING_DESCRIPTOR(ADDRESSOF_STRING_DESCRIPTOR)
@ -2411,7 +2426,7 @@ int main(void) {
.bMaxPacketSize0 = 0x40u, .bMaxPacketSize0 = 0x40u,
.idVendor = 0x0451u, .idVendor = 0x0451u,
.idProduct = 0xE010u, .idProduct = 0xE010u,
.bcdDevice = 0x260u, /* 2.60 */ .bcdDevice = 0x240u, /* 2.40 */
.iManufacturer = Imanufacturer, .iManufacturer = Imanufacturer,
.iProduct = Iproduct, .iProduct = Iproduct,
.iSerialNumber = Iserial_number, .iSerialNumber = Iserial_number,
@ -2425,34 +2440,68 @@ int main(void) {
.strings = strings, .strings = strings,
}; };
const system_info_t *info = os_GetSystemInfo(); const system_info_t *info = os_GetSystemInfo();
for (mtp_byte_t i = 0; i != MTP_MAX_PENDING_EVENTS; ++i)
global.events[i].container.type = MTP_BT_EVENT;
mtp_byte_t *device_info_strings = &device_info.model_length;
if (info->hardwareType & 1) {
*device_info_strings++ =
lengthof(Lproduct83);
memcpy(device_info_strings,
Lproduct83,
sizeof(Lproduct83));
device_info_strings +=
sizeof(Lproduct83);
*(mtp_byte_t *)&device.bcdDevice =
0x60; /* 2.60 */
strings[Iproduct - 1] = &product83;
var_extensions[0x23][0] = 'p';
} else {
*device_info_strings++ =
lengthof(Lproduct);
memcpy(device_info_strings,
Lproduct,
sizeof(Lproduct));
device_info_strings +=
sizeof(Lproduct);
}
{
char version[lengthof(Ldevice_version)];
int count =
snprintf(version, lengthof(version),
"%u.%u.%u.%04u",
info->osMajorVersion,
info->osMinorVersion,
info->osRevisionVersion,
info->osBuildVersion);
mtp_byte_t size = count <= 0 ? 0 : count + 1;
*device_info_strings++ = size;
for (mtp_byte_t i = 0; i != size; ++i) {
*device_info_strings++ = version[i];
device_info_strings++;
}
}
*device_info_strings++ =
lengthof(Lserial_number Lserial_number);
memcpy(device_info_strings,
Lserial_number,
sizeof(Lserial_number) -
sizeof(L'\0'));
device_info_strings +=
sizeof(Lserial_number Lserial_number);
global.device_info = &device_info;
global.device_info_size =
device_info_strings -
(mtp_byte_t *)&device_info;
#define SET_STORAGE_INFO_PTR(name) \
global.name##_storage_info = &name##_storage_info;
FOR_EACH_STORAGE(SET_STORAGE_INFO_PTR)
wchar_t *serial_numbers[] = { wchar_t *serial_numbers[] = {
&serial_number.bString[2 * lengthof(info->calcid)], &serial_number.bString[2 * lengthof(info->calcid)],
&device_info.serial_number[4 * lengthof(info->calcid)], (wchar_t *)device_info_strings - 1,
#define LIST_STORAGE_INFO_SERIAL(name) \ #define LIST_STORAGE_INFO_SERIAL(name) \
&name##_storage_info.volume_identifier[2 * lengthof(info->calcid)], &name##_storage_info.volume_identifier[2 * lengthof(info->calcid)],
FOR_EACH_STORAGE(LIST_STORAGE_INFO_SERIAL) FOR_EACH_STORAGE(LIST_STORAGE_INFO_SERIAL)
}; };
for (mtp_byte_t i = 0; i != MTP_MAX_PENDING_EVENTS; ++i)
global.events[i].container.type = MTP_BT_EVENT;
if (info->hardwareType & 1)
global.device_info_size = sizeof(mtp_device_info_t);
else {
*(mtp_byte_t *)&device.bcdDevice = 0x40; /* 2.40 */
device_info.model_length = lengthof(Lproduct84);
memcpy(device_info.model, Lproduct84, sizeof(Lproduct84));
memmove(&device_info.model[lengthof(Lproduct84)],
&device_info.device_version_length,
sizeof(mtp_device_info_t) -
offsetof(mtp_device_info_t, device_version_length));
global.device_info_size = sizeof(mtp_device_info_t) -
sizeof(Lproduct) + sizeof(Lproduct84);
strings[Iproduct - 1] = &product84;
var_extensions[0x23][0] = 'e';
}
global.device_info = &device_info;
#define SET_STORAGE_INFO_PTR(name) \
global.name##_storage_info = &name##_storage_info;
FOR_EACH_STORAGE(SET_STORAGE_INFO_PTR)
for (mtp_byte_t i = 2 * lengthof(info->calcid); i; ) { for (mtp_byte_t i = 2 * lengthof(info->calcid); i; ) {
mtp_byte_t nibble = info->calcid[--i >> 1]; mtp_byte_t nibble = info->calcid[--i >> 1];
if (!(i & 1)) if (!(i & 1))

View file

@ -8,9 +8,7 @@
#include <string.h> #include <string.h>
#include <tice.h> #include <tice.h>
#define STATIC_ROWS 4 static uint8_t static_rows, row, col, swap;
static uint8_t row, col, swap;
#define buffer(n) (*(uint8_t (*)[4][LCD_WIDTH][LCD_HEIGHT >> 1])lcd_Ram)[(n) ^ swap] #define buffer(n) (*(uint8_t (*)[4][LCD_WIDTH][LCD_HEIGHT >> 1])lcd_Ram)[(n) ^ swap]
void ui_Init(void) { void ui_Init(void) {
@ -31,6 +29,10 @@ void ui_Init(void) {
*(volatile uint8_t *volatile *)&lcd_UpBase = &buffer(0)[0][0]; *(volatile uint8_t *volatile *)&lcd_UpBase = &buffer(0)[0][0];
} }
void ui_Lock(void) {
static_rows = row;
}
void ui_Cleanup(void) { void ui_Cleanup(void) {
boot_ClearVRAM(); boot_ClearVRAM();
boot_TurnOn(); boot_TurnOn();
@ -56,7 +58,7 @@ void outchar(char c) {
sizeof(buffer(1)) - FONT_HEIGHT_BYTES); sizeof(buffer(1)) - FONT_HEIGHT_BYTES);
for (unsigned x = 0; x != LCD_WIDTH; ++x) { for (unsigned x = 0; x != LCD_WIDTH; ++x) {
memcpy(&buffer(0)[x][0], &buffer(1)[x][0], memcpy(&buffer(0)[x][0], &buffer(1)[x][0],
FONT_HEIGHT_BYTES * STATIC_ROWS); FONT_HEIGHT_BYTES * static_rows);
memset(&buffer(0)[x][((LCD_HEIGHT / FONT_HEIGHT - 1) * memset(&buffer(0)[x][((LCD_HEIGHT / FONT_HEIGHT - 1) *
FONT_HEIGHT) >> 1], 0xFF, FONT_HEIGHT_BYTES); FONT_HEIGHT) >> 1], 0xFF, FONT_HEIGHT_BYTES);
} }

View file

@ -2,6 +2,7 @@
#define UI_H #define UI_H
void ui_Init(void); void ui_Init(void);
void ui_Lock(void);
void ui_Cleanup(void); void ui_Cleanup(void);
#endif #endif

View file

@ -6,10 +6,9 @@
private ti.DataSize private ti.DataSize
private ti.DelVarArc private ti.DelVarArc
private ti.EquObj private ti.EquObj
private ti.flags
private ti.GroupObj
private ti.Get_Tok_Strng private ti.Get_Tok_Strng
private ti.GroupObj private ti.GroupObj
private ti.GroupObj
private ti.Mov9ToOP1 private ti.Mov9ToOP1
private ti.OP1 private ti.OP1
private ti.OP3 private ti.OP3
@ -18,13 +17,19 @@
private ti.ProgObj private ti.ProgObj
private ti.ProtProgObj private ti.ProtProgObj
private ti.PushErrorHandler private ti.PushErrorHandler
private ti.flags
private ti.tAns private ti.tAns
private ti.tExtTok
private ti.tRecurn private ti.tRecurn
private ti.tVarLst private ti.tVarLst
private ti.tVarOut private ti.tVarOut
include 'ti84pceg.inc' include 'ti84pceg.inc'
private ImageObj
private tVarImage1
private varTypeMask private varTypeMask
ImageObj := $1A
tVarImage1 := $50
varTypeMask := $3F varTypeMask := $3F
private DELETE_VAR_NOT_DELETED private DELETE_VAR_NOT_DELETED
@ -124,11 +129,16 @@ _get_var_data_ptr:
ex de,hl ex de,hl
bit 15,bc bit 15,bc
ret nz ret nz
ld bc,9 ex de,hl
add hl,bc call ti.Sym_Prog_non_t_Lst
ld c,(hl) jq z,.named
add hl,bc ld c,2
inc hl .named:
ex de,hl
ld de,10
add hl,de
ld e,c
add hl,de
ret ret
section .text section .text
@ -224,6 +234,11 @@ _arc_unarc_var:
ex (sp),iy ex (sp),iy
push de push de
.enter: .enter:
ld a,(de)
cp a,'A'
ret c
cp a,ti.tAns
ret z
ld hl,.return ld hl,.return
call ti.PushErrorHandler call ti.PushErrorHandler
lea hl,iy lea hl,iy
@ -255,6 +270,8 @@ _get_var_file_name:
sub a,(ti.AppVarObj-ti.ProtProgObj-1) shl 1 sub a,(ti.AppVarObj-ti.ProtProgObj-1) shl 1
sub a,(ti.GroupObj-ti.AppVarObj+1) shl 1 sub a,(ti.GroupObj-ti.AppVarObj+1) shl 1
jq c,.named jq c,.named
sub a,(ImageObj-ti.GroupObj-1) shl 1
jq z,.image
ld a,(de) ld a,(de)
cp a,'.' cp a,'.'
jq z,.namedEnter jq z,.namedEnter
@ -331,6 +348,12 @@ _get_var_file_name:
ld a,13 ld a,13
sub a,c sub a,c
ret ret
.image:
inc de
ld a,(de)
ld de,_image_name+1
add a,tVarImage1
ld (de),a
.list: .list:
dec de dec de
.token: .token:
@ -344,6 +367,10 @@ _get_var_file_name:
jq .named jq .named
section .data section .data
public _image_name
_image_name:
db ti.tExtTok,tVarImage1
public _var_extensions public _var_extensions
_var_extensions: _var_extensions:
db "xnxlxmxyxsxpxpci" db "xnxlxmxyxsxpxpci"

View file

@ -69,7 +69,7 @@ uint8_t create_var(const var_name_t *var_name,
const void *data, size_t size); const void *data, size_t size);
uint8_t arc_unarc_var(const var_name_t *var_name); uint8_t arc_unarc_var(const var_name_t *var_name);
uint8_t get_var_file_name(const var_name_t *var_name, uint8_t get_var_file_name(const var_name_t *var_name,
wchar_t file_name[13]); wchar_t file_name[MAX_FILE_NAME_LENGTH]);
#ifdef __cplusplus #ifdef __cplusplus
} }