diff --git a/CHANGELOG.md b/CHANGELOG.md index b713927..c49461d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,10 @@ ## 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. diff --git a/README.md b/README.md index 62cb334..56aa779 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# prgmTRANSFER v0.0.2b +# prgmTRANSFER v0.0.4b ### This software is still in beta, no liability for corrupted or lost files, etc! @@ -13,7 +13,7 @@ PTP or MTP transfer software. - Android 11 using the builtin Files application, check notifications after connecting to open. ## 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. 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. diff --git a/font/genfont.c b/font/genfont.c index 786da1f..306ec99 100644 --- a/font/genfont.c +++ b/font/genfont.c @@ -5,14 +5,14 @@ #include #include #include -#include int main(int argc, char **argv) { FT_Library library; FT_Error error; FT_Face face; 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_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; @@ -45,7 +45,7 @@ int main(int argc, char **argv) { "const uint8_t font[0x100][FONT_WIDTH][FONT_HEIGHT_BYTES] = {\n"); uint8_t *bitmap = calloc(width, height_bytes); 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); if ((error = FT_Load_Char(face, c, FT_LOAD_DEFAULT)) || (error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL))) return error; diff --git a/makefile b/makefile index dc428c8..d4a9d91 100644 --- a/makefile +++ b/makefile @@ -2,29 +2,47 @@ # Makefile Options # ---------------------------- -NAME ?= TRANSFER -ICON ?= transfer.png -DESCRIPTION ?= "Variable Transfer Program" -COMPRESSED ?= YES -ARCHIVED ?= YES +NATIVECC = clang -CFLAGS ?= -Wall -Wextra -Oz -CXXFLAGS ?= -Wall -Wextra -Oz +NAME = TRANSFER +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) -EXTRA_USERHEADERS ?= src/ti84pceg.inc src/font.h -EXTRA_CLEAN ?= src/font.c src/font.h font/genfont +FLAGS = -Wall -Wextra -Oz -DVERSION='"$(FULL_VERSION)"' +CFLAGS = $(FLAGS) +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 -$(error CEDEV environment path variable is not set) -endif +include $(shell cedev-config --makefile) -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 - @clang -O3 -flto $< `pkg-config --cflags --libs freetype2` -o $@ +release: BUILD_VERSION = +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 $@ diff --git a/src/main.c b/src/main.c index f9d1200..3499fb3 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,7 @@ typedef struct mtp_global mtp_global_t; #define usb_transfer_data_t mtp_global_t /* Includes */ +#include "font.h" #include "ui.h" #include "var.h" @@ -36,6 +37,8 @@ typedef struct mtp_global mtp_global_t; #define lengthof(array) (sizeof(array) / sizeof(*(array))) +#define charsof(literal) (lengthof(literal) - 1) + #define COUNT_EACH(...) +1 #define OBJECT_BUFFER \ @@ -125,13 +128,13 @@ typedef struct mtp_global mtp_global_t; } #define DATE_TIME_GET_SET 1 #define DATE_TIME_GET(current) \ - get_datetime(current.string) + get_datetime(¤t) #define DATE_TIME_SET(new) #define PERCEIVED_DEVICE_TYPE_DEF 0 #define PERCEIVED_DEVICE_TYPE_GET_SET 0 #define PERCEIVED_DEVICE_TYPE_GET(current) \ - current = 3 + current = 5 #define PERCEIVED_DEVICE_TYPE_SET(new) /* MTP Types */ @@ -164,16 +167,16 @@ typedef usb_error_t(*mtp_transaction_callback_t)( #define Los_specific L"MSFT100\1" #define Lmtp_extensions L"microsoft.com: 1.0;" #define Lmanufacturer L"Texas Instruments Incorporated" -#define Lproduct L"TI-83 Premium CE" /* default must be longer than alt */ -#define Lproduct84 L"TI-84 Plus CE" -#define Ldevice_version L"2.20" +#define Lproduct L"TI-84 Plus CE" +#define Lproduct83 L"TI-83 Premium CE" +#define Ldevice_version L"255.255.255.65535" #define Lserial_number L"0000000000000000" #define Lcharging_cfg L"Charging" #define Lmtp_interface L"MTP" /* magic string to aid detection */ #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_volume_id Lserial_number"A" +#define Larc_volume_id Lserial_number "A" #define Lfactory_datetime L"20150101T000000" typedef enum string_id { @@ -714,7 +717,8 @@ typedef struct mtp_device_info { mtp_byte_t manufacturer_length; wchar_t manufacturer[lengthof(Lmanufacturer)]; 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; wchar_t device_version[lengthof(Ldevice_version)]; mtp_byte_t serial_number_length; @@ -842,18 +846,12 @@ static usb_endpoint_t get_endpoint( static usb_error_t stall_data_endpoints( usb_endpoint_t endpoint) { printf("stalling data endpoints\n"); -#if 0 - usb_error_t error; - error = usb_StallEndpoint( + usb_error_t error = usb_SetEndpointHalt( get_endpoint(endpoint, MTP_EP_DATA_IN)); if (error == USB_SUCCESS) - error = usb_StallEndpoint( + error = usb_SetEndpointHalt( get_endpoint(endpoint, MTP_EP_DATA_OUT)); return error; -#else - (void)endpoint; - return USB_ERROR_FAILED; -#endif } static usb_error_t schedule_event( @@ -1053,19 +1051,19 @@ static uint16_t compute_checksum( } static void get_datetime( - wchar_t result[lengthof(Lfactory_datetime)]) { + datetime_t *result) { uint16_t year; - uint8_t month, day, hour, minute, second, - i = lengthof(Lfactory_datetime); - char string[lengthof(Lfactory_datetime)], - *pointer = string; + uint8_t month, day, hour, minute, second; + char string[lengthof(Lfactory_datetime)]; boot_GetDate(&day, &month, &year); boot_GetTime(&second, &minute, &hour); - sprintf(string, "%04u%02u%02uT%02u%02u%02u", - year, month, day, hour, minute, second); - do - *(char *)result++ = *pointer++; - while (--i); + int count = + snprintf(string, lengthof(string), + "%04u%02u%02uT%02u%02u%02u", + year, month, day, hour, minute, second); + result->length = count <= 0 ? 0 : count + 1; + for (mtp_byte_t i = 0; i != result->length; ++i) + result->string[i] = string[i]; } static int delete_object( @@ -1183,6 +1181,7 @@ static int send_object( version = entry->version; flag = entry->flag; } + (void)version; flag &= global->transaction.pending .send_object.mask; flag |= global->transaction.pending @@ -2199,7 +2198,7 @@ static usb_error_t usb_event(usb_event_t event, (USB_DEVICE_TO_HOST | USB_STANDARD_REQUEST | USB_RECIPIENT_DEVICE) && - setup->bRequest == USB_GET_DESCRIPTOR && + setup->bRequest == USB_GET_DESCRIPTOR_REQUEST && setup->wValue == 0x03EE && !setup->wIndex) { DEFINE_STRING_DESCRIPTOR(const, os_specific); error = usb_ScheduleTransfer( @@ -2272,10 +2271,19 @@ int main(void) { static mtp_global_t global; usb_error_t error; ui_Init(); - printf(" TRANSFER v0.0.2b\n" - " Connect USB to PC.\n" - " Press [clear] to exit.\n" - "--------------------------------"); +#define CENTER(string) \ + printf("%*s%.*s", \ + (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 = { .standard_version = 100, /* 1.00 */ .mtp_vendor_extension_id = 6, @@ -2291,7 +2299,11 @@ int main(void) { FOR_EACH_SUPP_OPR(LIST_SUPP_OPR) }, .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 = { #define LIST_SUPP_DP(type, name, form) \ @@ -2312,14 +2324,8 @@ int main(void) { }, .manufacturer_length = lengthof(device_info.manufacturer), .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 = { \ .storage_type = MTP_ST_FIXED_RAM, \ .filesystem_type = MTP_FT_GENERIC_FLAT, \ @@ -2337,7 +2343,7 @@ int main(void) { FOR_EACH_STORAGE(DEFINE_STORAGE_INFO) /* Standard USB Descriptors */ FOR_EACH_STRING_DESCRIPTOR(DEFINE_STRING_DESCRIPTOR) - DEFINE_STRING_DESCRIPTOR(const, product84) + DEFINE_STRING_DESCRIPTOR(const, product83) const static usb_string_descriptor_t *strings[] = { #define ADDRESSOF_STRING_DESCRIPTOR(const, name) &name, FOR_EACH_STRING_DESCRIPTOR(ADDRESSOF_STRING_DESCRIPTOR) @@ -2420,7 +2426,7 @@ int main(void) { .bMaxPacketSize0 = 0x40u, .idVendor = 0x0451u, .idProduct = 0xE010u, - .bcdDevice = 0x260u, /* 2.60 */ + .bcdDevice = 0x240u, /* 2.40 */ .iManufacturer = Imanufacturer, .iProduct = Iproduct, .iSerialNumber = Iserial_number, @@ -2434,34 +2440,68 @@ int main(void) { .strings = strings, }; 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[] = { &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) \ &name##_storage_info.volume_identifier[2 * lengthof(info->calcid)], 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; ) { mtp_byte_t nibble = info->calcid[--i >> 1]; if (!(i & 1)) diff --git a/src/ui.c b/src/ui.c index 85a44cd..5e6394f 100644 --- a/src/ui.c +++ b/src/ui.c @@ -8,9 +8,7 @@ #include #include -#define STATIC_ROWS 4 - -static uint8_t row, col, swap; +static uint8_t static_rows, row, col, swap; #define buffer(n) (*(uint8_t (*)[4][LCD_WIDTH][LCD_HEIGHT >> 1])lcd_Ram)[(n) ^ swap] void ui_Init(void) { @@ -31,6 +29,10 @@ void ui_Init(void) { *(volatile uint8_t *volatile *)&lcd_UpBase = &buffer(0)[0][0]; } +void ui_Lock(void) { + static_rows = row; +} + void ui_Cleanup(void) { boot_ClearVRAM(); boot_TurnOn(); @@ -56,7 +58,7 @@ void outchar(char c) { sizeof(buffer(1)) - FONT_HEIGHT_BYTES); for (unsigned x = 0; x != LCD_WIDTH; ++x) { 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) * FONT_HEIGHT) >> 1], 0xFF, FONT_HEIGHT_BYTES); } diff --git a/src/ui.h b/src/ui.h index e7f3eaf..d998800 100644 --- a/src/ui.h +++ b/src/ui.h @@ -2,6 +2,7 @@ #define UI_H void ui_Init(void); +void ui_Lock(void); void ui_Cleanup(void); #endif diff --git a/src/var.asm b/src/var.asm index 596fe92..396f470 100644 --- a/src/var.asm +++ b/src/var.asm @@ -234,6 +234,11 @@ _arc_unarc_var: ex (sp),iy push de .enter: + ld a,(de) + cp a,'A' + ret c + cp a,ti.tAns + ret z ld hl,.return call ti.PushErrorHandler lea hl,iy