diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..821672a --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ + +obj/ + +main.8xk + +main.bin + +main.ihx + +main.lk + +main.map + +main.noi + +ti83pv116.bin + +ti83pv116.sav + +0104.key diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f0efe16 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "stdlib.h": "c", + "bitset": "c", + "format": "c" + } +} \ No newline at end of file diff --git a/83chmap.bmp b/83chmap.bmp new file mode 100644 index 0000000..28c66d9 Binary files /dev/null and b/83chmap.bmp differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6ecc126 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ + +CC=sdcc +CFLAGS=-Ilib83 -c -mz80 --std-sdcc2x --no-std-crt0 --reserve-regs-iy --opt-code-size + +OBJS=_crt0.rel clrscr.rel putchar.rel puts.rel exit.rel gotoxy.rel __assert_fail.rel \ + getchar.rel put_int.rel ctype.rel \ + main.rel + +.PHONY: all clean try +all: main.8xk + +clean: + rm -f * main.ihx main.bin main.8xk + +try: main.8xk + tilem2 --rom=ti83pv116.bin + +%.rel: lib83/%.c + $(CC) $(CFLAGS) $< -o obj/$@ + +%.rel: %.c + $(CC) $(CFLAGS) $< -o obj/$@ + +main.ihx: $(OBJS) + cd obj && $(CC) -mz80 --no-std-crt0 --code-loc 0x4000 --code-size 0x4000 --xram-loc 0x9D95 --xram-size 0x6060 $^ -o ../$@ && cd .. + +main.bin: main.ihx + objcopy -Iihex -Obinary $< $@ + +main.8xk: main.bin + rabbitsign -v -P -p -t 8xk -g $< + diff --git a/README.md b/README.md index b98c566..2120dd8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1 @@ -# ti83-sdk - -A development kit for TI83+ Flash programs using C and sdcc. \ No newline at end of file +# ti83 diff --git a/binpac8x.py b/binpac8x.py new file mode 100755 index 0000000..922321d --- /dev/null +++ b/binpac8x.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python +import sys, os, time, platform, struct, math; + +def safeprint(*args): + print(" ".join([str(arg) for arg in args])) + +def disphelp(): + safeprint("\n BinPac8x Help Menu:\n======================\n",\ + "binpac8x.py [] [-O ] []\n",\ + "-h: Display this help menu\n",\ + "source bin: A .bin file to process\n",\ + "destination: Filename of output. If omitted, output name derived from input\n",\ + "-O: Specify optional oncalcname, should be <=8 chars and ALL UPPERCASE\n\n",\ + "By default produces a .8xp file. To build for a different calculator than\n",\ + "the TI-83+/TI-84+ series, use ONE of these flags:\n",\ + "-2: TI-82 program (.82p)\n",\ + "-3: TI-83 program (.83p)\n",\ + "-5: TI-85 string (.85s)\n",\ + "-6: TI-86 program (.86p)\n",\ + "-7: TI-86 string (.86s)\n") + sys.exit(0) + return + +t_start = time.localtime() + +def parsefile(fnamein,fnameout,abspath,calctype,oncalcname): + + fullpathin = os.path.join(abspath,fnamein) + if not(os.path.exists(fullpathin)): + safeprint("Error: Input file "+fullpathin+" was not found!") + return + if fnameout == "": + if 1 > fnamein.find("."): + fnameout = fnamein + ".bin" + else: + if calctype!="7" and calctype!="5": + fnameout = fnamein[:fnamein.find(".")+1] + "8" + calctype + "p" + elif calctype=="5": + fnameout = fnamein[:fnamein.find(".")+1] + "85s" + elif calctype=="7": + fnameout = fnamein[:fnamein.find(".")+1] + "86s" + + fullpathout = os.path.join(abspath,fnameout) + if os.path.exists(fullpathout): + safeprint("Warning: Input file "+fullpathout+" exists, overwriting.") + + fhi = open(fullpathin,'rb') + fho = open(fullpathout,'wb') + + if calctype=="2": + fho.write(bytearray(b'**TI82**')) #byte 00, length 08 + fho.write(mybytearray([26,10,0])) #byte 08, length 03 + elif calctype=="3": + fho.write(bytearray(b'**TI83**')) #byte 00, length 08 + fho.write(mybytearray([26,10,0])) #byte 08, length 03 + elif calctype=="5": + fho.write(bytearray(b'**TI85**')) #byte 00, length 08 + fho.write(mybytearray([26,12,0])) #byte 08, length 03 + elif calctype=="6" or calctype=="7": + fho.write(bytearray(b'**TI86**')) #byte 00, length 08 + fho.write(mybytearray([26,10,0])) #byte 08, length 03 + else: #case "x" + fho.write(bytearray(b'**TI83F*')) #byte 00, length 08 + fho.write(mybytearray([26,10,0])) #byte 08, length 03 + + fho.write(bytearray(b'BinPac8x (c)2010 Cemetech.net&Kerm Martian')) + #byte 11, length 42 + + bincontents = fhi.read(); + fhi.close(); + binsize = len(bincontents); + bbsize_hb = math.floor(binsize/256) + bbsize_lb = binsize - 256*bbsize_hb + binsize = binsize + 2 + bincontents = mybytearray([bbsize_lb,bbsize_hb]) + bincontents + + if oncalcname == "": + oncalcname = fnameout[:fnameout.find(".")].upper(); + else: + oncalcname = oncalcname.upper() + if len(oncalcname) >=8 or calctype != "5": #TI-85 has variable-len name + while len(oncalcname) != 8: + if len(oncalcname) > 8: + oncalcname = oncalcname[:8] + else: + if calctype != "6" and calctype != "7": + oncalcname = oncalcname + chr(0); + else: + oncalcname = oncalcname + " "; #TI-86 uses space-padded name + + if calctype=="2": + headersize = 15 + elif calctype=="3": + headersize = 15 + elif calctype=="5": + headersize = 8+len(oncalcname) + elif calctype=="6" or calctype=="7": + headersize = 16 + else: #case "x" + headersize = 17 # 17-byte header + + datasize = binsize + headersize + size_hb = math.floor(datasize/256); + size_lb = datasize - 256*size_hb; + fho.write(mybytearray([size_lb,size_hb])); #byte 53, length 02 + safeprint("On-calc name: "+oncalcname) + oncalcname.encode() + bsize_hb = math.floor(binsize/256); + bsize_lb = binsize - 256*bsize_hb; + + # Construct the header in the data field + if calctype=="2" or calctype=="3": + fho.write(mybytearray([11,0])); #byte 55, length 02 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02 + fho.write(mybytearray([6])); #byte 59, length 01 + fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 60, length 08 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 68, length 02 + elif calctype=="5": + fho.write(mybytearray([headersize-2,0])) #byte 55, length 02 + fho.write(mybytearray([bsize_lb,bsize_hb])) #byte 57, length 02 + fho.write(mybytearray([12])) #byte 59, length 01 + fho.write(mybytearray([len(oncalcname)])) #byte 60, length 01 + fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 61, length varies + fho.write(mybytearray([bsize_lb,bsize_hb])) #byte 62-69, length 02 + elif calctype=="6": + fho.write(mybytearray([12,0])); #byte 55, length 02 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02 + fho.write(mybytearray([18])); #byte 59, length 01 + fho.write(mybytearray([8])) #byte 60, length 01 + fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 61, length 08 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 69, length 02 + elif calctype=="7": + fho.write(mybytearray([12,0])); #byte 55, length 02 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02 + fho.write(mybytearray([12])); #byte 59, length 01 + fho.write(mybytearray([8])) #byte 60, length 01 + fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 61, length 08 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 69, length 02 + else: + fho.write(mybytearray([13,0])); #byte 55, length 02 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02 + fho.write(mybytearray([6])); #byte 59, length 01 + fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 60, length 08 + fho.write(mybytearray([0])); #byte 68, length 01 + fho.write(mybytearray([0])); #byte 69, length 01 + fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 70, length 02 + + fho.write(bincontents); #byte 72, length binsize + + if calctype=="2" or calctype=="3": + chksum = 2*bsize_lb + 2*bsize_hb + 11 + 0 + 6; + elif calctype=="5": + chksum = 2*bsize_lb + 2*bsize_hb + (headersize - 2) + 0 + 12 + len(oncalcname); + elif calctype=="6": + chksum = 2*bsize_lb + 2*bsize_hb + 12 + 0 + 18 + 8; + elif calctype=="7": + chksum = 2*bsize_lb + 2*bsize_hb + 12 + 0 + 12 + 8; + else: + chksum = 2*bsize_lb + 2*bsize_hb + 6 + 0 + 0 + 13 + 0; #including [13,0] + + for c in oncalcname: + chksum += ord(c); + if sys.version[0] == '2': + for c in bincontents: + chksum += ord(c); + else: + for c in bincontents: + chksum += c; + chksum = chksum % 65536 + cs_hb = math.floor(chksum/256); + cs_lb = chksum - 256*cs_hb; + fho.write(mybytearray([cs_lb,cs_hb])); #byte 63, length 02 + fho.close(); + return + +def mybytes(string, encoding): + if sys.version[0] == '2': + return bytes(string); + else: + return bytes(string,encoding) + +def mybytearray(thisblist): #this stunningly awkward hack is for 2.x/3.x compat + if sys.version[0] == '2': + mystr = "" + for i in range(0,len(thisblist)): + mystr += chr(int(thisblist[i])); + return mybytes(mystr,encoding="ascii"); + else: + return bytearray(thisblist); + +if __name__ == "__main__": + safeprint(" --+=====================+--") + safeprint(" --| BinPac8x v1.2 |--") + safeprint(" --| by Kerm Martian |--") + safeprint(" --| www.Cemetech.net |--") + safeprint(" --| admin@cemetech.net |--") + safeprint(" --+=====================+--") + fnamein = "" + fnameout = "" + oncalcname = "" + if (len(sys.argv) > 1): + prefix = "" + calc = "x"; + skipiter = 0; + for i in range(1,len(sys.argv)): + if skipiter == 0: + if sys.argv[i][0] == "-": + if sys.argv[i][1] == "h": + disphelp() + if sys.argv[i][1]=="2" or sys.argv[i][1]=="3" or sys.argv[i][1]=="5" or sys.argv[i][1]=="6" or sys.argv[i][1]=="x" or sys.argv[i][1]=="7": + calc = sys.argv[i][1] + elif sys.argv[i][1] == "O": + oncalcname = sys.argv[i+1]; + skipiter = 1; + else: + safeprint("\nUnknown switch: ",sys.argv[i]) + disphelp() + #prefix = sys.argv[i][1] + else: + if prefix == "": + if (fnamein == ''): + fnamein = sys.argv[i] + else: + fnmeout = sys.argv[i] + else: + safeprint("\nUnknown switch: -",prefix,"\n") + else: + skipiter = 0; + + if fnamein == "": + safeprint("\nPlease enter the relative path to the bincontents file to pack as a .8*p: ") + fnamein = sys.stdin.readline()[:-1] + + basepath = os.path.dirname(fnamein) + safeprint("**Pass 1/1: .8"+calc+"p Construction**") + parsefile(fnamein,fnameout,basepath,calc,oncalcname) + safeprint("Total time:",str(time.mktime(time.localtime())-time.mktime(t_start)) + "s") + sys.exit() diff --git a/lib83/__assert_fail.c b/lib83/__assert_fail.c new file mode 100644 index 0000000..7aca21e --- /dev/null +++ b/lib83/__assert_fail.c @@ -0,0 +1,25 @@ + +#include +#include +#include + +void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function) { + clrscr(); + gotoxy(0, 0); + puts("Assertion failed"); + puts(__assertion); + putchar('\xff'); + puts("File: "); + puts(__file); + putchar('\xff'); + puts("Line: "); + put_int(__line); + putchar('\xff'); + puts("Function: "); + puts(__function); + putchar('\xff'); + puts("Press any key to continue ..."); + getchar(); + exit(); +} + diff --git a/lib83/_crt0.c b/lib83/_crt0.c new file mode 100644 index 0000000..35de3d9 --- /dev/null +++ b/lib83/_crt0.c @@ -0,0 +1,43 @@ + +#include + +extern void main(); + +void AppHeader() { + __asm + .db 0x80, 0x0F + .db 0, 0, 0, 0 + + .db 0x80, 0x12 + .db 0x01,0x04 + + .db 0x80, 0x21 + .db 1 + .db 0x80, 0x31 + .db 1 + .db 0x80, 0x48 + .db 75, 97, 109, 105, 108, 97, 32, 32 + .db 0x80, 0x81 + .db 1 + .db 0x80, 0x90 + .db 0x03, 0x26, 0x09, 0x04, 0x04, 0x6f, 0x1b, 0x80 + .db 0x02, 0x0d, 0x40, 0xa1, 0x6b, 0x99, 0xf6, 0x59, 0xbc, 0x67 + .db 0xf5, 0x85, 0x9c, 0x09, 0x6c, 0x0f, 0xb4, 0x03, 0x9b, 0xc9 + .db 0x03, 0x32, 0x2c, 0xe0, 0x03, 0x20, 0xe3, 0x2c, 0xf4, 0x2d + .db 0x73, 0xb4, 0x27, 0xc4, 0xa0, 0x72, 0x54, 0xb9, 0xea, 0x7c + .db 0x3b, 0xaa, 0x16, 0xf6, 0x77, 0x83, 0x7a, 0xee, 0x1a, 0xd4 + .db 0x42, 0x4c, 0x6b, 0x8b, 0x13, 0x1f, 0xbb, 0x93, 0x8b, 0xfc + .db 0x19, 0x1c, 0x3c, 0xec, 0x4d, 0xe5, 0x75 + .db 0x80, 0x7f + .db 0, 0, 0, 0 + .db 0, 0, 0, 0 + .db 0, 0, 0, 0 + .db 0, 0, 0, 0 + .db 0, 0, 0 + __endasm; + main(); + __asm + rst 0x28; + .dw 0x4027; + __endasm; +} \ No newline at end of file diff --git a/lib83/assert.h b/lib83/assert.h new file mode 100644 index 0000000..0edfbb1 --- /dev/null +++ b/lib83/assert.h @@ -0,0 +1,9 @@ + +#ifndef _ASSERT_H +#define _ASSERT_H + +#define assert(expr) ((expr) ? (void) (0) : __assert_fail(#expr, __FILE__, __LINE__, __func__)) + +extern void __assert_fail(const char *__assertion, const char *__file, unsigned int __line, const char *__function); + +#endif diff --git a/lib83/clrscr.c b/lib83/clrscr.c new file mode 100644 index 0000000..87c04f5 --- /dev/null +++ b/lib83/clrscr.c @@ -0,0 +1,13 @@ + +#include + +void clrscr() __naked { + __asm + push ix + rst #0x28 + .dw #0x4540 + pop ix + ret + __endasm; +} + diff --git a/lib83/ctype.c b/lib83/ctype.c new file mode 100644 index 0000000..415a923 --- /dev/null +++ b/lib83/ctype.c @@ -0,0 +1,74 @@ + +#include + +#define NONE 0x00 +#define ALPHA 0x01 +#define DIGIT 0x02 +#define LOWER 0x04 +#define UPPER 0x08 +#define SPECL 0x10 +#define SPACE 0x20 +#define PUNCT 0x40 +#define GRAPH 0x80 + +// TODO. +static unsigned char tab[256] = { + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE +}; + +int isalnum(int c) { + return tab[c & 0xFF] & (ALPHA | DIGIT); +} + +int isalpha(int c) { + return tab[c & 0xFF] & ALPHA; +} + +int islower(int c) { + return tab[c & 0xFF] & LOWER; +} + +int isupper(int c) { + return tab[c & 0xFF] & UPPER; +} + +int isdigit(int c) { + return tab[c & 0xFF] & DIGIT; +} + +int isspecl(int c) { + return tab[c & 0xFF] & SPECL; +} + +int isspace(int c) { + return tab[c & 0xFF] & SPACE; +} + +int ispunct(int c) { + return tab[c & 0xFF] & PUNCT; +} + +int isgraph(int c) { + return tab[c & 0xFF] & GRAPH; +} + + + diff --git a/lib83/ctype.h b/lib83/ctype.h new file mode 100644 index 0000000..e69de29 diff --git a/lib83/exit.c b/lib83/exit.c new file mode 100644 index 0000000..de6cbb1 --- /dev/null +++ b/lib83/exit.c @@ -0,0 +1,10 @@ + +#include + +void exit() __naked { + __asm + rst 0x28 + .dw 0x4027 + __endasm; +} + diff --git a/lib83/getchar.c b/lib83/getchar.c new file mode 100644 index 0000000..17ac408 --- /dev/null +++ b/lib83/getchar.c @@ -0,0 +1,22 @@ + +#include + +int getchar(void) __naked { + __asm + push ix + ; set 3, (iy+36) + .db 0xfd, 0xcb, 0x24, 0xde + push de + push hl + push bc + rst 0x28 + .dw 0x4972 + pop bc + pop hl + pop de + pop ix + ret + __endasm; + +} + diff --git a/lib83/gotoxy.c b/lib83/gotoxy.c new file mode 100644 index 0000000..10cf1aa --- /dev/null +++ b/lib83/gotoxy.c @@ -0,0 +1,11 @@ + +#include + +__at (0x844B) unsigned char curRow; +__at (0x844C) unsigned char curCol; + +void gotoxy(int x, int y) { + curRow = y; + curCol = x; +} + diff --git a/lib83/put_int.c b/lib83/put_int.c new file mode 100644 index 0000000..b68f250 --- /dev/null +++ b/lib83/put_int.c @@ -0,0 +1,18 @@ + +#include + +void put_int(int i) { + if (i < 0) { + putchar('-'); + i *= -1; + } + char buf[10]; + int j = 0; + do { + buf[j++] = i % 10 + '0'; + i /= 10; + } while (i > 0); + while (j > 0) + putchar(buf[--j]); +} + diff --git a/lib83/putchar.c b/lib83/putchar.c new file mode 100644 index 0000000..c8bd5fc --- /dev/null +++ b/lib83/putchar.c @@ -0,0 +1,33 @@ + +#include + +int putchar(int c) __naked { + c; + + __asm + ; If a is 0xA: + ld a, l + push hl + push bc + .db 0x01, 0xFF, 0x00 + or h + sbc hl,bc + pop bc + pop hl + jr nz, do_print + + push ix + rst 0x28 + .dw 0x452E + pop ix + ret + + do_print: + push ix + rst 0x28 + .dw 0x4504 + pop ix + ret + __endasm; +} + diff --git a/lib83/puts.c b/lib83/puts.c new file mode 100644 index 0000000..4eee60f --- /dev/null +++ b/lib83/puts.c @@ -0,0 +1,10 @@ + +#include + +void puts(const char * s) { + while(*s) { + putchar(*s); + s++; + } +} + diff --git a/lib83/stdio.h b/lib83/stdio.h new file mode 100644 index 0000000..650c055 --- /dev/null +++ b/lib83/stdio.h @@ -0,0 +1,13 @@ + +#ifndef STDIO_H +#define STDIO_H + +extern void clrscr(); +extern void puts(const char * s); +extern void put_int(int i); +extern int putchar(int c); +extern int getchar(void); +extern void gotoxy(int x, int y); + +#endif + diff --git a/lib83/stdlib.h b/lib83/stdlib.h new file mode 100644 index 0000000..d245032 --- /dev/null +++ b/lib83/stdlib.h @@ -0,0 +1,8 @@ + +#ifndef STDLIB_H +#define STDLIB_H + +extern void exit(); + +#endif + diff --git a/main.c b/main.c new file mode 100644 index 0000000..f53dd5f --- /dev/null +++ b/main.c @@ -0,0 +1,5 @@ +#include + +void main() { + assert(0); +}