From dfbf66ea398ead2670cb30390fb8303dda2ca3ed Mon Sep 17 00:00:00 2001 From: Godzil Date: Wed, 31 Jan 2018 14:10:57 +0000 Subject: [PATCH] Initial commit from latest tar.gz file --- INSTALL | 3 + Makefile | 37 + bin/Makefile | 20 + common-gtc.mk | 13 + common.mk | 11 + configure | 20 + doc/building.html | 55 + doc/cmdline.html | 118 + doc/credits.html | 83 + doc/examples.html | 14 + doc/extensions.html | 352 ++ doc/faq.html | 112 + doc/glossary.html | 51 + doc/index.html | 51 + doc/layout/default.css | 1 + doc/layout/simple.css | 89 + doc/license-gpl2.html | 354 +++ doc/missing.html | 14 + doc/oncalc.html | 93 + doc/preprocessor.html | 27 + doc/specificities.html | 78 + doc/version.html | 32 + doc/windows.html | 29 + gtc/Makefile | 96 + gtc/Makefile.orig | 87 + gtc/script/mkprotos.rb | 114 + gtc/src/Makefile | 4 + gtc/src/all.c | 201 ++ gtc/src/analyze.c | 816 +++++ gtc/src/bin2calc.c | 102 + gtc/src/c.h | 548 ++++ gtc/src/cglbdec.h | 303 ++ gtc/src/cmain.c | 675 ++++ gtc/src/decl.c | 1657 ++++++++++ gtc/src/define.h | 378 +++ gtc/src/error.c | 150 + gtc/src/error.h | 58 + gtc/src/expr.c | 2157 +++++++++++++ gtc/src/expr.h | 169 + gtc/src/ffplib.h | 74 + gtc/src/flashend.c | 24 + gtc/src/flashhdr.c | 210 ++ gtc/src/flashhdr.h | 301 ++ gtc/src/func.c | 471 +++ gtc/src/gen.h | 352 ++ gtc/src/gen68k.c | 3536 +++++++++++++++++++++ gtc/src/genffp.c | 174 + gtc/src/genstmt.c | 1248 ++++++++ gtc/src/getasm.c | 718 +++++ gtc/src/getsym.c | 2293 +++++++++++++ gtc/src/gtdevcomm.c | 43 + gtc/src/gtdevcomm.h | 44 + gtc/src/gtpack/gtpack.c | 2259 +++++++++++++ gtc/src/gtpack/packhead.h | 99 + gtc/src/gtpack/revtools.h | 108 + gtc/src/gtpack/tt.h | 48 + gtc/src/gtpack/ttunpack.h | 49 + gtc/src/gtpack/ttversion.h | 53 + gtc/src/identity.h | 22 + gtc/src/init.c | 434 +++ gtc/src/intexpr.c | 96 + gtc/src/memmgt.c | 532 ++++ gtc/src/optimize.c | 887 ++++++ gtc/src/out68k_as.c | 3017 ++++++++++++++++++ gtc/src/out68k_exe.h | 71 + gtc/src/pch.h | 53 + gtc/src/peep68k.c | 1291 ++++++++ gtc/src/preproc.c | 572 ++++ gtc/src/protos.h | 329 ++ gtc/src/reg68k.c | 446 +++ gtc/src/searchkw.c | 182 ++ gtc/src/securecommdef.h | 23 + gtc/src/stmt.c | 952 ++++++ gtc/src/sunpack.c | 91 + gtc/src/symbol.c | 343 ++ gtc/src/trees.c | 247 ++ gtc/src/vcg.c | 98 + gtc/src/version.h | 8 + h/Makefile | 24 + h/all | 0 h/legacy/README | 1 + h/legacy/ezgen | 67 + h/legacy/ezgensc | 42 + h/legacy/genle | 1 + h/legacy/inclgen | 4 + h/legacy/include | 1 + h/processed/COPYING | 340 ++ h/processed/assert.89t | Bin 0 -> 222 bytes h/processed/compat.89t | Bin 0 -> 2113 bytes h/processed/default.89t | Bin 0 -> 3054 bytes h/processed/doors.89t | Bin 0 -> 906 bytes h/processed/extgraph.89t | Bin 0 -> 113 bytes h/processed/gen.89t | Bin 0 -> 108 bytes h/processed/nostub.89t | Bin 0 -> 629 bytes h/processed/patch.89t | Bin 0 -> 5660 bytes h/processed/std.89t | Bin 0 -> 168 bytes h/processed/tigcclib.89t | Bin 0 -> 402 bytes h/processed/ttunpack.89t | Bin 0 -> 3610 bytes h/processed/xupak.89t | Bin 0 -> 429 bytes h/script/strip.pl | 31 + h/src/COPYING | 340 ++ h/src/assert.h | 5 + h/src/compat.h | 66 + h/src/default.h | 132 + h/src/doors.h | 47 + h/src/extgraph.h | 1 + h/src/gen.h | 1 + h/src/nostub.h | 36 + h/src/patch.h | 420 +++ h/src/std.h | 4 + h/src/tigcclib.h | 17 + h/src/ttunpack.h | 81 + h/src/xupak.h | 12 + pch/Makefile | 81 + pch/all | 0 pch/deflt.txt | 345 ++ pch/estack.89y | Bin 0 -> 12268 bytes pch/estack.def | 533 ++++ pch/estack.pch | Bin 0 -> 12172 bytes pch/estackle.89y | Bin 0 -> 5670 bytes pch/estackle.def | 124 + pch/estackle.pch | Bin 0 -> 5574 bytes pch/events.89y | Bin 0 -> 4300 bytes pch/events.def | 124 + pch/events.pch | Bin 0 -> 4204 bytes pch/ext.mk | 5 + pch/homescr.89y | Bin 0 -> 1438 bytes pch/homescr.def | 20 + pch/homescr.pch | Bin 0 -> 1342 bytes pch/keywords.89y | Bin 0 -> 792 bytes pch/keywords.def | 43 + pch/keywords.pch | Bin 0 -> 696 bytes pch/script/merge.pl | 19 + pch/src/COPYING | 340 ++ pch/src/alloc.pchsource | 40 + pch/src/ams2-basfunc.pchsource | 111 + pch/src/ams2-basop.pchsource | 30 + pch/src/ams2-kbd.pchsource | 6 + pch/src/ams2-menus.pchsource | 10 + pch/src/args-le.pchsource | 48 + pch/src/args.pchsource | 263 ++ pch/src/asmtypes.pchsource | 20 + pch/src/assert.pchsource | 1 + pch/src/bascmd.pchsource | 135 + pch/src/basfunc.pchsource | 28 + pch/src/basop.pchsource | 17 + pch/src/cert.pchsource | 27 + pch/src/compat-x.pchsource | 89 + pch/src/compat.pchsource | 87 + pch/src/compiler-internals.pchsource | 10 + pch/src/ctype.pchsource | 30 + pch/src/dialogs.pchsource | 38 + pch/src/dll.pchsource | 26 + pch/src/error-le.pchsource | 37 + pch/src/error.pchsource | 209 ++ pch/src/estack.pchsource | 704 ++++ pch/src/estackle.pchsource | 167 + pch/src/events.pchsource | 142 + pch/src/flash.pchsource | 24 + pch/src/float.pchsource | 41 + pch/src/gdraw.pchsource | 17 + pch/src/graph.pchsource | 87 + pch/src/gray.pchsource | 87 + pch/src/gtc.pchsource | 5 + pch/src/homescr.pchsource | 29 + pch/src/intr.pchsource | 73 + pch/src/kbd.pchsource | 66 + pch/src/keywords.pchsource | 42 + pch/src/lex.txt | 74 + pch/src/limits.pchsource | 18 + pch/src/link.pchsource | 36 + pch/src/math.pchsource | 67 + pch/src/mem.pchsource | 9 + pch/src/menus.pchsource | 105 + pch/src/pchlog.pchsource | 236 ++ pch/src/peekpoke.pchsource | 21 + pch/src/rsa.pchsource | 12 + pch/src/setjmp.pchsource | 5 + pch/src/sprites.pchsource | 9 + pch/src/statline-vle.pchsource | 15 + pch/src/statline.pchsource | 56 + pch/src/stdarg.pchsource | 6 + pch/src/stdhead-ams2.pchmerge | 6 + pch/src/stdhead-light.pchmerge | 31 + pch/src/stdhead.pchmerge | 41 + pch/src/stdio.pchsource | 69 + pch/src/stdlib.pchsource | 35 + pch/src/string.pchsource | 26 + pch/src/system.pchsource | 63 + pch/src/textedit.pchsource | 29 + pch/src/tigcc-archive/COMPILING | 13 + pch/src/tigcc-archive/License.txt | 27 + pch/src/tigcc-archive/addbf.s | 6 + pch/src/tigcc-archive/ashldi.s | 24 + pch/src/tigcc-archive/ashrdi.s | 31 + pch/src/tigcc-archive/assert.s | 59 + pch/src/tigcc-archive/atexit.s | 107 + pch/src/tigcc-archive/atof.s | 44 + pch/src/tigcc-archive/atoi.c | 16 + pch/src/tigcc-archive/atol.c | 13 + pch/src/tigcc-archive/bc.s | 19 + pch/src/tigcc-archive/bcopy.s | 13 + pch/src/tigcc-archive/bsearch.c | 19 + pch/src/tigcc-archive/bzero.s | 12 + pch/src/tigcc-archive/calloc.s | 24 + pch/src/tigcc-archive/calloc_throw.s | 12 + pch/src/tigcc-archive/clrscr.s | 12 + pch/src/tigcc-archive/cmpbf.s | 12 + pch/src/tigcc-archive/contrastdn.s | 10 + pch/src/tigcc-archive/contrastup.s | 10 + pch/src/tigcc-archive/divbf.s | 6 + pch/src/tigcc-archive/divdi.s | 37 + pch/src/tigcc-archive/diventry.s | 11 + pch/src/tigcc-archive/divsi.s | 6 + pch/src/tigcc-archive/dll.c | 70 + pch/src/tigcc-archive/dummyhandler.s | 5 + pch/src/tigcc-archive/enter_ghost_space.s | 36 + pch/src/tigcc-archive/exit.s | 10 + pch/src/tigcc-archive/fclose.c | 16 + pch/src/tigcc-archive/fgetc.c | 18 + pch/src/tigcc-archive/fgets.c | 14 + pch/src/tigcc-archive/fixbf.s | 7 + pch/src/tigcc-archive/floatbf.s | 6 + pch/src/tigcc-archive/fopen.c | 68 + pch/src/tigcc-archive/fpcall.s | 17 + pch/src/tigcc-archive/fpentry.s | 11 + pch/src/tigcc-archive/fprintf.s | 17 + pch/src/tigcc-archive/fputc.c | 33 + pch/src/tigcc-archive/fputchar.s | 68 + pch/src/tigcc-archive/fputs.s | 15 + pch/src/tigcc-archive/fread.c | 17 + pch/src/tigcc-archive/freetimer.s | 24 + pch/src/tigcc-archive/fseek.c | 17 + pch/src/tigcc-archive/fsetbufsize.c | 7 + pch/src/tigcc-archive/ftell.c | 7 + pch/src/tigcc-archive/fwrite.c | 14 + pch/src/tigcc-archive/getappid.s | 57 + pch/src/tigcc-archive/gray.s | 675 ++++ pch/src/tigcc-archive/grayversion.c | 1 + pch/src/tigcc-archive/homestore.s | 22 + pch/src/tigcc-archive/homestorepair.c | 25 + pch/src/tigcc-archive/hrealloc_throw.s | 17 + pch/src/tigcc-archive/isextalnum.s | 5 + pch/src/tigcc-archive/isextpunct.s | 5 + pch/src/tigcc-archive/kbd_queue.s | 7 + pch/src/tigcc-archive/loaddll_throw.s | 14 + pch/src/tigcc-archive/lshrdi.s | 24 + pch/src/tigcc-archive/malloc_throw.s | 18 + pch/src/tigcc-archive/moddi.s | 30 + pch/src/tigcc-archive/modsi.s | 6 + pch/src/tigcc-archive/mulbf.s | 6 + pch/src/tigcc-archive/muldi.s | 58 + pch/src/tigcc-archive/mulsi.s | 17 + pch/src/tigcc-archive/negbf.s | 6 + pch/src/tigcc-archive/nocallback.s | 8 + pch/src/tigcc-archive/printf.s | 17 + pch/src/tigcc-archive/push_longint.s | 43 + pch/src/tigcc-archive/push_longlongint.s | 50 + pch/src/tigcc-archive/push_shortint.s | 43 + pch/src/tigcc-archive/pushfifonode.c | 16 + pch/src/tigcc-archive/puts.s | 13 + pch/src/tigcc-archive/qsort.c | 22 + pch/src/tigcc-archive/rand.s | 26 + pch/src/tigcc-archive/realloc.s | 38 + pch/src/tigcc-archive/realloc_throw.s | 12 + pch/src/tigcc-archive/registertimer.s | 56 + pch/src/tigcc-archive/rename.c | 10 + pch/src/tigcc-archive/rowread.s | 16 + pch/src/tigcc-archive/sprite16.c | 18 + pch/src/tigcc-archive/sprite32.c | 23 + pch/src/tigcc-archive/sprite8.c | 18 + pch/src/tigcc-archive/strputchar.s | 11 + pch/src/tigcc-archive/strtol.c | 60 + pch/src/tigcc-archive/strtoul.c | 57 + pch/src/tigcc-archive/subbf.s | 6 + pch/src/tigcc-archive/tigcc.tpr | 147 + pch/src/tigcc-archive/tmpnam.c | 23 + pch/src/tigcc-archive/udivdi.s | 43 + pch/src/tigcc-archive/udivsi.s | 6 + pch/src/tigcc-archive/umoddi.s | 40 + pch/src/tigcc-archive/umodsi.s | 6 + pch/src/tigcc-archive/unlink.c | 9 + pch/src/timath.pchsource | 116 + pch/src/tiosdlg-merge.pchmerge | 6 + pch/src/values.pchsource | 30 + pch/src/vat-le.pchsource | 124 + pch/src/vat.pchsource | 141 + pch/src/version.pchsource | 6 + pch/src/wingraph.pchsource | 113 + pch/srcdata/C-loseF-ile.ref | 1 + pch/srcdata/CI1.ext | Bin 0 -> 50 bytes pch/srcdata/CI2.ext | Bin 0 -> 58 bytes pch/srcdata/CI3.ext | Bin 0 -> 46 bytes pch/srcdata/O-penF-ile.ref | 1 + pch/srcdata/OpenFile.ext | Bin 0 -> 224 bytes pch/srcdata/__mulsi3_rp.ref | 1 + pch/srcdata/__mulsi3si2_rp.ref | 1 + pch/srcdata/__mulsi3ui2_rp.ref | 1 + pch/srcdata/export.dat | Bin 0 -> 1247 bytes pch/srcdata/tigcc.a | Bin 0 -> 46014 bytes pch/stdhead.89y | Bin 0 -> 40446 bytes pch/stdhead.def | 939 ++++++ pch/stdhead.pch | Bin 0 -> 40350 bytes pch/subprojects/xupaki.pch | Bin 0 -> 860 bytes pch/subprojects/xupaki/Unpack2.o | Bin 0 -> 968 bytes pch/subprojects/xupaki/a2ext/U-npack.ref | 1 + pch/subprojects/xupaki/a2ext/Unpack2.ext | Bin 0 -> 774 bytes pch/subprojects/xupaki/a2ext/Unpack2.o | Bin 0 -> 968 bytes pch/subprojects/xupaki/a2ext/deflt.txt | 1 + pch/subprojects/xupaki/a2ext/export.dat | Bin 0 -> 8 bytes pch/subprojects/xupaki/export.dat | Bin 0 -> 8 bytes pch/subprojects/xupaki/xupaki.pchsource | 1 + pch/tiosdlg.89y | Bin 0 -> 6030 bytes pch/tiosdlg.def | 168 + pch/tiosdlg.pch | Bin 0 -> 5934 bytes pch/wingraph.89y | Bin 0 -> 2540 bytes pch/wingraph.def | 73 + pch/wingraph.pch | Bin 0 -> 2444 bytes pch/xupaki.89y | Bin 0 -> 956 bytes pch/xupaki.pch | Bin 0 -> 860 bytes platform.mk | 2 + readme.html | 11 + ti68k/Makefile | 51 + ti68k/bin-89/assert.89t | Bin 0 -> 222 bytes ti68k/bin-89/compat.89t | Bin 0 -> 2113 bytes ti68k/bin-89/default.89t | Bin 0 -> 3054 bytes ti68k/bin-89/doors.89t | Bin 0 -> 906 bytes ti68k/bin-89/estack.89y | Bin 0 -> 12268 bytes ti68k/bin-89/estackle.89y | Bin 0 -> 5670 bytes ti68k/bin-89/events.89y | Bin 0 -> 4300 bytes ti68k/bin-89/extgraph.89t | Bin 0 -> 113 bytes ti68k/bin-89/gen.89t | Bin 0 -> 108 bytes ti68k/bin-89/gtc-ide.89z | Bin 0 -> 30923 bytes ti68k/bin-89/gtc.89k | Bin 0 -> 109161 bytes ti68k/bin-89/homescr.89y | Bin 0 -> 1438 bytes ti68k/bin-89/keywords.89y | Bin 0 -> 792 bytes ti68k/bin-89/nostub.89t | Bin 0 -> 629 bytes ti68k/bin-89/patch.89t | Bin 0 -> 5660 bytes ti68k/bin-89/std.89t | Bin 0 -> 168 bytes ti68k/bin-89/stdhead.89y | Bin 0 -> 40446 bytes ti68k/bin-89/tigcclib.89t | Bin 0 -> 402 bytes ti68k/bin-89/tiosdlg.89y | Bin 0 -> 6030 bytes ti68k/bin-89/ttunpack.89t | Bin 0 -> 3610 bytes ti68k/bin-89/wingraph.89y | Bin 0 -> 2540 bytes ti68k/bin-89/xupak.89t | Bin 0 -> 429 bytes ti68k/bin-89/xupaki.89y | Bin 0 -> 956 bytes ti68k/bin-92p/assert.9xt | Bin 0 -> 222 bytes ti68k/bin-92p/compat.9xt | Bin 0 -> 2113 bytes ti68k/bin-92p/default.9xt | Bin 0 -> 3054 bytes ti68k/bin-92p/doors.9xt | Bin 0 -> 906 bytes ti68k/bin-92p/estack.9xy | Bin 0 -> 12268 bytes ti68k/bin-92p/estackle.9xy | Bin 0 -> 5670 bytes ti68k/bin-92p/events.9xy | Bin 0 -> 4300 bytes ti68k/bin-92p/extgraph.9xt | Bin 0 -> 113 bytes ti68k/bin-92p/gen.9xt | Bin 0 -> 108 bytes ti68k/bin-92p/gtc-ide.9xz | Bin 0 -> 31019 bytes ti68k/bin-92p/gtc.9xk | Bin 0 -> 109161 bytes ti68k/bin-92p/homescr.9xy | Bin 0 -> 1438 bytes ti68k/bin-92p/keywords.9xy | Bin 0 -> 792 bytes ti68k/bin-92p/nostub.9xt | Bin 0 -> 629 bytes ti68k/bin-92p/patch.9xt | Bin 0 -> 5660 bytes ti68k/bin-92p/std.9xt | Bin 0 -> 168 bytes ti68k/bin-92p/stdhead.9xy | Bin 0 -> 40446 bytes ti68k/bin-92p/tigcclib.9xt | Bin 0 -> 402 bytes ti68k/bin-92p/tiosdlg.9xy | Bin 0 -> 6030 bytes ti68k/bin-92p/ttunpack.9xt | Bin 0 -> 3610 bytes ti68k/bin-92p/wingraph.9xy | Bin 0 -> 2540 bytes ti68k/bin-92p/xupak.9xt | Bin 0 -> 429 bytes ti68k/bin-92p/xupaki.9xy | Bin 0 -> 956 bytes ti68k/bin-v200/assert.v2t | Bin 0 -> 222 bytes ti68k/bin-v200/compat.v2t | Bin 0 -> 2113 bytes ti68k/bin-v200/default.v2t | Bin 0 -> 3054 bytes ti68k/bin-v200/doors.v2t | Bin 0 -> 906 bytes ti68k/bin-v200/estack.v2y | Bin 0 -> 12268 bytes ti68k/bin-v200/estackle.v2y | Bin 0 -> 5670 bytes ti68k/bin-v200/events.v2y | Bin 0 -> 4300 bytes ti68k/bin-v200/extgraph.v2t | Bin 0 -> 113 bytes ti68k/bin-v200/gen.v2t | Bin 0 -> 108 bytes ti68k/bin-v200/gtc-ide.v2z | Bin 0 -> 31019 bytes ti68k/bin-v200/gtc.v2k | Bin 0 -> 109161 bytes ti68k/bin-v200/homescr.v2y | Bin 0 -> 1438 bytes ti68k/bin-v200/keywords.v2y | Bin 0 -> 792 bytes ti68k/bin-v200/nostub.v2t | Bin 0 -> 629 bytes ti68k/bin-v200/patch.v2t | Bin 0 -> 5660 bytes ti68k/bin-v200/std.v2t | Bin 0 -> 168 bytes ti68k/bin-v200/stdhead.v2y | Bin 0 -> 40446 bytes ti68k/bin-v200/tigcclib.v2t | Bin 0 -> 402 bytes ti68k/bin-v200/tiosdlg.v2y | Bin 0 -> 6030 bytes ti68k/bin-v200/ttunpack.v2t | Bin 0 -> 3610 bytes ti68k/bin-v200/wingraph.v2y | Bin 0 -> 2540 bytes ti68k/bin-v200/xupak.v2t | Bin 0 -> 429 bytes ti68k/bin-v200/xupaki.v2y | Bin 0 -> 956 bytes ti68k/ide/Makefile | 55 + ti68k/ide/autoint_fix.h | 92 + ti68k/ide/axplore.h | 223 ++ ti68k/ide/bin/gtc-ide.89z | Bin 0 -> 30923 bytes ti68k/ide/bin/gtc-ide.9xz | Bin 0 -> 31019 bytes ti68k/ide/bin/gtc-ide.v2z | Bin 0 -> 31019 bytes ti68k/ide/dialogs.h | 332 ++ ti68k/ide/display.h | 652 ++++ ti68k/ide/edit.h | 668 ++++ ti68k/ide/editor.h | 227 ++ ti68k/ide/editui.h | 551 ++++ ti68k/ide/files.h | 98 + ti68k/ide/font.bin | Bin 0 -> 1536 bytes ti68k/ide/font.h | 66 + ti68k/ide/gtdev-apphdr.h | 122 + ti68k/ide/gtdev-plugins.h | 58 + ti68k/ide/gtdev-securecomm.h | 28 + ti68k/ide/handlers.h | 224 ++ ti68k/ide/limits.h | 14 + ti68k/ide/main.c | 305 ++ ti68k/ide/pchutil.h | 113 + ti68k/ide/plugins.h | 51 + ti68k/ide/sunpack.c | 73 + ti68k/ide/tags | 600 ++++ ti68k/ide/textedit.h | 132 + ti68k/ide/util.h | 48 + ti68k/ide/workspace.h | 179 ++ ti68k/mkinfo-89-flashapp | 0 ti68k/mkinfo-89-h | 0 ti68k/mkinfo-89-ide | 0 ti68k/mkinfo-89-pch | 0 ti68k/mkinfo-92p-flashapp | 0 ti68k/mkinfo-92p-h | 0 ti68k/mkinfo-92p-ide | 0 ti68k/mkinfo-92p-pch | 0 ti68k/mkinfo-v200-flashapp | 0 ti68k/mkinfo-v200-h | 0 ti68k/mkinfo-v200-ide | 0 ti68k/mkinfo-v200-pch | 0 ti68k/srcdata/flashapp/gtc-89.89k | Bin 0 -> 109161 bytes ti68k/srcdata/flashapp/gtc-92p.9xk | Bin 0 -> 109161 bytes tools/Makefile | 8 + tools/dat89y/Makefile | 14 + tools/dat89y/bin2calc.c | 85 + tools/dat89y/dat89y.c | 104 + tools/obj2ti/Makefile | 12 + tools/obj2ti/m68kdefs.h | 43 + tools/obj2ti/obj2ti.cpp | 1244 ++++++++ tools/obj2ti/obj2ti.h | 262 ++ tools/obj2ti/str.h | 36 + tools/obj2ti/stubs.h | 15 + tools/pchmaker/Makefile | 12 + tools/pchmaker/pchmaker.c | 556 ++++ tools/pchmaker/spack.c | 223 ++ tools/txt89t/Makefile | 14 + tools/txt89t/bin2calc.c | 85 + tools/txt89t/txt89t.c | 123 + 449 files changed, 50397 insertions(+) create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 bin/Makefile create mode 100644 common-gtc.mk create mode 100644 common.mk create mode 100755 configure create mode 100644 doc/building.html create mode 100644 doc/cmdline.html create mode 100644 doc/credits.html create mode 100644 doc/examples.html create mode 100644 doc/extensions.html create mode 100644 doc/faq.html create mode 100644 doc/glossary.html create mode 100644 doc/index.html create mode 100644 doc/layout/default.css create mode 100644 doc/layout/simple.css create mode 100644 doc/license-gpl2.html create mode 100644 doc/missing.html create mode 100644 doc/oncalc.html create mode 100644 doc/preprocessor.html create mode 100644 doc/specificities.html create mode 100644 doc/version.html create mode 100644 doc/windows.html create mode 100644 gtc/Makefile create mode 100644 gtc/Makefile.orig create mode 100644 gtc/script/mkprotos.rb create mode 100644 gtc/src/Makefile create mode 100644 gtc/src/all.c create mode 100644 gtc/src/analyze.c create mode 100644 gtc/src/bin2calc.c create mode 100644 gtc/src/c.h create mode 100644 gtc/src/cglbdec.h create mode 100644 gtc/src/cmain.c create mode 100644 gtc/src/decl.c create mode 100644 gtc/src/define.h create mode 100644 gtc/src/error.c create mode 100644 gtc/src/error.h create mode 100644 gtc/src/expr.c create mode 100644 gtc/src/expr.h create mode 100644 gtc/src/ffplib.h create mode 100644 gtc/src/flashend.c create mode 100644 gtc/src/flashhdr.c create mode 100644 gtc/src/flashhdr.h create mode 100644 gtc/src/func.c create mode 100644 gtc/src/gen.h create mode 100644 gtc/src/gen68k.c create mode 100644 gtc/src/genffp.c create mode 100644 gtc/src/genstmt.c create mode 100644 gtc/src/getasm.c create mode 100644 gtc/src/getsym.c create mode 100644 gtc/src/gtdevcomm.c create mode 100644 gtc/src/gtdevcomm.h create mode 100644 gtc/src/gtpack/gtpack.c create mode 100644 gtc/src/gtpack/packhead.h create mode 100644 gtc/src/gtpack/revtools.h create mode 100644 gtc/src/gtpack/tt.h create mode 100644 gtc/src/gtpack/ttunpack.h create mode 100644 gtc/src/gtpack/ttversion.h create mode 100644 gtc/src/identity.h create mode 100644 gtc/src/init.c create mode 100644 gtc/src/intexpr.c create mode 100644 gtc/src/memmgt.c create mode 100644 gtc/src/optimize.c create mode 100644 gtc/src/out68k_as.c create mode 100644 gtc/src/out68k_exe.h create mode 100644 gtc/src/pch.h create mode 100644 gtc/src/peep68k.c create mode 100644 gtc/src/preproc.c create mode 100644 gtc/src/protos.h create mode 100644 gtc/src/reg68k.c create mode 100644 gtc/src/searchkw.c create mode 100644 gtc/src/securecommdef.h create mode 100644 gtc/src/stmt.c create mode 100644 gtc/src/sunpack.c create mode 100644 gtc/src/symbol.c create mode 100644 gtc/src/trees.c create mode 100644 gtc/src/vcg.c create mode 100644 gtc/src/version.h create mode 100644 h/Makefile create mode 100644 h/all create mode 100644 h/legacy/README create mode 100644 h/legacy/ezgen create mode 100644 h/legacy/ezgensc create mode 100644 h/legacy/genle create mode 100644 h/legacy/inclgen create mode 100644 h/legacy/include create mode 100644 h/processed/COPYING create mode 100644 h/processed/assert.89t create mode 100644 h/processed/compat.89t create mode 100644 h/processed/default.89t create mode 100644 h/processed/doors.89t create mode 100644 h/processed/extgraph.89t create mode 100644 h/processed/gen.89t create mode 100644 h/processed/nostub.89t create mode 100644 h/processed/patch.89t create mode 100644 h/processed/std.89t create mode 100644 h/processed/tigcclib.89t create mode 100644 h/processed/ttunpack.89t create mode 100644 h/processed/xupak.89t create mode 100644 h/script/strip.pl create mode 100644 h/src/COPYING create mode 100644 h/src/assert.h create mode 100644 h/src/compat.h create mode 100644 h/src/default.h create mode 100644 h/src/doors.h create mode 100644 h/src/extgraph.h create mode 100644 h/src/gen.h create mode 100644 h/src/nostub.h create mode 100644 h/src/patch.h create mode 100644 h/src/std.h create mode 100644 h/src/tigcclib.h create mode 100644 h/src/ttunpack.h create mode 100644 h/src/xupak.h create mode 100644 pch/Makefile create mode 100644 pch/all create mode 100644 pch/deflt.txt create mode 100644 pch/estack.89y create mode 100644 pch/estack.def create mode 100644 pch/estack.pch create mode 100644 pch/estackle.89y create mode 100644 pch/estackle.def create mode 100644 pch/estackle.pch create mode 100644 pch/events.89y create mode 100644 pch/events.def create mode 100644 pch/events.pch create mode 100644 pch/ext.mk create mode 100644 pch/homescr.89y create mode 100644 pch/homescr.def create mode 100644 pch/homescr.pch create mode 100644 pch/keywords.89y create mode 100644 pch/keywords.def create mode 100644 pch/keywords.pch create mode 100644 pch/script/merge.pl create mode 100644 pch/src/COPYING create mode 100644 pch/src/alloc.pchsource create mode 100644 pch/src/ams2-basfunc.pchsource create mode 100644 pch/src/ams2-basop.pchsource create mode 100644 pch/src/ams2-kbd.pchsource create mode 100644 pch/src/ams2-menus.pchsource create mode 100644 pch/src/args-le.pchsource create mode 100644 pch/src/args.pchsource create mode 100644 pch/src/asmtypes.pchsource create mode 100644 pch/src/assert.pchsource create mode 100644 pch/src/bascmd.pchsource create mode 100644 pch/src/basfunc.pchsource create mode 100644 pch/src/basop.pchsource create mode 100644 pch/src/cert.pchsource create mode 100644 pch/src/compat-x.pchsource create mode 100644 pch/src/compat.pchsource create mode 100644 pch/src/compiler-internals.pchsource create mode 100644 pch/src/ctype.pchsource create mode 100644 pch/src/dialogs.pchsource create mode 100644 pch/src/dll.pchsource create mode 100644 pch/src/error-le.pchsource create mode 100644 pch/src/error.pchsource create mode 100644 pch/src/estack.pchsource create mode 100644 pch/src/estackle.pchsource create mode 100644 pch/src/events.pchsource create mode 100644 pch/src/flash.pchsource create mode 100644 pch/src/float.pchsource create mode 100644 pch/src/gdraw.pchsource create mode 100644 pch/src/graph.pchsource create mode 100644 pch/src/gray.pchsource create mode 100644 pch/src/gtc.pchsource create mode 100644 pch/src/homescr.pchsource create mode 100644 pch/src/intr.pchsource create mode 100644 pch/src/kbd.pchsource create mode 100644 pch/src/keywords.pchsource create mode 100644 pch/src/lex.txt create mode 100644 pch/src/limits.pchsource create mode 100644 pch/src/link.pchsource create mode 100644 pch/src/math.pchsource create mode 100644 pch/src/mem.pchsource create mode 100644 pch/src/menus.pchsource create mode 100644 pch/src/pchlog.pchsource create mode 100644 pch/src/peekpoke.pchsource create mode 100644 pch/src/rsa.pchsource create mode 100644 pch/src/setjmp.pchsource create mode 100644 pch/src/sprites.pchsource create mode 100644 pch/src/statline-vle.pchsource create mode 100644 pch/src/statline.pchsource create mode 100644 pch/src/stdarg.pchsource create mode 100644 pch/src/stdhead-ams2.pchmerge create mode 100644 pch/src/stdhead-light.pchmerge create mode 100644 pch/src/stdhead.pchmerge create mode 100644 pch/src/stdio.pchsource create mode 100644 pch/src/stdlib.pchsource create mode 100644 pch/src/string.pchsource create mode 100644 pch/src/system.pchsource create mode 100644 pch/src/textedit.pchsource create mode 100644 pch/src/tigcc-archive/COMPILING create mode 100644 pch/src/tigcc-archive/License.txt create mode 100644 pch/src/tigcc-archive/addbf.s create mode 100644 pch/src/tigcc-archive/ashldi.s create mode 100644 pch/src/tigcc-archive/ashrdi.s create mode 100644 pch/src/tigcc-archive/assert.s create mode 100644 pch/src/tigcc-archive/atexit.s create mode 100644 pch/src/tigcc-archive/atof.s create mode 100644 pch/src/tigcc-archive/atoi.c create mode 100644 pch/src/tigcc-archive/atol.c create mode 100644 pch/src/tigcc-archive/bc.s create mode 100644 pch/src/tigcc-archive/bcopy.s create mode 100644 pch/src/tigcc-archive/bsearch.c create mode 100644 pch/src/tigcc-archive/bzero.s create mode 100644 pch/src/tigcc-archive/calloc.s create mode 100644 pch/src/tigcc-archive/calloc_throw.s create mode 100644 pch/src/tigcc-archive/clrscr.s create mode 100644 pch/src/tigcc-archive/cmpbf.s create mode 100644 pch/src/tigcc-archive/contrastdn.s create mode 100644 pch/src/tigcc-archive/contrastup.s create mode 100644 pch/src/tigcc-archive/divbf.s create mode 100644 pch/src/tigcc-archive/divdi.s create mode 100644 pch/src/tigcc-archive/diventry.s create mode 100644 pch/src/tigcc-archive/divsi.s create mode 100644 pch/src/tigcc-archive/dll.c create mode 100644 pch/src/tigcc-archive/dummyhandler.s create mode 100644 pch/src/tigcc-archive/enter_ghost_space.s create mode 100644 pch/src/tigcc-archive/exit.s create mode 100644 pch/src/tigcc-archive/fclose.c create mode 100644 pch/src/tigcc-archive/fgetc.c create mode 100644 pch/src/tigcc-archive/fgets.c create mode 100644 pch/src/tigcc-archive/fixbf.s create mode 100644 pch/src/tigcc-archive/floatbf.s create mode 100644 pch/src/tigcc-archive/fopen.c create mode 100644 pch/src/tigcc-archive/fpcall.s create mode 100644 pch/src/tigcc-archive/fpentry.s create mode 100644 pch/src/tigcc-archive/fprintf.s create mode 100644 pch/src/tigcc-archive/fputc.c create mode 100644 pch/src/tigcc-archive/fputchar.s create mode 100644 pch/src/tigcc-archive/fputs.s create mode 100644 pch/src/tigcc-archive/fread.c create mode 100644 pch/src/tigcc-archive/freetimer.s create mode 100644 pch/src/tigcc-archive/fseek.c create mode 100644 pch/src/tigcc-archive/fsetbufsize.c create mode 100644 pch/src/tigcc-archive/ftell.c create mode 100644 pch/src/tigcc-archive/fwrite.c create mode 100644 pch/src/tigcc-archive/getappid.s create mode 100644 pch/src/tigcc-archive/gray.s create mode 100644 pch/src/tigcc-archive/grayversion.c create mode 100644 pch/src/tigcc-archive/homestore.s create mode 100644 pch/src/tigcc-archive/homestorepair.c create mode 100644 pch/src/tigcc-archive/hrealloc_throw.s create mode 100644 pch/src/tigcc-archive/isextalnum.s create mode 100644 pch/src/tigcc-archive/isextpunct.s create mode 100644 pch/src/tigcc-archive/kbd_queue.s create mode 100644 pch/src/tigcc-archive/loaddll_throw.s create mode 100644 pch/src/tigcc-archive/lshrdi.s create mode 100644 pch/src/tigcc-archive/malloc_throw.s create mode 100644 pch/src/tigcc-archive/moddi.s create mode 100644 pch/src/tigcc-archive/modsi.s create mode 100644 pch/src/tigcc-archive/mulbf.s create mode 100644 pch/src/tigcc-archive/muldi.s create mode 100644 pch/src/tigcc-archive/mulsi.s create mode 100644 pch/src/tigcc-archive/negbf.s create mode 100644 pch/src/tigcc-archive/nocallback.s create mode 100644 pch/src/tigcc-archive/printf.s create mode 100644 pch/src/tigcc-archive/push_longint.s create mode 100644 pch/src/tigcc-archive/push_longlongint.s create mode 100644 pch/src/tigcc-archive/push_shortint.s create mode 100644 pch/src/tigcc-archive/pushfifonode.c create mode 100644 pch/src/tigcc-archive/puts.s create mode 100644 pch/src/tigcc-archive/qsort.c create mode 100644 pch/src/tigcc-archive/rand.s create mode 100644 pch/src/tigcc-archive/realloc.s create mode 100644 pch/src/tigcc-archive/realloc_throw.s create mode 100644 pch/src/tigcc-archive/registertimer.s create mode 100644 pch/src/tigcc-archive/rename.c create mode 100644 pch/src/tigcc-archive/rowread.s create mode 100644 pch/src/tigcc-archive/sprite16.c create mode 100644 pch/src/tigcc-archive/sprite32.c create mode 100644 pch/src/tigcc-archive/sprite8.c create mode 100644 pch/src/tigcc-archive/strputchar.s create mode 100644 pch/src/tigcc-archive/strtol.c create mode 100644 pch/src/tigcc-archive/strtoul.c create mode 100644 pch/src/tigcc-archive/subbf.s create mode 100644 pch/src/tigcc-archive/tigcc.tpr create mode 100644 pch/src/tigcc-archive/tmpnam.c create mode 100644 pch/src/tigcc-archive/udivdi.s create mode 100644 pch/src/tigcc-archive/udivsi.s create mode 100644 pch/src/tigcc-archive/umoddi.s create mode 100644 pch/src/tigcc-archive/umodsi.s create mode 100644 pch/src/tigcc-archive/unlink.c create mode 100644 pch/src/timath.pchsource create mode 100644 pch/src/tiosdlg-merge.pchmerge create mode 100644 pch/src/values.pchsource create mode 100644 pch/src/vat-le.pchsource create mode 100644 pch/src/vat.pchsource create mode 100644 pch/src/version.pchsource create mode 100644 pch/src/wingraph.pchsource create mode 100644 pch/srcdata/C-loseF-ile.ref create mode 100644 pch/srcdata/CI1.ext create mode 100644 pch/srcdata/CI2.ext create mode 100644 pch/srcdata/CI3.ext create mode 100644 pch/srcdata/O-penF-ile.ref create mode 100644 pch/srcdata/OpenFile.ext create mode 100644 pch/srcdata/__mulsi3_rp.ref create mode 100644 pch/srcdata/__mulsi3si2_rp.ref create mode 100644 pch/srcdata/__mulsi3ui2_rp.ref create mode 100644 pch/srcdata/export.dat create mode 100644 pch/srcdata/tigcc.a create mode 100644 pch/stdhead.89y create mode 100644 pch/stdhead.def create mode 100644 pch/stdhead.pch create mode 100644 pch/subprojects/xupaki.pch create mode 100644 pch/subprojects/xupaki/Unpack2.o create mode 100644 pch/subprojects/xupaki/a2ext/U-npack.ref create mode 100644 pch/subprojects/xupaki/a2ext/Unpack2.ext create mode 100644 pch/subprojects/xupaki/a2ext/Unpack2.o create mode 100644 pch/subprojects/xupaki/a2ext/deflt.txt create mode 100644 pch/subprojects/xupaki/a2ext/export.dat create mode 100644 pch/subprojects/xupaki/export.dat create mode 100644 pch/subprojects/xupaki/xupaki.pchsource create mode 100644 pch/tiosdlg.89y create mode 100644 pch/tiosdlg.def create mode 100644 pch/tiosdlg.pch create mode 100644 pch/wingraph.89y create mode 100644 pch/wingraph.def create mode 100644 pch/wingraph.pch create mode 100644 pch/xupaki.89y create mode 100644 pch/xupaki.pch create mode 100644 platform.mk create mode 100644 readme.html create mode 100644 ti68k/Makefile create mode 100644 ti68k/bin-89/assert.89t create mode 100644 ti68k/bin-89/compat.89t create mode 100644 ti68k/bin-89/default.89t create mode 100644 ti68k/bin-89/doors.89t create mode 100644 ti68k/bin-89/estack.89y create mode 100644 ti68k/bin-89/estackle.89y create mode 100644 ti68k/bin-89/events.89y create mode 100644 ti68k/bin-89/extgraph.89t create mode 100644 ti68k/bin-89/gen.89t create mode 100644 ti68k/bin-89/gtc-ide.89z create mode 100644 ti68k/bin-89/gtc.89k create mode 100644 ti68k/bin-89/homescr.89y create mode 100644 ti68k/bin-89/keywords.89y create mode 100644 ti68k/bin-89/nostub.89t create mode 100644 ti68k/bin-89/patch.89t create mode 100644 ti68k/bin-89/std.89t create mode 100644 ti68k/bin-89/stdhead.89y create mode 100644 ti68k/bin-89/tigcclib.89t create mode 100644 ti68k/bin-89/tiosdlg.89y create mode 100644 ti68k/bin-89/ttunpack.89t create mode 100644 ti68k/bin-89/wingraph.89y create mode 100644 ti68k/bin-89/xupak.89t create mode 100644 ti68k/bin-89/xupaki.89y create mode 100644 ti68k/bin-92p/assert.9xt create mode 100644 ti68k/bin-92p/compat.9xt create mode 100644 ti68k/bin-92p/default.9xt create mode 100644 ti68k/bin-92p/doors.9xt create mode 100644 ti68k/bin-92p/estack.9xy create mode 100644 ti68k/bin-92p/estackle.9xy create mode 100644 ti68k/bin-92p/events.9xy create mode 100644 ti68k/bin-92p/extgraph.9xt create mode 100644 ti68k/bin-92p/gen.9xt create mode 100644 ti68k/bin-92p/gtc-ide.9xz create mode 100644 ti68k/bin-92p/gtc.9xk create mode 100644 ti68k/bin-92p/homescr.9xy create mode 100644 ti68k/bin-92p/keywords.9xy create mode 100644 ti68k/bin-92p/nostub.9xt create mode 100644 ti68k/bin-92p/patch.9xt create mode 100644 ti68k/bin-92p/std.9xt create mode 100644 ti68k/bin-92p/stdhead.9xy create mode 100644 ti68k/bin-92p/tigcclib.9xt create mode 100644 ti68k/bin-92p/tiosdlg.9xy create mode 100644 ti68k/bin-92p/ttunpack.9xt create mode 100644 ti68k/bin-92p/wingraph.9xy create mode 100644 ti68k/bin-92p/xupak.9xt create mode 100644 ti68k/bin-92p/xupaki.9xy create mode 100644 ti68k/bin-v200/assert.v2t create mode 100644 ti68k/bin-v200/compat.v2t create mode 100644 ti68k/bin-v200/default.v2t create mode 100644 ti68k/bin-v200/doors.v2t create mode 100644 ti68k/bin-v200/estack.v2y create mode 100644 ti68k/bin-v200/estackle.v2y create mode 100644 ti68k/bin-v200/events.v2y create mode 100644 ti68k/bin-v200/extgraph.v2t create mode 100644 ti68k/bin-v200/gen.v2t create mode 100644 ti68k/bin-v200/gtc-ide.v2z create mode 100644 ti68k/bin-v200/gtc.v2k create mode 100644 ti68k/bin-v200/homescr.v2y create mode 100644 ti68k/bin-v200/keywords.v2y create mode 100644 ti68k/bin-v200/nostub.v2t create mode 100644 ti68k/bin-v200/patch.v2t create mode 100644 ti68k/bin-v200/std.v2t create mode 100644 ti68k/bin-v200/stdhead.v2y create mode 100644 ti68k/bin-v200/tigcclib.v2t create mode 100644 ti68k/bin-v200/tiosdlg.v2y create mode 100644 ti68k/bin-v200/ttunpack.v2t create mode 100644 ti68k/bin-v200/wingraph.v2y create mode 100644 ti68k/bin-v200/xupak.v2t create mode 100644 ti68k/bin-v200/xupaki.v2y create mode 100644 ti68k/ide/Makefile create mode 100644 ti68k/ide/autoint_fix.h create mode 100644 ti68k/ide/axplore.h create mode 100644 ti68k/ide/bin/gtc-ide.89z create mode 100644 ti68k/ide/bin/gtc-ide.9xz create mode 100644 ti68k/ide/bin/gtc-ide.v2z create mode 100644 ti68k/ide/dialogs.h create mode 100644 ti68k/ide/display.h create mode 100644 ti68k/ide/edit.h create mode 100644 ti68k/ide/editor.h create mode 100644 ti68k/ide/editui.h create mode 100644 ti68k/ide/files.h create mode 100644 ti68k/ide/font.bin create mode 100644 ti68k/ide/font.h create mode 100644 ti68k/ide/gtdev-apphdr.h create mode 100644 ti68k/ide/gtdev-plugins.h create mode 100644 ti68k/ide/gtdev-securecomm.h create mode 100644 ti68k/ide/handlers.h create mode 100644 ti68k/ide/limits.h create mode 100644 ti68k/ide/main.c create mode 100644 ti68k/ide/pchutil.h create mode 100644 ti68k/ide/plugins.h create mode 100644 ti68k/ide/sunpack.c create mode 100644 ti68k/ide/tags create mode 100644 ti68k/ide/textedit.h create mode 100644 ti68k/ide/util.h create mode 100644 ti68k/ide/workspace.h create mode 100644 ti68k/mkinfo-89-flashapp create mode 100644 ti68k/mkinfo-89-h create mode 100644 ti68k/mkinfo-89-ide create mode 100644 ti68k/mkinfo-89-pch create mode 100644 ti68k/mkinfo-92p-flashapp create mode 100644 ti68k/mkinfo-92p-h create mode 100644 ti68k/mkinfo-92p-ide create mode 100644 ti68k/mkinfo-92p-pch create mode 100644 ti68k/mkinfo-v200-flashapp create mode 100644 ti68k/mkinfo-v200-h create mode 100644 ti68k/mkinfo-v200-ide create mode 100644 ti68k/mkinfo-v200-pch create mode 100644 ti68k/srcdata/flashapp/gtc-89.89k create mode 100644 ti68k/srcdata/flashapp/gtc-92p.9xk create mode 100644 tools/Makefile create mode 100644 tools/dat89y/Makefile create mode 100644 tools/dat89y/bin2calc.c create mode 100644 tools/dat89y/dat89y.c create mode 100644 tools/obj2ti/Makefile create mode 100644 tools/obj2ti/m68kdefs.h create mode 100644 tools/obj2ti/obj2ti.cpp create mode 100644 tools/obj2ti/obj2ti.h create mode 100644 tools/obj2ti/str.h create mode 100644 tools/obj2ti/stubs.h create mode 100644 tools/pchmaker/Makefile create mode 100644 tools/pchmaker/pchmaker.c create mode 100644 tools/pchmaker/spack.c create mode 100644 tools/txt89t/Makefile create mode 100644 tools/txt89t/bin2calc.c create mode 100644 tools/txt89t/txt89t.c diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..25dee30 --- /dev/null +++ b/INSTALL @@ -0,0 +1,3 @@ +Quick install: type "./configure && make -j && sudo make install". + +More information is available in "doc/building.html". diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1910ab5 --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +SUBSYSTEMS = tools bin h pch gtc ti68k +INSTALLABLE_SUBSYSTEMS = h pch gtc +all: $(addprefix all-,$(SUBSYSTEMS)) + @echo 1>&2 + @echo 1>&2 '-- Compilation successful!' + @echo 1>&2 ' You may use the calculator binaries now (e.g. for the TI-89 in ti68k/bin-89).' + @echo 1>&2 ' Or if you want to go ahead and install the cross-compiler, just type "make install".' + @echo 1>&2 +install: $(addprefix all-,$(SUBSYSTEMS)) $(addprefix install-,$(INSTALLABLE_SUBSYSTEMS)) + @echo 1>&2 + @echo 1>&2 '-- Cross-compiler install successful!' + @echo 1>&2 ' You should now be able to compile by typing "gtc myprogram.c".' + @echo 1>&2 ' Remember that the calculator binaries are available, e.g. for the TI-89 in ti68k/bin-89.' + @echo 1>&2 +clean: $(addprefix clean-,$(SUBSYSTEMS)) +distclean: $(addprefix distclean-,$(SUBSYSTEMS)) +scratchclean: $(addprefix scratchclean-,$(SUBSYSTEMS)) +distclean scratchclean: + $(RM) config.mk + +all-bin: all-tools +all-h: all-bin +all-pch: all-bin +all-gtc: all-bin +all-ti68k: all-bin all-h all-pch +$(addprefix install-,$(INSTALLABLE_SUBSYSTEMS)): $(addprefix all-,$(INSTALLABLE_SUBSYSTEMS)) + +all-%: + $(MAKE) -C $(patsubst all-%,%,$@) all +install-%: + $(MAKE) -C $(patsubst install-%,%,$@) install +clean-%: + $(MAKE) -C $(patsubst clean-%,%,$@) clean +distclean-%: + $(MAKE) -C $(patsubst distclean-%,%,$@) distclean +scratchclean-%: + $(MAKE) -C $(patsubst scratchclean-%,%,$@) scratchclean diff --git a/bin/Makefile b/bin/Makefile new file mode 100644 index 0000000..9591cd1 --- /dev/null +++ b/bin/Makefile @@ -0,0 +1,20 @@ +include ../platform.mk +vpath ../tools + +PROGRAMS = obj2ti$(BIN_SUFFIX) pchmaker$(BIN_SUFFIX) txt89t$(BIN_SUFFIX) dat89y$(BIN_SUFFIX) + +all: $(PROGRAMS) + +clean: +distclean: + $(RM) $(PROGRAMS) +scratchclean: distclean + +obj2ti$(BIN_SUFFIX): ../tools/obj2ti/obj2ti$(BIN_SUFFIX) + cp $< $@ +pchmaker$(BIN_SUFFIX): ../tools/pchmaker/pchmaker$(BIN_SUFFIX) + cp $< $@ +txt89t$(BIN_SUFFIX): ../tools/txt89t/txt89t$(BIN_SUFFIX) + cp $< $@ +dat89y$(BIN_SUFFIX): ../tools/dat89y/dat89y$(BIN_SUFFIX) + cp $< $@ diff --git a/common-gtc.mk b/common-gtc.mk new file mode 100644 index 0000000..9b66d1a --- /dev/null +++ b/common-gtc.mk @@ -0,0 +1,13 @@ +# This Makefile is used for source codes that depend on the GTC code tree. +# It is expected that the current working directory is of the form src/xxx/yyy. +# +# Note that GTC itself may need more C defines to be compiled, but they will +# only be required in .c files, not .h files, so they are not defined here. + +include ../../common.mk +include ../../config.mk + +GTC_SOURCE = ../../gtc/src +GTC_HEADERS = $(GTC_SOURCE)/*.h + +CFLAGS = $(DEFAULT_CFLAGS) -I$(GTC_SOURCE) $(GTC_ARCH_DEFINES) diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..1b306bf --- /dev/null +++ b/common.mk @@ -0,0 +1,11 @@ +# This Makefile is used for all source codes that must build binaries. + +DEFAULT_CFLAGS = -O2 -s + +ifndef CC +ifeq (,$(shell which gcc 2>&1 >/dev/null)) +CC=gcc +else +CC=cc +endif +endif diff --git a/configure b/configure new file mode 100755 index 0000000..3fb1d11 --- /dev/null +++ b/configure @@ -0,0 +1,20 @@ +#!/bin/sh +rm -f config.mk +touch config.mk +if [ "x$1" = "x--prefix" ]; then + if test -z "$2"; then + echo "missing argument to $1" 1>&2; exit 1 + fi + echo "using prefix $2..." + echo "prefix=$2" >> config.mk + shift 2 +else + deflt_prefix=/usr/local + echo "using default prefix $deflt_prefix..." + echo "prefix=$deflt_prefix" >> config.mk +fi +if test "$1"; then + echo "error: too many arguments" 1>&2; exit 1 +fi +echo "GTC_ARCH_DEFINES = -DNDEBUG -DMC68000 -DCPU_DEFINED -DPC -DUNIXOID -DAS -DASM -DPCH -DREGPARM -DBCDFLT -DNOFLOAT -DVCG" >> config.mk +echo configuration OK ! 1>&2 diff --git a/doc/building.html b/doc/building.html new file mode 100644 index 0000000..ac7af9e --- /dev/null +++ b/doc/building.html @@ -0,0 +1,55 @@ + + + + Building GTC - GTC documentation + + + + +

◄ Back to index

+
+

Building GTC

+

If you use Windows or TI calculators you don't need to build GTC yourself as +there are already precompiled versions available.

+

If you use Unix-like operating systems (Linux, Mac OS X...) you will have to +follow these instructions to build GTC yourself.

+ +
+

Building the binaries


+

You should need no special package apart from GNU make and a C/C++ compiler to +build GTC. On Windows you will need Cygwin.

+

Just type

+

./configure && make && sudo make install

+

(replace make with make -j to take advantage of multiprocessor systems).

+

By default GTC will be installed in /usr/local. If you want to install it in +a different directory (for example if you don't have administrator rights), use +the following command:

+

./configure --prefix $HOME/my_directory && make install

+
+
+

Rebuilding a modified GTC


+

The above instructions are designed to only recompile platform-dependent files +and as such have minimal dependencies.

+

If you want to modify precompiled data such as the precompiled headers you will +need extra packages like Perl and possibly Ruby.

+
+
+

Notes for developers


+

The Makefiles follow these conventions:

+
  • make clean cleans up intermediary files, but not final files. +
  • make distclean cleans up intermediary files and any platform-dependent + files. +
  • make scratchclean cleans up everything that can be rebuilt. Note: use + with care, as if you don't have the right tools installed you are not going + to be able to rebuild GTC. +
+

All Makefiles are designed to be safely used with parallel compilation. +

+ + diff --git a/doc/cmdline.html b/doc/cmdline.html new file mode 100644 index 0000000..28e8859 --- /dev/null +++ b/doc/cmdline.html @@ -0,0 +1,118 @@ + + + + GTC Command-line options - GTC documentation + + + + +

◄ Back to index

+
+

GTC Command-line options

+

The computer version of GTC has a number of options available on the command-line. They are all listed here.

+

Please note that currently, these options are not available for the FlashApp version.

+ +
+

Basic usage


+

Invocation


+

To compile a file named hello.c, open a command-line prompt in the folder where hello.c is stored, and type:

+
+gtc hello.c
+
+

This will create files named hello.89z, hello.9xz and hello.v2z (or only some of those, if your program is specific to a calculator model). You can now run them after sending them to your calculator or to an emulator.

+
+
+

Adding options


+

You can modify the behaviour of GTC with command-line options (or command-line switches). Their position on the command-line does not matter. For example, if you want to use the -o switch to create files named somename.89z, somename.9xz and somename.v2z, you can type:

+
+gtc hello.c -o somename
+
+

Or, equivalently:

+
+gtc -o somename hello.c
+
+

See below for a complete list of options.

+
+
+
+

List of all options


+

Options affecting output


+

-o switch


+

By default, gtc hello.c foo.c bar.c results in an executable named hello.89z or hello.v2z. You can specify other names with this switch, for example gtc hello.c foo.c bar.c -o somename will instead create an executable named somename.89z or somename.v2z.

+
+
+

--folder switch


+

By default, calculator executables are stored in the main folder. You can store them in the folder somefold with the switch --folder=somefold.

+
+
+

--output switch


+

By default, gtc hello.c -o somename results in an executable named somename.89z; the name of the program on the calculator will thus be somename(). You can change this with the switch --output=myprog: gtc hello.c -o somename --output=myprog creates an executable named somename.89z containing a program whose name on the calculator will be myprog().

+
+
+
+

Preprocessor options


+

-I switch


+

The -I folder (or -Ifolder) switch tells GTC to look for include files not only in the current directory, but also in the folder folder. +You can use this switch several times to include several folders.

+
+
+

-D switch


+

The -D SYMBOL (or -DSYMBOL) switch tells GTC to #define the symbol SYMBOL, with no specific value. +The -D SYMBOL=value (or -DSYMBOL=value) switch tells GTC to #define the symbol SYMBOL, with the value value. +You can use this switch several times to define several symbols.

+
+
+
+

Optimization options


+

It is in the philosophy of GTC to have default options as sensible as possible, so optimization options are kept to a bare minimum. Furthermore, optimizations are always enabled.

+
+

-exe switch


+

This switch will make your program much smaller and very slightly faster, at the expense of a short loading time (usually less than half a second). However note that because it adds an unpacker to your program, it will make very small programs (less than 3-4 kilobytes) larger, so it should not be used in this case. It has the same effect as defining the EXE_OUT preprocessor symbol.

+

It can be an interesting way to work around AMS's program size limit for AMS version 2.0x, because a program that exceeds the size limit when uncompressed can be compressed to a size below the limit.

+
+
+

-mno-bss switch


+

This switch disables the creation of BSS sections. In some cases it has absolutely no effect, in other cases it will either make the program faster and smaller, or make it much larger (if you are using large global arrays).

+
+
+
+

Other options


+

-- separator


+

Not an option per se, but a way to indicate that all arguments after -- are really filenames and not command-line switches. +For example gtc -DHELLO hello.c -- foo.c -file-with-dashes-.c will compile the 3 files hello.c, foo.c and -file-with-dashes-.c, with the single option -DHELLO. Without -- the file -file-with-dashes-.c would have been understood as an (invalid) command-line option. +

+
+

+ + diff --git a/doc/credits.html b/doc/credits.html new file mode 100644 index 0000000..28063e2 --- /dev/null +++ b/doc/credits.html @@ -0,0 +1,83 @@ + + + + Information - GTC documentation + + + + +

◄ Back to index

+
+

Information

+ +
+

Credits and licensing


+

GTC is composed of three separate parts: the GTC compiler, the GTC IDE and the +GTC standard library. You are free to use these parts separately or in +combination.

+

You can redistribute or modify GTC freely for non-commercial use, as long as +you also redistribute the modified source and comply with the licenses of the +components you choose to distribute: you cannot redistribute the GTC standard +library if you fail to comply with the terms of the GNU General Public +License, version 2 (GPL). In addition you may redistribute the GTC standard +library under the terms of the GPL license, without restriction on commercial +use.

+

Excluding the standard library, the main author of GTC is Paul Froissart, +however GTC would not have been possible without building upon the work of +the following contributors.

+
+

Standard library


+

The GTC standard library is a simple recompilation of old versions of the TIGCC +library, adapted for usage of a different calling convention. As such it is +licensed under the terms of the GNU General Public License, with an +exception allowing linking of the library with external programs, and +redistribution of the linked programs notwithstanding the provisions of the +GPL.

+

The TIGCC library was written by Zeljko Juric, Thomas Nussbaumer, Sebastian +Reichelt, Kevin Kofler and other contributors to the + TIGCC project.

+
+
+

Compiler core


+

The GTC compiler is based on the 68000 and i386 C compiler III.1 by Christoph +van Wuellen (1989-1991), itself based on the 68000 compiler by Matthew Brandt +(1984-1986).

+
+
+

Compression routines


+

The -exe mode is based on the PuCrunch algorithm written by Pasi Albert Ojala, and adapted for use on TI calculators by Thomas Nussbaumer.

+
+
+

Object file import


+

The code to import .o files is based on obj2ti written by Julien Muchembled and further modified by Sebastian Reichelt and Kevin Kofler.

+
+
+

Thanks


+

Some people provided significant help without contributing code to the project.

+

Thanks to Olivier Armand for his FlashAppy patch: since TI has stopped signing +Flash applications this is absolutely vital to GTC.

+

Thanks to vince from the Ti-Fr team for his generous hosting.

+

Thanks to all the testers who helped uncover bugs.

+
+
+
+

Contact


+

You will find the latest versions and online documentation on the GTC website:

+

http://gtc.ti-fr.com/

+

Please use the feedback form to submit bugs or +comments. +

+ + diff --git a/doc/examples.html b/doc/examples.html new file mode 100644 index 0000000..e74da44 --- /dev/null +++ b/doc/examples.html @@ -0,0 +1,14 @@ + + + + GTC examples - GTC documentation + + + + +

◄ Back to index

+
+

GTC examples

+

You will find

+ + diff --git a/doc/extensions.html b/doc/extensions.html new file mode 100644 index 0000000..9c9e4ec --- /dev/null +++ b/doc/extensions.html @@ -0,0 +1,352 @@ + + + + GTC Extensions - GTC documentation + + + + +

◄ Back to index

+
+

GTC Extensions

+

GTC supports a number of extensions, designed to take advantage of the TI platform, or simply to maintain compatibility with existing programs.

+ +
+

GNU extensions


+

Statements and Declarations in Expressions

+
+

Referring to a Type with typeof

+
+

Generalized Lvalues


+

See Generalized Lvalues.

+

Note however that weird constructs like (a,b)+=5 are rejected by GTC -- commas are not considered legal lvalues.

+
+
+

Conditionals with Omitted Operands

+
+

Binary Numbers

+
+

Structures With No Members

+
+

Arrays of Length Zero

+
+

Macros with a Variable Number of Arguments

+
+

Arithmetic on void and Function Pointers

+
+

Non-Constant Initializers

+
+

Compound Literals (Cast Constructors)


+

See Compound Literals (Cast Constructors). There is some difference in the handling of static storage duration though, see Differences between GTC and TIGCC.

+
+
+

Designated Initializers


+

See Designated Initializers, but in GTC this only works for array types.

+
+
+

Case Ranges


+

See Case Ranges.

+
+
+

Specifying Attributes of Functions


+

See Specifying Attributes of Functions, however not all of the specifiers are meaningful in GTC.

+
+
+

C++ Style Comments

+
+

Dollar Signs in Identifier Names

+
+

Escape Character in Constants

+
+

Alternate Keywords

+ +
+

Mixed Declarations and Code

+
+

Unnamed struct/union Fields within structs/unions

+
+
+

GTC-specific extensions


+

incbin directive


+

It is sometimes convenient to include binary files directly into your program, for example when using sprites. The incbin directives allows you to do just that, without having to convert your data to a decimal or hexadecimal header (which can be memory-consuming on a TI).

+
+

Using incbin to declare a C array


+

You can use incbin to initialize the contents of a C array:

+
+// The following declares a sprite using normal C initializers
+short sprite1[] = {
+    0xFFFF, 0x8008, 0x8008, 0xFFFF,
+    0xFF00, 0x8800, 0x8800, 0x8800,
+    0x00FF, 0x0088, 0x0088, 0x0088,
+    0xFFFF, 0x8008, 0x8008, 0xFFFF,
+};
+
+// The following declares a sprite using incbin,
+// reading the contents from the file sprite.bin
+short sprite2[] = incbin "sprite.bin";
+
+

The first declaration creates an array of 16 shorts containing the hexadecimal numbers provided. +The second declaration creates an array of 16 shorts whose representation in memory will be the same as sprite.bin.

+

Note that for the sake of portability, import_binary can be a useful +alternative, although there are several caveats: you will have to manually +declare the size of the array if sizeof is to be used, and you cannot use it +to declare a static array inside a function.

+
+
+

Using incbin within an asm{} statement


+

Like in a68k, you can also use incbin inside an asm{} statement to insert binary data.

+
+asm {
+// Insert the values 1,2,3,4 after label1
+label1:
+    dc.w 1,2
+    dc.w 3,4
+// Insert the content of sprite.bin after label2
+label2:
+    incbin "sprite.bin"
+};
+
+
+
+

asm{} statement


+

GTC allows you to program in assembly, with a syntax very close to that of a68k. In fact, it is powerful enough to write full assembly programs using only GTC!

+
+

Inserting an asm{} statement in the code


+

Global asm{} statements


+

You can insert assembly code at the global level, for example:

+
+asm {
+add_3_and_multiply_by_5:
+    add.w #3,d0
+    mulu #5,d0
+    rts
+};
+
+

This creates an assembly function named add_3_and_multiply_by_5 that takes an input argument in d0, adds 3 to it, multiplies it by 5, and returns the result in d0.

+

To use such a function in C code, you need to prototype it:

+
+short add_3_and_multiply_by_5(short x);
+
+

This tells GTC that your function takes a short named x as an input, and outputs a short. Because of the calling convention, x will be placed in d0: see default calling convention for more information on where input arguments to assembly functions will be located.

+
+
+

Inline asm{} statements


+

You can also insert assembly code within a function. This has the advantage over global assembly functions to eliminate the overhead associated with a function call.

+
+void do_something(char *command) {
+    if (!strcmp(command,"off"))
+	asm { trap #4 };
+    else
+	printf("unknown command!\n");
+}
+
+

This functions turns off the calculator when command is "off", by calling trap #4.

+
+
+
+

Structure of an asm{} statement


+

An asm{} statement is comprised of a set of declarations between the outer { and } braces. +A declaration can be:

+
  • a 68000 instruction, e.g. moveq #123,d0
  • a label definition, e.g. my_function:
  • a data declaration, e.g. dc.w 123,456,789 or incbin "data.bin"
+

You must separate different declarations either:

+
  • by putting them on separate lines +
  • by simply concatenating them if the first is a label +
  • by separating them with a semicolon (;) -- however you should absolutely avoid doing this outside #define, as the behaviour may change some day +
+
+

asm{} interpretation rules


+

The behaviour of GTC is indeed very close to that of a68k. Like a68k, GTC tries to optimize instructions when it is possible, for example add.w #3,d0 will be optimized to addq.w #3,d0. Like a68k, you don't need to add a : after label names: however, while with a68k you can only do so if the label is placed on the first char of the line, with GTC you can do so any time as long as the label does not correspond to an assembly instruction.

+

The most notable difference is perhaps that, where a68k uses specific commands like equ and equr to define macros, GTC simply uses the C preprocessor. This is very powerful, as it allows you to define constants just once and reuse them in C code. You can also use normal C conditionals like #if or #ifdef, making conditional compilation easier. +You can also interface your code with C much more easily, for example you have access to the sizeof operator:

+
+int table[] = { 1,2,3,4 };
+
+asm {
+negate_table:
+    lea table,a0
+    moveq #sizeof(table)/2-1,d0
+\loop
+    neg.w (a0)+
+    dbra d0,\loop
+    rts
+};
+
+

After execution of negate_table, table will be equal to { -1,-2,-3,-4 }.

+

Note the \ in \loop: this means that the label is local. However, this notion differs slightly from that of a68k: while the label is only valid between the surrounding two global labels in a68k, the label is valid throughout the asm{} statement in GTC. It is often more convenient, as this example shows:

+
+asm {
+\return_with_error
+    moveq #-1,d0
+    rts
+my_function:
+    addq.w #5,d0
+    bmi.s \return_with_error
+    tst.w d1
+    bmi.s \return_with_error
+    ... very long code (longer than 128 bytes) ...
+    rts
+};
+
+

In this example, \return_with_error is placed before my_function because it allows the branches to \return_with_error to be short branches (bmi.s, 2 bytes) rather than long branches (bmi.w, 4 bytes). If GTC followed the rules of a68k, then it would require \return_with_error to be a global, which can be inconvenient if you have lots of these. Instead, it allows you to structurally divide your program in logical asm{} blocks.

+
+
+

Extra features of asm{} statements


+

Because asm{} statements rely on the C compiler architecture of GTC, there are lots of nice features, for example:

+
+#define USE_KERNEL
+#include <std.h>
+asm {
+_main:
+    pea "Hello, world!"(pc)
+    jsr ST_helpMsg
+    addq.l #4,a7
+    rts
+};
+
+

What's most interesting in all this is that the C library required no modification whatsoever to allow using ROM calls in such a way: ROM calls are not defined twice, and there isn't even a conditional statement acting differently inside asm{} code and inside C code! +This is possible because the assembler was able to interpret the C construct corresponding to ST_helpMsg.

+
+
+

asm{} special operator: __c__


+

This is an operator reserved to operands of instructions in asm{} statements.

+

The reason why this operator exists is simple: assembly and C each have different arithmetic rules. For example, if you have the following code:

+
+int table[] = { 1,2,3,4 };
+
+

then, while in C table+2 will designate the address of table[2] (the number 3), in assembly table+2 will designate the address of table[0] plus 2 bytes, which happens to be the address of table[1].

+

So when you write:

+
+asm {
+load_address:
+    lea table+2(pc),a0
+    rts
+};
+
+

then, as you would expect from assembly code, table+2 corresponds to the address given by assembly arithmetic rules.

+

This works with #define statements too:

+
+asm {
+load_address:
+#define my_item table+2
+    lea my_item(pc),a0
+    rts
+};
+
+

But GTC allows you to do much more: you may want to access information that requires access to the full typing system of C, not just the addresses of different objects. +The way you can access this typing system is by the __c__ operator: if you write

+
+asm {
+load_address:
+    lea __c__(table+2)(pc),a0
+    rts
+};
+
+

then table+2 will not be interpreted according to assembly rules, but according to C rules: that is, __c__(table+2) is the adress of table[2].

+

GTC goes one step further, by automatically enclosing #defines written as part of C code in the __c__ operator:

+
+int table[] = { 1,2,3,4 };
+#define third_item &table[2]  // note: table+2 would give the same results
+
+int *c_load_address() {
+    return third_item;
+}
+
+asm {
+load_address:
+    lea third_item(pc),a0
+    rts
+};
+
+

Here both c_load_address() and load_address() do the same thing, without ever having to define third_item twice!

+
+
+
+

@@ prefix


+

The prefix @@ can be prepended to any identifier to prevent it from being expanded by the preprocessor. +For example, @@MY_SYMBOL will expand to MY_SYMBOL even if MY_SYMBOL has been #defined to expand to 0x1234.

+

This is not very useful in normal C code, but it can be useful in conjunction with other GTC extensions, mainly asm{} statements and pre-compiled headers.

+
+
+ + diff --git a/doc/faq.html b/doc/faq.html new file mode 100644 index 0000000..824bcc1 --- /dev/null +++ b/doc/faq.html @@ -0,0 +1,112 @@ + + + + Frequently Asked Questions - GTC documentation + + + + +

◄ Back to index

+
+

Frequently Asked Questions

+ +
+

Common issues


+

(on-calc) I keep getting errors such as "not enough memory to compile function abc"


+

This could be because you do not have enough free RAM (more than 100kb is recommended), but if you have enough RAM it is probably because the function abc is too large to fit in the memory of the calculator. You will need to split into smaller functions to avoid the error.

+

Another reason could be that you have a #define with a large body, or a very +large number of global declarations. This shouldn't be a problem for most +programs, but if you think you are in this case, you can try to solve it with #undef or by creating a precompiled header.

+
+
+
+

Differences between GTC and TIGCC


+

How can I port my program from TIGCC to GTC?


+

It all depends on what features your program uses. Here is a list of porting issues:

+
  • long long support: GTC does not support them, if you use them you will have to rewrite your code to use two longs instead. In many cases it's very easy to port. +
  • asm() vs asm{}: the assembly syntax is different between GTC and TIGCC. However if you are familiar with a68k you will be able to use GTC's syntax in no time. +
  • float/double support: currently, GTC does not support floats. If your program uses floats, then unless you think you can get rid of them (e.g. if you are only using them for sines and cosines, you can use a pre-computed table instead), you're basically stuck and should definitely continue using TIGCC (unless you're willing to go down to the assembly level). Sorry. +
+

Additionally, you may run into these little behaviour differences:

+
  • Cast constructors: currently, the following code +
    +int *f(int *dest,int x) {
    +    memcpy(dest,(int[4]){x,x+1,x+2},8);
    +    return dest;
    +}
    +
    +is not accepted by GTC because the array constructed is not constant (x is not known at compile time). But you can rewrite it to use a temporary array instead: +
    +int *f(int *dest,int x) {
    +    int temp[4] = {x,x+1,x+2};
    +    memcpy(dest,temp,8);
    +    return dest;
    +}
    +
    +
  • Calling convention: by default, GTC uses the regparm(2,1) convention, while TIGCC uses the stkparm convention. This is only a problem if you have written assembly functions yourself; in this case, you have to specify the calling convention you use in the prototype, e.g.: +
    +asm {
    +upper_8_bits:
    +    move.b 4(a7),d0
    +    rts
    +};
    +char upper_8_bits(long x);
    +
    +would become +
    +asm {
    +upper_8_bits:
    +    move.b 4(a7),d0
    +    rts
    +};
    +char upper_8_bits(long x) __attribute__((stkparm));
    +
    +
+

This list may not be exhaustive, but I will be happy to hear about any problems you might have that are not mentioned in this list.

+
+
+

How can I make sure my GTC program can be compiled with TIGCC too?


+

You should not have much trouble compiling GTC programs with TIGCC as GTC was designed to introduce as few incompatibilities as possible. However, if you use low-level features like assembly you might run into some problems:

+
  • See if your program uses GTC-specific extensions. For example, if you really need to use a short bit of assembly you can use conditional compilation to turn a GTC-only program like this one: +
    +asm {
    +turn_calculator_off:
    +    trap #4
    +    rts
    +};
    +
    +into this more portable program: +
    +#ifdef __GTC__
    +/* assembly code using GTC's asm{} syntax */
    +asm {
    +turn_calculator_off:
    +    trap #4
    +    rts
    +};
    +#else
    +/* assembly code using TIGCC's asm() syntax */
    +asm("
    +turn_calculator_off:
    +    trap #4
    +    rts
    +");
    +#endif
    +
    +
  • The default calling convention is different, so if you define your own assembly functions and call them from C code make sure their prototypes are properly specified with regparm. +
+
+ + diff --git a/doc/glossary.html b/doc/glossary.html new file mode 100644 index 0000000..1c99f5e --- /dev/null +++ b/doc/glossary.html @@ -0,0 +1,51 @@ + + + + Glossary - GTC documentation + + + + +

◄ Back to index

+
+

Glossary

+
+Contents: +
+
+
+
+
+

68000


+

The type of processor included in TI-89 and above calculators.

+
+
+

a68k


+

The traditional (and popular) assembler for TI calculators. It is currently +distributed as part of TIGCC.

+
+
+

AMS


+

AMS (Advanced Mathematics Software) is the operating system of TI calculators. +It is stored in the Flash ROM.

+
+
+

Assembly


+

The native language of the 68000 processor.

+
+
+

TIGCC


+

The largest C compiler available for TI calculators. It's a patched GCC +compiler and for this reason is only available for PC platforms. +

+
+
+

+ + diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..34de7ef --- /dev/null +++ b/doc/index.html @@ -0,0 +1,51 @@ + + + + GTC 0.90.2 - GTC documentation + + + + +
+

GTC 0.90.2

+
+Contents: +
+
+
+

About GTC


+

GTC is a C compiler to create programs for the TI-89/TI-92+/V200 calculators. You can choose to run the compiler either on a computer (cross-compilation) or directly on a TI calculator (on-calc compilation). +You can download GTC here.

+

Warning: the Windows version does not have a graphical interface yet, so +you should only use it if you know how to run programs from the command line.

+

Please note this is preliminary documentation. Some important topics are +missing, and you may find broken links.

+
+
+

Documentation summary


+

General information:

+ +

Getting started:

+ +

General TI programming documentation:

+ +

GTC-specific documentation:

+
+
+ + diff --git a/doc/layout/default.css b/doc/layout/default.css new file mode 100644 index 0000000..27314b2 --- /dev/null +++ b/doc/layout/default.css @@ -0,0 +1 @@ +@import url(simple.css); diff --git a/doc/layout/simple.css b/doc/layout/simple.css new file mode 100644 index 0000000..3598784 --- /dev/null +++ b/doc/layout/simple.css @@ -0,0 +1,89 @@ +body { + background-color: white; + color: black; + font-family: georgia, verdana, sans-serif; + padding-bottom: 2em; + font-size-adjust: 0.5; +} +p { + text-align: justify; + line-height: 130%; +} +pre { + margin-left: 2em; +} +/*.widespace { + margin: 0.1em; +}*/ +a { + color:#0000b0; + text-decoration:none; +} +a:hover { + color:#6060ff; + text-decoration:underline; +} +h1,h2,h3,h4,h5,h6, +h1 a,h2 a,h3 a,h4 a,h5 a,h6 a { + color:#25b; +} +h1 { + margin-top: 1.5em; + margin-bottom: 0; +} +h2 { + margin-top: 1.5em; +} +.hr1in { + height: 1px; + background-color: #999; /* used by FF */ + color: #999; /* used by IE */ + border: 0; +} +.hr1,.hr2,.hr3,.hr4,.hr5,.hr6 { + display: none; +} +.hr0in { + height: 1px; + background-color: #7a7; + border: 0; +} +.hr0in,.hr2in,.hr3in,.hr4in,.hr5in,.hr6in { + display: none; +} +.c0 { + width: 700px; +} +/* +.c0 { + width: 700px; + margin-left: auto; + margin-right: auto; + text-align: center; +} + */ +.c1 { + text-align: left; +} +.toc { + font-size: 95%; + margin-top: 1em; + margin-left: 2em; + padding: 0.2em; + border: 1px dotted black; +} +.toc ul { + /*list-style-type: circle;*/ +} +.toc ul ul ul { + /*list-style-type: ;*/ +} +.toc ul ul ul ul { + display: none; +} +code a { + font-weight: bold; +} +a.invalidlink { + color: #900000; +} diff --git a/doc/license-gpl2.html b/doc/license-gpl2.html new file mode 100644 index 0000000..d728852 --- /dev/null +++ b/doc/license-gpl2.html @@ -0,0 +1,354 @@ + + + + GNU General Public License - GTC documentation + + + + +

◄ Back to index

+
+

GNU General Public License

+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type show c' for details.
+
+The hypothetical commands show w' and show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than show w' and show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
+ + diff --git a/doc/missing.html b/doc/missing.html new file mode 100644 index 0000000..e08c111 --- /dev/null +++ b/doc/missing.html @@ -0,0 +1,14 @@ + + + + Missing entry - GTC documentation + + + + +

◄ Back to index

+
+

Missing entry

+

Sorry, this entry has not been written yet!

+ + diff --git a/doc/oncalc.html b/doc/oncalc.html new file mode 100644 index 0000000..83c7438 --- /dev/null +++ b/doc/oncalc.html @@ -0,0 +1,93 @@ + + + + On-calc usage - GTC documentation + + + + +

◄ Back to index

+
+

On-calc usage

+ +
+

On-calc IDE


+

Installation


+

You must first install FlashAppy on your calculator. Note that like all ROM +patches, you will not be able to send your modified calculator ROM image to +other calculators. Neither the authors of GTC nor the author of FlashAppy can +be held responsible for any damage that could occur during or after this +process. However, we are not aware of any case where a calculator was damaged +by FlashAppy.

+

You only need to install FlashAppy once: you won't need to reinstall it after a +reset or after upgrading to a newer version of GTC. On the other hand if you +install an AMS update you will need to reinstall FlashAppy afterwards.

+

Legal notice: the .89t/.9xt/.v2t and .89y/.9xy/.v2y files in the bin-89/92p/v200 directories are subject to the GNU General Public License, which grants you a number of rights. You may choose not to install them, but this will prevent you from using the TIGCC Library.

+

Once FlashAppy is installed, send all the files in the bin-89, bin-92p or bin-v200 directory (depending on the model) to your calculator, and archive +them all.

+

Check that the GTC flashapp was properly transferred by entering the Var-Link +screen and pressing F7: you should see GTC appear in the list. Otherwise, the +transfer failed: make sure that FlashAppy is installed and that you have enough +Archive memory.

+

To create a test source file, create a directory named source, create an +empty text file inside that directory named hello with the TI text editor, +and archive it with the Var-Link screen.

+

Now you can run the IDE by typing gtc\gtc_ide() and open the file named hello.

+

Type in the following code:

+
+#include <tigcclib.h>
+
+void _main() {
+  ST_helpMsg("Hello world!");
+}
+
+

Now press the F5 key. This should bring up a compilation dialog, which should +close after a few seconds (if not, you may not have installed GTC properly: +make sure FlashAppy is correctly installed, that everything is archived, and +that you have enough RAM).

+

Once the compilation is over you can exit the IDE and run your program by +typing

+
+outbin()
+
+

It should display the text Hello world! in the status line. If it worked, +congratulations! You now have a working C compiler on your calculator.

+
+
+

Key commands


+

Here is a small subset of the key commands supported by GTC IDE:

+
  • CLEAR: indent the cursor by two columns (equivalent to the TAB key on a + PC) +
  • Catalog: lists all functions available in the standard library +
  • F5: compile the current file +
  • 2nd-F3: search for a string in the current file +
  • Diamond-F3: replace a string in the current file +
  • F3: search for the next occurrence of the string +
+

Also, GTC IDE supports keyboard shortcuts that the standard text editor +doesn't: for example, you can press Shift-2nd-Right (press Shift and 2nd, +then press Right while still holding Shift and 2nd) to highlight the text from +the cursor to the end of the line. Likewise you can press Shift-2nd-Down to +highlight a whole screen of text, or Shift-Diamond-Down to select until the +end of the file. These shortcuts come in particularly handy when selecting +large amounts of text.

+
+
+

Tips and tricks


  • You should map main\outbin() to a kbdprgm like kbdprgm9 so that you can + quickly run a freshly compiled program by typing Diamond-9 in the Home + screen. +
  • You can save memory by deleting header files you don't use in the folder zheader. You should not delete stdhead or keywords if you want to + compile programs designed for the TIGCC library. +
+
+ + diff --git a/doc/preprocessor.html b/doc/preprocessor.html new file mode 100644 index 0000000..7da8424 --- /dev/null +++ b/doc/preprocessor.html @@ -0,0 +1,27 @@ + + + + The C preprocessor - GTC documentation + + + + +

◄ Back to index

+
+

The C preprocessor

+
+Contents: +
+
+

Preprocessor directives


+

#define


+

... +

+

+ + diff --git a/doc/specificities.html b/doc/specificities.html new file mode 100644 index 0000000..10d4bb4 --- /dev/null +++ b/doc/specificities.html @@ -0,0 +1,78 @@ + + + + Specificities of GTC - GTC documentation + + + + +

◄ Back to index

+
+

Specificities of GTC

+ +
+

Application binary interface (ABI)


+

Calling convention


+

A calling convention specifies where arguments to a function are placed, and where the function places its return value. +You shouldn't worry about it, unless you are an assembly programmer trying to call assembly functions from C code or vice-versa.

+
+

Default calling convention (regparm)


+

Unless otherwise specified, GTC uses the most efficient calling convention, regparm. +Basically, it consists of placing as many arguments as possible into a small set of registers for maximum efficiency, and when they are all used, place the remaining arguments on the stack, which is less efficient.

+

More precisely, here is the specific algorithm for placing arguments:

+
  • for each argument a, from left to right +
    • if all registers {d0,d1,d2,a0,a1} are already used by other arguments +
      • place a on the stack +
    • else +
      • if there is at least one of {d0,d1,d2} unused and one of {a0,a1} unused +
        • if a's type is a pointer +
          • place a in the next free address register +
        • else +
          • place a in the next free data register +
      • else +
        • if one of {a0,a1} is unused +
          • place a in the next free address register +
        • else +
          • place a in the next free data register +
+

Here is how the placement of an argument is done:

+
  • how to place a in the next free data register: +
    • place a in d0 if it is unused +
    • or if it is used +
      • place a in d1 if it is unused +
      • or if it is used place a in d2
  • how to place a in the next free address register: +
    • place a in a0 if it is unused +
    • or if it is used place a in a1
  • how to place a on the stack: +
+

Here is the algorithm for placing the return value:

+
  • if the return value's type is a pointer +
    • the function should return the value in a0
  • if the return value's type is an integer +
    • the function should return the value in d0
  • if the return value's type is a struct or a union
    • if the structure is 4 bytes long or shorter +
      • the function should return the contents of the structure in d0 (not the address!) +
    • else +
      • the ABI is not specified in this case, you should avoid it +
+

Note that regparm requires the function to have a fixed number of arguments: otherwise, for variable-argument functions, no arguments are placed in registers, and the stkparm convention is used instead.

+

Note that TIGCC uses the same algorithm, as long as you specify the function attribute __attribute__((regparm(2,1))).

+

You can also use a different set of variables than d0-d2/a0-a1 thanks to the regparm function attribute, but it is not recommended.

+
+
+

AMS calling convention (stkparm)


+

The stkparm convention is less efficient, but is useful because it is the one used internally by AMS. It is also much simpler to describe.

+

The arguments are pushed one after the other onto the stack, starting from the rightmost argument. chars and unsigned chars should be widened to an int before being pushed. +

+
+

+ + diff --git a/doc/version.html b/doc/version.html new file mode 100644 index 0000000..d5e4565 --- /dev/null +++ b/doc/version.html @@ -0,0 +1,32 @@ + + + + History - GTC documentation + + + + +

◄ Back to index

+
+

History

+
+Contents: +
+
+

Version history


  • 0.90.2: +
    • fix IDE behaviour when catalog symbol limit is reached +
    • small compiler fixes: +
      • proper error message when converting from union type to another type +
      • reject duplicate member names in struct or union declarations +
  • 0.90.1: first public release +
+
+

To do


  • Implement command-line interface in on-calc version. +
  • Improve the pre-compiled header format to handle the full up-to-date TIGCC library. +
  • Add a true linker. +
+ + diff --git a/doc/windows.html b/doc/windows.html new file mode 100644 index 0000000..1e9fa93 --- /dev/null +++ b/doc/windows.html @@ -0,0 +1,29 @@ + + + + Windows-specific features - GTC documentation + + + + +

◄ Back to index

+
+

Windows-specific features

+

Warning: the Windows version does not have a graphical interface yet, so +you should only use it if you know how to run programs from the command line.

+ +
+

Getting started with the Windows compiler


+

Legal notice: the Include directory is subject to the GNU General Public License, which grants you a number of rights. You may choose not to install it, but it will prevent you from using the TIGCC Library.

+

To install GTC just extract gtc.exe and the Include directory to any +directory. You should add that directory to your Windows path (Control Panel → +System → Advanced → Environment Variables, and modify the PATH variable).

+

Now you can invoke gtc on the command-line, for more information see GTC +Command-line options. +

+ + diff --git a/gtc/Makefile b/gtc/Makefile new file mode 100644 index 0000000..89f870a --- /dev/null +++ b/gtc/Makefile @@ -0,0 +1,96 @@ +VPATH = src + +ifndef DEBUG_FLAG +CCBASEFLAGS=-O2 -Wall -Wno-unused-functions +LDFLAGS=-s +else +CCBASEFLAGS=-g -Wall -Wno-switch -DDEBUGGING +LDFLAGS= +endif +ifdef MINGW32 +ifeq (Cygwin,$(shell uname -o)) +CCBASEFLAGS += -mno-cygwin +LDFLAGS += -mno-cygwin +endif +endif +include ../config.mk +include ../platform.mk +CDEFINES=$(GTC_ARCH_DEFINES) -DINCL_PATH=\"$(prefix)/share/gtc/include\" +CFLAGS=$(CCBASEFLAGS) $(CDEFINES) +SOURCEFILES=$(wildcard src/*.c src/*.h src/gtpack/*) +HEADERS=$(wildcard src/*.h) +OBJFILES=\ + analyze.o \ + bin2calc.o \ + cmain.o \ + decl.o \ + expr.o \ + func.o \ + gen68k.o \ + genffp.o \ + genstmt.o \ + getasm.o \ + getsym.o \ + init.o \ + intexpr.o \ + memmgt.o \ + optimize.o \ + out68k_as.o \ + peep68k.o \ + preproc.o \ + reg68k.o \ + searchkw.o \ + stmt.o \ + sunpack.o \ + symbol.o \ + + +.PHONY: all clean install + +all: gtc + +clean: + $(RM) $(OBJFILES) src/tags +distclean: clean + $(RM) gtc$(BIN_SUFFIX) +scratchclean: distclean + +install: gtc + mkdir -p $(prefix)/bin + install gtc $(prefix)/bin/gtc + +splint: + splint \ + -nestcomment -paramuse -nullassign -initallelements -fullinitblock \ + +charint +boolint -boolops +ptrnegate -shiftnegative \ + -nullret -retvalint -retvalother \ + -noeffect \ + -globstate -mustfreeonly -mustfreefresh -onlytrans -statictrans -observertrans -dependenttrans -temptrans -branchstate \ + $(CDEFINES) $(OBJFILES:%.o=%.c) + # -nestcomment is for '//#define foo bar /* this is a comment */' + # -paramuse is for unused func params + # -nullassign is for 'int x CGLOB;' + # -initallelements is for 'int x[5] CGLOBL;' + # -fullinitblock is for 'TI_SHORT x CGLOBL;' + # +charint is for 'char c = 2+1;' or 'if (c < 2+1)' + # +boolint is for 'int z = (x==y);' + # -boolops is for 'ptr && x' + # +ptrnegate is for '!ptr' + # -shiftnegative is for '1 << my_int' where 'my_int' has no known range + # -noeffect is for '(void)0' + # -nullret is for 'return NULL;' without '/*@null@*/' annotation + # -retvalint is for 'myfunc(x);' without subsequent cast to void + # -retvalother is for 'myfunc(x);' without subsequent cast to void + +src/protos.h: src/*.c + ruby -e '' && perl -e '' && (grep "^[^/\#*} ].*(.*{" src/*.c | perl -pe 's/ {/;/ or die $$_' | perl -pe '$$m=$$_;s/\/\*.*?\*\// /g;/(\w+)\(/ or die $$_;print "$$1:";$$_=$$m' | perl -pe 's/\bTYP\b/struct typ/g;s/\bSYM\b/struct sym/g;s/\bTABLE\b/struct stab/g;s/\bHTABLE\b/struct hstab/g;s/\bSTACK_IMAGE\b/struct _stackimg/g;s/\bREGS_IMAGE\b/struct _regsimg/g;s/\b_pc_bcd\b/struct _pc_bcd_s/g' | sort | uniq | ruby script/mkprotos.rb > $@) || echo 1>&2 "warning: unable to rebuild 'protos.h'" + +gtc: $(SOURCEFILES) + $(MAKE) gtc-rebuild + +#$(OBJFILES): $(HEADERS) +gtc-rebuild: $(OBJFILES) + $(CC) -o gtc $(LDFLAGS) $(OBJFILES) + +%.o: %.c vcg.c error.c *.h gtpack/*.h Makefile config.mk + $(CC) -c $(CFLAGS) $< diff --git a/gtc/Makefile.orig b/gtc/Makefile.orig new file mode 100644 index 0000000..e1b154a --- /dev/null +++ b/gtc/Makefile.orig @@ -0,0 +1,87 @@ +VPATH = src + +ifndef DEBUG_FLAG +CCBASEFLAGS=-O2 -Wimplicit +LDFLAGS=-s +else +CCBASEFLAGS=-g -Wall +LDFLAGS= +endif +ifdef MINGW32 +ifeq (Cygwin,$(shell uname -o)) +CCBASEFLAGS += -mno-cygwin +LDFLAGS += -mno-cygwin +endif +endif +include ../config.mk +include ../platform.mk +CDEFINES=$(GTC_ARCH_DEFINES) -DINCL_PATH=\"$(prefix)/share/gtc/include\" +CFLAGS=$(CCBASEFLAGS) $(CDEFINES) +OBJFILES=\ + analyze.o \ + cmain.o \ + decl.o \ + expr.o \ + func.o \ + gen68k.o \ + genffp.o \ + genstmt.o \ + getasm.o \ + getsym.o \ + init.o \ + intexpr.o \ + memmgt.o \ + optimize.o \ + out68k_as.o \ + peep68k.o \ + preproc.o \ + reg68k.o \ + searchkw.o \ + stmt.o \ + sunpack.o \ + symbol.o \ + ttbin2asm.o \ + + +.PHONY: all clean install + +all: gtc + +clean: + $(RM) $(OBJFILES) src/tags +distclean: clean + $(RM) gtc$(BIN_SUFFIX) +scratchclean: distclean + +install: gtc + mkdir -p $(prefix)/bin + install gtc $(prefix)/bin/gtc + +splint: + splint \ + -nestcomment -paramuse -nullassign -initallelements -fullinitblock \ + +charint +boolint -boolops +ptrnegate -shiftnegative \ + -nullret -retvalint -retvalother \ + -noeffect \ + -globstate -mustfreeonly -mustfreefresh -onlytrans -statictrans -observertrans -dependenttrans -temptrans -branchstate \ + $(CDEFINES) $(OBJFILES:%.o=%.c) + # -nestcomment is for '//#define foo bar /* this is a comment */' + # -paramuse is for unused func params + # -nullassign is for 'int x CGLOB;' + # -initallelements is for 'int x[5] CGLOBL;' + # -fullinitblock is for 'TI_SHORT x CGLOBL;' + # +charint is for 'char c = 2+1;' or 'if (c < 2+1)' + # +boolint is for 'int z = (x==y);' + # -boolops is for 'ptr && x' + # +ptrnegate is for '!ptr' + # -shiftnegative is for '1 << my_int' where 'my_int' has no known range + # -noeffect is for '(void)0' + # -nullret is for 'return NULL;' without '/*@null@*/' annotation + # -retvalint is for 'myfunc(x);' without subsequent cast to void + # -retvalother is for 'myfunc(x);' without subsequent cast to void + +gtc: $(OBJFILES) + $(CC) -o gtc $(LDFLAGS) $(OBJFILES) + +%.o: %.c vcg.c error.c *.h gtpack/*.h Makefile config.mk + $(CC) -c $(CFLAGS) $< diff --git a/gtc/script/mkprotos.rb b/gtc/script/mkprotos.rb new file mode 100644 index 0000000..1255eeb --- /dev/null +++ b/gtc/script/mkprotos.rb @@ -0,0 +1,114 @@ +#!/usr/bin/ruby + +class String + def scan_for_structenum(target) + scan(/(struct\s+\w+)/) do + target[$1] = true + end + scan(/enum\((\w+)\)/) do + target["enum #$1"] = true + end + end +end + +class FuncDef + attr_accessor :name,:files,:proto,:referenced + def initialize(name,files,proto) + @name = name + @files = files + @proto = proto + @referenced = [] + end + def to_s + (files.length==1 ? files[0] : "{"+files.join(",")+"}")+":#{name} [[#{proto}]]" + end + def inspect + "{{FuncDef #{to_s}}}" + end + def compatible?(oth) + name==oth.name && proto==oth.proto + end + def static? + proto =~ /^\bstatic\b/ + end +end + +funcs = {} +structenum = {} + +while x=gets + if x !~ /^(\w+):(.*?):(.*)$/ + throw x + else + func = FuncDef.new($1,[$2],$3) + if !func.static? + func.proto.scan_for_structenum(structenum) + name = func.name + if funcs[name] + if funcs[name].compatible?(func) + funcs[name].files += func.files + else + $stderr.puts "conflict between #{funcs[name]} and #{func}" + throw :conflict + end + else + funcs[name] = func + end + end + end +end + +banlist = %w(debug isidch isalnum isdigit isspace unary declare nl Compile err_int warn_int error_do AP_app AP_about sUnpack) +banlist.each do |name| + funcs.delete(name) +end + +class Union + include Enumerable + def initialize(*sets) + @sets = sets + end + def each + @sets.each do |set| + set.each do |item| + yield item + end + end + end +end + +Union.new(Dir['**/*.c']).each do |path| + File.open(path) do |f| + words = Hash.new 0 + f.each do |line| + line.scan(/\w+/) do |word| + if funcs[word] + words[word] += 1 + end + end + end + words.each do |word,count| + if funcs[word].files != [path] + funcs[word].referenced << path + end + end + end +end + + +puts "// Auto-generated file, do not edit!" +puts +puts "#ifndef PROTOS_H_" +puts "#define PROTOS_H_" +puts +structenum.keys.sort.each do |decl| + puts "#{decl};" +end +puts +funcs.each do |name,func| + if !func.referenced.empty? || func.files!=["src/out68k_as.c"] + puts func.proto + end +end +puts +puts "#endif" diff --git a/gtc/src/Makefile b/gtc/src/Makefile new file mode 100644 index 0000000..8f74291 --- /dev/null +++ b/gtc/src/Makefile @@ -0,0 +1,4 @@ +all: + +tags: *.c *.h + ctags *.c *.h diff --git a/gtc/src/all.c b/gtc/src/all.c new file mode 100644 index 0000000..57a41fd --- /dev/null +++ b/gtc/src/all.c @@ -0,0 +1,201 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) main file + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define DECLARE +#define FLASH_VERSION +#define GTDEV +#include "define.h" +#ifdef OPTIMIZE_BSS +register void *bssdata asm("a5"); +#endif +#define dseg() while (0) +#define cseg() while (0) +#define nl() while (0) +#define compound_done getsym +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +#include "flashhdr.h" +#ifdef GTDEV +#include "GtDevComm.h" +#endif +#include "flashhdr.c" + +#ifndef debug +void debug(int c) { + printf("%c ",c); + ngetchx(); +} +#endif + +#undef exit +#define exit(k) asm(" move.l exit_a7,%sp\n rts") +extern char *curname; +extern void fatal(char *s) __attribute__ ((noreturn)); + +#include "out68k_as.c" + +#include "decl.c" +#include "expr.c" +#ifdef ASM +#include "getasm.c" +#endif +#include "getsym.c" +#include "init.c" +#include "intexpr.c" +//#include "memmgt.c" // xalloc is common to both modules +#include "preproc.c" +#include "searchkw.c" +#include "stmt.c" +#include "symbol.c" + +void *exit_a7 CGLOB; +#if 0 +void _exit(int code) { + clean_up(); + printf("\nerror code %d",code); + while (!kbhit()); + asm(" move.l exit_a7,%sp; rts"); +// exit(0); +} +#endif + +void _noreturn assert_terminated(); +#ifdef GTDEV +void fatal(char *message) { + clean_up(); + msg_process(message, ET_FATAL, "", "", -1, -1); + exit(0); + assert_terminated(); +} +#else +void fatal(char *message) { + clean_up(); + msg2("Fatal error!\n%s\n", message); +// msg("There may be a syntax error or a compiler bug.\n"); +// while (!kbhit()); + ngetchx(); + asm(" move.l exit_a7,%sp; rts"); + assert_terminated(); +// exit(0); +} +#endif + +void fatal(char *s) __attribute__ ((noreturn)); + +#define mk_node near_mk_node +#define mk_icon near_mk_icon +struct enode *mk_node(enum(e_node) nt, struct enode *v1, struct enode *v2) { +/* + * build an expression node with a node type of nt and values v1 and v2. + */ + struct enode *ep; + ep = (struct enode *) xalloc((int) sizeof(struct enode), ENODE+MK_NODE); + ep->nodetype = nt; + ep->etype = bt_void; + ep->esize = -1; + ep->v.p[0] = v1; + ep->v.p[1] = v2; + return ep; +} + +struct enode *mk_icon(long i) { +/* + * build an expression node forming an integer constant + */ + struct enode *ep; +// ep = (struct enode *) xalloc((int) sizeof(struct enode), ENODE+MK_ICON); + ep = (struct enode *) xalloc((int) sizeof(struct xcon), ENODE+MK_ICON); + ep->nodetype = en_icon; + ep->etype = bt_void; +#ifdef NO_CALLOC + ep->esize = 0; +#endif + ep->v.i = i; + return ep; +} + +#include "analyze.c" +#include "func.c" +#include "gen68k.c" +#include "genffp.c" +#include "genstmt.c" +#include "memmgt.c" // xalloc is common to both modules +#include "optimize.c" +#include "peep68k.c" +#include "reg68k.c" + +/* this is reimplemented because old versions of TIGCC didn't check for _F_WRIT */ +void my_fclose(FILE *f) { + if (f->flags&_F_WRIT) + HeapRealloc(f->handle,*(unsigned short*)f->base+2); + HeapUnlock(f->handle); + free(f); +} + +asm("bcopy:\n" +" move.w (12,%sp),-(%sp)\n" +" clr.w -(%sp)\n" +" move.l (8,%sp),-(%sp)\n" +" move.l (16,%sp),-(%sp)\n" +" movea.l 0xC8,%a0\n" +" movea.l (%a0,0x26A*4),%a0\n" +" jsr (%a0) /* memcpy */\n" +" lea (%sp,12),%sp\n" +" rts\n" + +"__mulsi3:\n" +" move.l (4,%sp),%d1\n" +" move.l (8,%sp),%d2\n" +" move.l %d2,%d0\n" +" mulu %d1,%d0\n" +" swap %d2\n" +" mulu %d1,%d2\n" +" swap %d1\n" +" mulu (10,%sp),%d1\n" +" add.w %d1,%d2\n" +" swap %d2\n" +" clr.w %d2\n" +" add.l %d2,%d0\n" +" rts\n" + +"__modsi3:\n" +" move.w #0x2A9*4,%d2 /* _ms32s32 */\n" +" bra.s __div_entry\n" +"__divsi3:\n" +" move.w #0x2A8*4,%d2 /* _ds32s32 */\n" +" bra.s __div_entry\n" +"__umodsi3:\n" +" move.w #0x2A9*4,%d2 /* _mu32u32 */\n" +" bra.s __div_entry\n" +"__udivsi3:\n" +" move.w #0x2A8*4,%d2 /* _du32u32 */\n" +" bra.s __div_entry\n" +" nop\n" +"__div_entry:\n" +" move.l (4,%sp),%d1\n" +" move.l (8,%sp),%d0\n" +" movea.l 0xC8,%a0\n" +" movea.l (%a0,%d2.w),%a0\n" +" jsr (%a0)\n" +" move.l %d1,%d0\n" +" rts"); + +#include "cmain.c" + +#include "flashend.c" +// vim:ts=4:sw=4 diff --git a/gtc/src/analyze.c b/gtc/src/analyze.c new file mode 100644 index 0000000..b0ff640 --- /dev/null +++ b/gtc/src/analyze.c @@ -0,0 +1,816 @@ +/* + * GTools C compiler + * ================= + * source file : + * analyzer + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +//#undef OPT_ROMCALLS + +/* + * this module will step through the parse tree and find all optimizable + * expressions. at present these expressions are limited to expressions that + * are valid throughout the scope of the function. the list of optimizable + * expressions is: + * + * constants + * global and static addresses + * auto addresses + * contents of auto addresses. + * + * contents of auto addresses are valid only if the address is never referred to + * without dereferencing. + * + * scan will build a list of optimizable expressions which opt1 will replace + * during the second optimization pass. + */ + +void scan(struct snode *block); +void repcse(struct snode *block); + +#define INIT_EXEC_COUNT 16 +FILE *list CGLOB; +int regs_used CGLOB; +struct enode *regexp[REGEXP_SIZE] CGLOBL; +xstatic unsigned int exec_count CGLOB; +xstatic struct cse *olist CGLOB; /* list of optimizable expressions */ + +int equalnode(struct enode *node1, struct enode *node2) { +/* + * equalnode will return 1 if the expressions pointed to by node1 and node2 + * are equivalent. + */ + if (node1 == 0 || node2 == 0) + return 0; + if (node1->nodetype != node2->nodetype) + return 0; + switch (node1->nodetype) { +#ifndef AS + case en_labcon: + /* FALLTHROUGH - HACK : v.i==(long)v.ensp */ + case en_icon: +#else + case en_labcon: + return (node1->v.enlab == node2->v.enlab); + case en_icon: +#endif + case en_autocon: + case en_tempref: // note: this one is not necessary when doing CSE, but can be useful in gen68k.c + /*infunc("chk_curword") + if (node2->v.i=(long)(char)0xCD) + bkpt();*/ + return (node1->v.i == node2->v.i); + case en_nacon: + return (!strcmp(node1->v.ensp, node2->v.ensp)); + case en_ref: + case en_fieldref: + return equalnode(node1->v.p[0], node2->v.p[0]); + default: + return 0; + } +} + + +static struct cse *searchnode(struct enode *node) { +/* + * searchnode will search the common expression table for an entry that + * matches the node passed and return a pointer to it. + * the top level of equalnode is code inline here for speed + */ + register struct cse *csp; + register struct enode *ep; + if (node == 0) + return 0; + csp = olist; + while (csp != 0) { + ep = csp->exp; + if (ep != 0 && node->nodetype == ep->nodetype) { + switch (node->nodetype) { + case en_icon: +#ifndef AS + case en_labcon: +#endif + case en_autocon: + if (node->v.i == ep->v.i) + return csp; + break; +#ifndef AS + case en_nacon: + if (!strcmp(node->v.ensp, ep->v.ensp)) + return csp; + break; +#endif +#ifdef AS + case en_labcon: + case en_nacon: + if (node->v.enlab == ep->v.enlab) + return csp; + break; +#endif + case en_ref: + if (equalnode(node->v.p[0], ep->v.p[0])) { + /* 05/09/03: added check for size ; struct or unions + * won't work either since Gen68k needs their address + */ + if (node->esize != ep->esize || bt_aggregate(node->etype)) + csp->voidf=1; + return csp; + } + break; + } + } + csp = csp->next; + } + return 0; +} + +struct enode *copynode(struct enode *node) { +/* + * copy the node passed into a new enode so it wont get corrupted during + * substitution. + */ + struct enode *temp; + if (node == 0) + return 0; + temp = (struct enode *) xalloc((int) sizeof(struct enode), ENODE+COPYNODE); + *temp = *node; + return temp; +} + + + +static struct cse *enternode(struct enode *node, int duse) { +/* + * enternode will enter a reference to an expression node into the common + * expression table. duse is a flag indicating whether or not this reference + * will be dereferenced. + */ + struct cse *csp; + if ((csp = searchnode(node)) == 0) { /* add to tree */ + csp = (struct cse *) xalloc((int) sizeof(struct cse), CSE+ENTERNODE); + csp->next = olist; +#ifdef NO_CALLOC + csp->uses = 0; + csp->duses = 0; + csp->voidf = 0; +#endif + csp->exp = copynode(node); + olist = csp; + if (bt_aggregate(node->etype)) + csp->voidf++; + } else { + /* + * Integer constants may be in the table with different sizes -- keep + * the maximum size + */ + if (node->nodetype == en_icon && node->esize > csp->exp->esize) + csp->exp->esize = node->esize; + } +/* infunc("chk_curword") + if (node->nodetype != en_icon && node->esize==1) + bkpt();*/ +#ifdef REGALLOC_FOR_SIZE +#define exec_count INIT_EXEC_COUNT +#endif + csp->uses+=exec_count; + if (duse) + csp->duses+=exec_count; +#ifdef REGALLOC_FOR_SIZE +#undef exec_count +#endif + return csp; +} + +static struct cse *voidauto(struct enode *node) { +/* + * voidauto will void an auto dereference node which points to the same auto + * constant as node. + */ + struct cse *csp; + csp = olist; + while (csp != 0) { + if (csp->exp->nodetype==en_ref && equalnode(node, csp->exp->v.p[0])) { + if (csp->voidf) + return 0; + csp->voidf = 1; + return csp; + } + csp = csp->next; + } + return 0; +} + +void scanexpr(struct enode *node, int duse) { +/* + * scanexpr will scan the expression pointed to by node for optimizable + * subexpressions. when an optimizable expression is found it is entered into + * the tree. if a reference to an autocon node is scanned the corresponding + * auto dereferenced node will be voided. duse should be set if the + * expression will be dereferenced. + */ + struct cse *csp, *csp1; + if (node == 0) + return; + switch (node->nodetype) { + case en_nacon: +#ifdef FLINE_RC + if (fline_rc && node->v.ensp && + node->v.ensp[1]=='R' && node->v.ensp[0]=='_' && + !memcmp(node->v.ensp+2,"OM_CALL_",8)) + break; +#endif + /*@fallthrough@*/ + case en_labcon: +#ifndef NO_ICONST_SCAN + case en_icon: +#endif + (void) enternode(node, duse); + break; + case en_autocon: + /* + * look if the dereferenced use of the node is in the list, remove it + * in this case + */ + if ((csp = voidauto(node)) != 0) { + csp1 = enternode(node, duse); + csp1->duses += csp->uses; + } else if (duse>=0) // don't enter it otherwise (we can already access it) + (void) enternode(node, duse); + break; + + case en_ref: + case en_fieldref: + if (node->v.p[0]->nodetype == en_autocon) { + /*infunc("ChargerAdressesData") + bkpt();*/ + { + int first = (searchnode(node) == 0); +/* infunc("chk_curword") if (node->v.p[0]->v.i==(long)(char)0xCD) + bkpt();*/ + csp = enternode(node, duse); + /* + * take care: the non-derereferenced use of the autocon node may + * already be in the list. In this case, set voidf to 1 + */ + if (searchnode(node->v.p[0]) != 0) { + csp->voidf = 1; + scanexpr(node->v.p[0], 1); + } else if (first) { + /* look for register nodes */ + int i = 0; + XLST_TYPE j = (XLST_TYPE)node->v.p[0]->v.i, *p; + p=reglst; while (i < regptr) { + if (*p++ == j) { + csp->voidf--; /* this is not in auto_lst */ +// if (regalloc[i]>=0) csp->reg=regalloc[i]; + csp->uses += 256 * INIT_EXEC_COUNT * (100 - i); + //csp->duses += 30 * (100 - i); // so we know we don't always need an areg + break; + } + ++i; + } + /* set voidf if the node is not in autolst */ + csp->voidf++; + i = autoptr; + p=autolst; + while (i--) + if (*p++ == j) { + csp->voidf--; + break; + } + /* + * even if that item must not be put in a register, + * it is legal to put its address therein + */ + if (csp->voidf) + scanexpr(node->v.p[0], 1); + } + } +#ifdef OPT_ROMCALLS + } else if (node->v.p[0]->nodetype == en_icon && node->v.p[0]->v.i == 0xC8) { + enternode(node, 1); +#endif + } else { + scanexpr(node->v.p[0], 1); + } + break; + case en_uminus: + case en_compl: + case en_ainc: + case en_adec: + case en_not: + case en_cast: + case en_deref: + scanexpr(node->v.p[0], duse); + break; + case en_alloca: + scanexpr(node->v.p[0], 0); + break; + case en_asadd: + case en_assub: + case en_add: + case en_sub: +#ifndef NO_IMPROVED_CSE_SCAN + if (duse) { + if (node->v.p[0]->etype==bt_pointer + || (node->v.p[1]->etype!=bt_pointer && node->v.p[0]->esize==4) + || (node->v.p[1]->esize!=4)) { + if (node->v.p[1]->nodetype!=en_icon) + scanexpr(node->v.p[0], 1), + scanexpr(node->v.p[1], 0); + else + scanexpr(node->v.p[0], -1); + } else scanexpr(node->v.p[0], 0), scanexpr(node->v.p[1], 1); + } else +#endif + scanexpr(node->v.p[0], 0), scanexpr(node->v.p[1], 0); +/* scanexpr(node->v.p[0], duse); // why ?? + scanexpr(node->v.p[1], duse);*/ + break; + case en_mul: + case en_div: + case en_lsh: + case en_rsh: + case en_mod: + case en_and: + case en_or: + case en_xor: + case en_lor: + case en_land: + case en_eq: + case en_ne: + case en_gt: + case en_ge: + case en_lt: + case en_le: + case en_asmul: + case en_asdiv: + case en_asmod: + case en_aslsh: + case en_asrsh: + case en_asand: + case en_asor: + case en_asxor: + case en_cond: + case en_void: + case en_assign: + scanexpr(node->v.p[0], 0); + scanexpr(node->v.p[1], 0); + break; + case en_fcall: + scanexpr(node->v.p[0], 1); + scanexpr(node->v.p[1], 0); + break; + case en_compound: + scan(node->v.st); + break; + } +} + +void scan(struct snode *block) { +/* + * scan will gather all optimizable expressions into the expression list for + * a block of statements. + */ + while (block != 0) { + unsigned int old=exec_count; + switch (block->stype) { + case st_return: + case st_expr: + opt4(&block->exp); + scanexpr(block->exp, 0); + break; + case st_loop: + opt4(&block->exp); + scanexpr(block->exp, 0); + exec_count*=block->count; + scanexpr(block->exp->v.p[0],0); // increase desirability of counter reg allocation + scan(block->s1); + if (block->v2.e) { + opt4(&block->v2.e); + scanexpr(block->v2.e, 0); + } + break; + case st_while: + case st_do: + exec_count*=block->count; + exec_count++; + opt4(&block->exp); + scanexpr(block->exp, 0); + exec_count--; + scan(block->s1); + break; + case st_for: + opt4(&block->exp); + scanexpr(block->exp, 0); + exec_count*=block->count; + opt4(&block->v1.e); + scanexpr(block->v1.e, 0); + scan(block->s1); + opt4(&block->v2.e); + scanexpr(block->v2.e, 0); + break; + case st_if: + opt4(&block->exp); + scanexpr(block->exp, 0); + exec_count=(unsigned int)(((unsigned long)exec_count*(unsigned long)block->count+32768)>>16); + scan(block->s1); + exec_count=old-exec_count; + scan(block->v1.s); + break; + case st_switch: + opt4(&block->exp); + scanexpr(block->exp, 0); + exec_count>>=1; + scan(block->v1.s); + break; + case st_case: + case st_default: + scan(block->v1.s); + break; + case st_compound: + case st_label: + scan(block->s1); + break; + } + block = block->next; + exec_count=old; + } +} + +unsigned long desire(struct cse *csp) { +/* + * returns the desirability of optimization for a subexpression. + */ +#ifdef INFINITE_REGISTERS + return 4294967295; +#endif + if (csp->voidf || (csp->exp->nodetype == en_icon && +// (unsigned int)csp->exp->v.i+8 <= 16)) + csp->exp->v.i < 16 && csp->exp->v.i >= 0)) + return 0; +#ifdef REGPARM_OLD + { struct enode *ep; + if (csp->exp->nodetype == en_ref && (ep=csp->exp->v.p[0])->nodetype == en_autocon + && ep->v.i>0 && (ep->v.i®_PARAMS)) + return 10000000; // if it's a register param, then it *must* be in a long-live reg + } +#endif + if (g_lvalue(csp->exp)) + return 2 * csp->uses; + return csp->uses; +} + +void bsort(struct cse **list) { +/* + * bsort implements a bubble sort on the expression list. + */ + struct cse *csp1, *csp2; + csp1 = *list; + if (csp1 == 0 || csp1->next == 0) + return; + bsort(&(csp1->next)); + while (csp1 != 0 && (csp2 = csp1->next) != 0 && desire(csp1) < desire(csp2)) { + *list = csp2; + csp1->next = csp2->next; + csp2->next = csp1; + list = &(csp2->next); + } +} + +#ifdef REGPARM_OLD +extern struct typ *head; +#define parm_val (_parm_val+1) +XLST_TYPE _parm_val[1+MAX_DATA+1+MAX_ADDR+1]; +int parm_reg[MAX_DATA+1+MAX_ADDR+1]; +#endif +void allocate(void) { +/* + * allocate will allocate registers for the expressions that have a high + * enough desirability. + */ + struct cse *csp; + struct enode *exptr/*,*ep*/; + reg_t datareg, addreg; +#ifdef AREG_AS_DREG + int areg_possible; +#endif + unsigned int mask, rmask; + struct amode *ap, *ap2; +//#define __DEBUG__ +/*#ifdef __DEBUG__ + int i=0;* +#endif*/ + regs_used = 0; + datareg = MAX_DATA+1; + addreg = MAX_ADDR+1 + AREGBASE; + mask = 0; + rmask = 0; + bsort(&olist); /* sort the expression list */ + csp = olist; +/* infunc("play") + bkpt();*/ //autoptr=0,regptr=0; + while (csp != 0) { +/*#ifdef __DEBUG__ + infunc("play") + if (i++==2) { + csp->voidf=1; + regs_used++; + rmask = rmask | (1 << (15 - datareg)); + mask = mask | (1 << datareg); + datareg++; + } +#endif*/ +/* + * If reg_option is not true, the 'desire' value must be at least + * 5000, which I hope can only be achieved by the 'register' attribute + */ + if (desire(csp) < 3*INIT_EXEC_COUNT || (!reg_option && desire(csp) < 5000)) + csp->reg = -1; +#ifndef AREG_AS_DREG + else if (csp->duses && +#else + else if ((areg_possible= +#endif + /* && (csp->duses * 3) > csp->uses */ + addreg < + #ifdef USE_LINK + FRAMEPTR + #else + STACKPTR - uses_link + #endif + /* + * integer constants may have different types + */ + && (csp->exp->nodetype == en_icon + /* + * the types which are fine in address registers + */ + || (csp->exp->etype == bt_short || + csp->exp->etype == bt_long || + csp->exp->etype == bt_ulong || + csp->exp->etype == bt_pointer)) +#ifndef AREG_AS_DREG + ) +#else + ) && csp->duses) +#endif + csp->reg = addreg++; + else if (datareg < AREGBASE && csp->exp->nodetype!=en_autocon) + csp->reg = datareg++; +#ifdef AREG_AS_DREG + else if (areg_possible) + csp->reg = addreg++; +#endif + else + csp->reg = -1; +/* infunc("chk_curword") + if (csp->reg==AREGBASE+2 || csp->reg==AREGBASE+3 || csp->reg==4) + bkpt();*/ + if (csp->reg IS_VALID) { + regexp[reg_t_to_regexp(csp->reg)] = csp->exp; + regs_used++; + rmask = rmask | (1 << (15 - csp->reg)); + mask = mask | (1 << csp->reg); + } + csp = csp->next; + } +#ifdef ADD_REDUNDANCY + if (regs_used>=6) { /* >=6 : won't increase the push/pop time very much */ + mask = 0x7CF8, rmask = 0x1F3E; + regs_used = 10; + /* (note that we could use less than 6 as a threshold, but the benefit lies around + +0.5% while the runtime cost is rather high for such functions) + (note too that the benefit for the optimization with threshold 6 is around 0.5% + only, but it is so inexpensive that we really can afford it :] ) */ + } +#endif + if (mask != 0) { + g_code(op_movem, 4, mk_rmask(rmask), push_am); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\t$regpush %04x\n", rmask); +#endif + } + save_mask = mask; + csp = olist; + while (csp != 0) { + if (csp->reg IS_VALID) { /* see if preload needed */ + exptr = csp->exp; +#ifdef REGPARM_OLD + /* the following code works since REGPARM's are always + * handled first -- their desire() is highest */ + if (exptr->nodetype==en_ref && (ep=exptr->v.p[0])->nodetype==en_autocon + && ep->v.i>0 && (ep->v.i®_PARAMS)) { + ap = mk_reg(ep->v.i>>REG_PARAMLOG); + ap2 = mk_reg(csp->reg); + g_code(op_move, (int) exptr->esize, ap, ap2); + } else +#endif + if (exptr->nodetype!=en_ref +#ifdef OPT_ROMCALLS + || exptr->v.p[0]->nodetype!=en_autocon +#endif +#ifdef REGPARM + || ((XLST_TYPE)exptr->v.p[0]->v.i >= -reg_size)) { +#else + || ((XLST_TYPE)exptr->v.p[0]->v.i > 0)) { +#endif + initstack(); + ap = g_expr(exptr, F_ALL | F_SRCOP); + ap2 = mk_reg(csp->reg); + g_code(op_move, (int) exptr->esize, ap, ap2); + freeop(ap); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "$reg "); + if (csp->reg < AREGBASE) + fprintf(icode, "D%d\n", csp->reg); + else + fprintf(icode, "A%d\n", csp->reg - AREGBASE); + g_icode(exptr); + } +#endif + } + } + csp = csp->next; + } +} + +#ifdef NO_EXTENDED_AUTOS +void repexpr(struct enode *node) { +#else +#define repexpr(node) _repexpr(&(node)) +void _repexpr(struct enode **ep) { + struct enode *node=*ep; +#endif +/* + * repexpr will replace all allocated references within an expression with + * tempref nodes. + */ + struct cse *csp; + if (node == 0) + return; + switch (node->nodetype) { + case en_icon: + case en_nacon: + case en_labcon: + case en_autocon: + if ((csp = searchnode(node)) != 0) { + if (csp->reg > 0) { + node->nodetype = en_tempref; + node->v.i = csp->reg; + } + } + break; + case en_ref: + case en_fieldref: + if ((csp = searchnode(node)) != 0) { + if (csp->reg > 0) { + node->nodetype = en_tempref; + node->v.i = csp->reg; + } else + repexpr(node->v.p[0]); + } else + repexpr(node->v.p[0]); + break; + case en_uminus: + case en_not: + case en_compl: + case en_ainc: + case en_adec: + case en_cast: + case en_deref: + case en_alloca: + repexpr(node->v.p[0]); + break; + case en_add: + if (node->v.p[0]->nodetype==en_autocon && node->v.p[1]->nodetype==en_icon) { + /**ep=mk_icon(node->v.p[0]->v.i+node->v.p[1]->v.i); + (*ep)->nodetype=en_autocon; + (*ep)->etype=bt_pointer; + (*ep)->esize=4;*/ + node->v.p[0]->v.i+=node->v.p[1]->v.i; + *ep=node->v.p[0]; + return; + } + /*@fallthrough@*/ + case en_sub: + case en_mul: + case en_div: + case en_mod: + case en_lsh: + case en_rsh: + case en_and: + case en_or: + case en_xor: + case en_land: + case en_lor: + case en_eq: + case en_ne: + case en_lt: + case en_le: + case en_gt: + case en_ge: + case en_cond: + case en_void: + case en_asadd: + case en_assub: + case en_asmul: + case en_asdiv: + case en_asor: + case en_asxor: + case en_asand: + case en_asmod: + case en_aslsh: + case en_asrsh: + case en_fcall: + case en_assign: + repexpr(node->v.p[0]); + repexpr(node->v.p[1]); + break; + case en_compound: + repcse(node->v.st); + break; + } +} + +void repcse(struct snode *block) { +/* + * repcse will scan through a block of statements replacing the optimized + * expressions with their temporary references. + */ + while (block != 0) { + switch (block->stype) { + case st_return: + case st_expr: + repexpr(block->exp); + break; + case st_loop: + repexpr(block->exp); + repcse(block->s1); + repexpr(block->v2.e); + break; + case st_while: + case st_do: + repexpr(block->exp); + repcse(block->s1); + break; + case st_for: + repexpr(block->exp); + repexpr(block->v1.e); + repcse(block->s1); + repexpr(block->v2.e); + break; + case st_if: + repexpr(block->exp); + repcse(block->s1); + repcse(block->v1.s); + break; + case st_switch: + repexpr(block->exp); + repcse(block->v1.s); + break; + case st_case: + case st_default: + repcse(block->v1.s); + break; + case st_compound: + case st_label: + repcse(block->s1); + break; + } + block = block->next; + } +} + +void opt1(struct snode *block) { +/* + * opt1 is the externally callable optimization routine. it will collect and + * allocate common subexpressions and substitute the tempref for all + * occurrances of the expression within the block. + * + */ + if (!opt_option) + return; + olist = 0; + exec_count = INIT_EXEC_COUNT; + scan(block); /* collect expressions */ + allocate(); /* allocate registers */ + repcse(block); /* replace allocated expressions */ +} +// vim:ts=4:sw=4 diff --git a/gtc/src/bin2calc.c b/gtc/src/bin2calc.c new file mode 100644 index 0000000..0638e4e --- /dev/null +++ b/gtc/src/bin2calc.c @@ -0,0 +1,102 @@ +/* + * GTools C compiler + * ================= + * source file : + * binary to TI calculator format conversion + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include +#include +#include +#include "define.h" +#include "gtpack/gtpack.c" + +// This structure comes from ttools. +typedef struct { + char signature[8]; // "**TI92P*" or "**TI89**" + unsigned char fill1[2]; // 01 00 + char folder[8]; // folder name + char desc[40]; // ---- not used ---- + unsigned char fill2[6]; // 01 00 52 00 00 00 + char name[8]; // varname + unsigned char type[4]; // 0C 00 00 00 + unsigned char size[4]; // complete file size (including checksum) + unsigned char fill3[6]; // A5 5A 00 00 00 00 + unsigned char datasize[2]; // data size +} TI_FILE_HDR; + + +static void put_little_endian(unsigned char *dest, unsigned long val, int len) { + while (len--) { + *dest++ = (unsigned char)(val&0xFF); + val >>= 8; + } +} +static void put_big_endian(unsigned char *dest, unsigned long val, int len) { + dest += len; + while (len--) { + *--dest = (unsigned char)(val&0xFF); + val >>= 8; + } +} + +char *create_ti_file(int calc,int tigl_type,char *name,char *folder,char *content,unsigned long content_size,unsigned long *ti_file_size) { + TI_FILE_HDR h; + memset(&h, 0, sizeof h); + memcpy(h.signature, "********", 8); +#define sig(x) memcpy(h.signature+2,x,sizeof(x)-1) + switch (calc) { + case 0: + sig("TI89"); + break; + case 1: + sig("TI92P"); + break; + case 2: + sig("TI92P"); + break; + default: + fatal("unknown calc type"); + } +#undef sig + h.fill1[0] = 1; + strncpy(h.folder, folder?folder:"main", 8); + h.fill2[0] = 1; h.fill2[2] = 0x52; + strncpy(h.name, name, 8); + h.type[0] = tigl_type; h.type[2] = 3; + h.fill3[0] = 0xA5; h.fill3[1] = 0x5A; + { + unsigned long oncalc_size = 88+content_size+2; + put_little_endian(h.size, oncalc_size, 4); + } + put_big_endian(h.datasize, content_size, 2); + + if (content_size>=65520) + fatal("TIOS variables can't be more than 65520 bytes long."); + + { + char *ret = malloc(sizeof(h)+content_size+2); + if (!ret) + fatal("Memory"); + if (ti_file_size) + *ti_file_size = sizeof(h)+content_size+2; + memcpy(ret, &h, sizeof(h)); + memcpy(ret+sizeof(h), content, content_size); + { + unsigned int crc = h.datasize[0]+h.datasize[1]; + unsigned long n = content_size; + while (n--) + crc += 0xff & (unsigned char)*content++; + put_little_endian(ret+sizeof(h)+content_size, crc, 2); + } + return ret; + } +} diff --git a/gtc/src/c.h b/gtc/src/c.h new file mode 100644 index 0000000..ab97e69 --- /dev/null +++ b/gtc/src/c.h @@ -0,0 +1,548 @@ +/* + * GTools C compiler + * ================= + * source file : + * C + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef C_H +#define C_H +#ifdef PC + #ifdef SHORT_INT + #undef int + #endif + #include + //#include + #include + #ifdef SHORT_INT + #define int short + #endif +#else + #include "define.h" +#endif +//#warning hey hey! +#include "error.h" + +#ifdef CPU_DEFINED +#undef CPU_DEFINED +#endif + +#ifdef MC68000 +#define MC680X0 +#ifdef CPU_DEFINED +error, define only one target CPU! +#endif +#define CPU_DEFINED +#define LIST_NAME "gtclist.txt" +#define ICODE_NAME "gtcicode.txt" +#endif + +#ifdef MC68010 +#define MC680X0 +#ifdef CPU_DEFINED +error, define only one target CPU! +#endif +#define CPU_DEFINED +#define LIST_NAME "gtclist.txt" +#define ICODE_NAME "gtcicode.txt" +#endif + +#ifdef MC68020 +#define MC680X0 +#ifdef CPU_DEFINED +error, define only one target CPU! +#endif +#define CPU_DEFINED +#define LIST_NAME "gtclist.txt" +#define ICODE_NAME "gtcicode.txt" +#endif + +#ifdef MC68030 +#define MC680X0 +#ifdef CPU_DEFINED +error, define only one target CPU! +#endif +#define CPU_DEFINED +#define LIST_NAME "gtclist.txt" +#define ICODE_NAME "gtcicode.txt" +#endif + +#ifdef MC68040 +#define MC680X0 +#ifdef CPU_DEFINED +error, define only one target CPU! +#endif +#define CPU_DEFINED +#define LIST_NAME "gtclist.txt" +#define ICODE_NAME "gtcicode.txt" +#endif + +#ifdef INTEL_486 +#ifndef INTEL_386 +#define INTEL_386 +#endif +#endif + +#ifdef INTEL_386 +#ifdef CPU_DEFINED +#error define only one target CPU! +#endif +#define CPU_DEFINED +#define LIST_NAME "c386.list" +#define ICODE_NAME "c386.icode" +/* + * if FUNCS_USE_387 is defined, extra library calls are generated if the + * nofpu option is in effect that allows to use code generated by + * this compiler to be linked with functions that return values + * on the 387 stack + */ +#define FUNCS_USE_387 +#endif + +#ifndef CPU_DEFINED +#error target CPU type must be defined +#endif + +/* the tokens returned from lexical analysis */ + +/* assumptions about the order : + * none currently (beware of is_lang_ext though) */ +enum e_sym { + // 0x00 + cconst, iconst, lconst, uconst, ulconst, sconst, rconst, plus, minus, + // 0x09 + divide, lshift, rshift, modop, eq, neq, lt, leq, gt, + // 0x12 + geq, assign, asplus, asminus, astimes, asdivide, asmodop, + asuparrow, + // 0x1A + aslshift, asrshift, asand, asor, autoinc, autodec, hook, compl, + // 0x22 + comma, colon, semicolon, uparrow, openbr, closebr, begin, end, + // 0x2A + closepa, pointsto, dot, lor, land, not, or, and, + // 0x32 + star, openpa, id, kw_int, kw_char, kw_short, kw_long, + kw_void, kw_float, kw_double, kw_struct, kw_union, + kw_enum, kw_unsigned, kw_signed, kw_auto, kw_extern, + kw_const, kw_volatile, + // 0x45 + kw_register, kw_typedef, kw_static, kw_goto, kw_return, + kw_sizeof, kw_break, kw_continue, kw_if, kw_else, kw_for, + kw_do, kw_while, kw_switch, kw_case, kw_default, + // 0x55 + eof, + // ANSI extensions + kw_typeof, dots, kw_alloca, + // GTC extensions + kw_loop, kw_until, kw_count, kw_eval, // (lang extensions) + kw_defined, kw_incbin, kw_softcast, kw_c, + // GNU C extensions + kw_asm, kwb_constant_p, kw_attr, + // ASM keywords + kw_dreg, kw_areg, sharp, +#ifdef OLD_AMODE_INPUT + kw_offs_end, +#endif + kw_instr, +}; +#define is_lang_ext(__st) (__st>=kw_loop && __st<=kw_eval) + +/* storage classes */ + +enum e_sc { + sc_static, sc_auto, sc_global, sc_external, sc_type, sc_const, + sc_member, sc_label, sc_ulabel, sc_typedef, sc_parms, sc_parms2, + sc_define, sc_vamac +}; + +/* basic data types */ + +#ifndef BCDFLT +#define bt_size(__x) ((__x)=bt_struct) +#else +#define bt_aggregate(__x) ((__x)>=bt_struct) +#endif +#define bt_uncastable(__x) ((__x)>=bt_struct) +#define iscomparable(tp) bt_comparable((tp)->type) +#define isscalar(tp) bt_scalar((tp)->type) +#define integral(tp) bt_integral((tp)->type) +#define isaggregate(tp) bt_aggregate((tp)->type) +enum e_bt { + bt_char, bt_uchar, bt_short, bt_ushort, + bt_long, bt_ulong, bt_float, +#ifdef DOUBLE + bt_double, +#endif + bt_pointer, + bt_func, + bt_void, bt_bitfield, + bt_struct, bt_union, +}; + +/* these form the string literal pool */ + +struct slit { + struct slit *next; + char *str; + short label; + short len; +}; + +/* a symbol table */ +struct stab { + int hash; + struct sym *head; + struct sym *tail; +}; +/* important points for reconsidering N_HASH value : + - a HTABLE is about 8*N_HASH -byte long + - each imbricated 'compound()' call takes the space of 2 HTABLEs on the stack + (512 bytes with N_HASH=32, thus allowing only 20 imbricated compound stmts) + - there are 6 static HTABLEs, 7 if AS is defined (but could be improved with malloc() / BSS) + - N_HASH = 1 << HASH_LOG */ +#define N_HASH 32 +#define N_HASH_AND "31" +#define HASH_LOG 5 +typedef struct hstab { + int hash; + struct htab { + struct sym *head; + struct sym *tail; + } h[N_HASH]; +} HTABLE; + +/* structure defining a data type */ + +struct typ { + struct stab lst; + struct typ *btp; +#ifdef LISTING + char *sname; +#endif + long size; + enum(e_bt) type; +/* + * The following six chars may be unsigned -- no harm. + * They could be ints without restriction -- this is to save memory + */ + /* + * val_flag is normally 0, except for: + * - type==bt_pointer: set to 1 if it's an array, to 0 if it's a pointer + * - type==bt_func: always set to 1 + * (passing a function is like passing an array, we should actually be passing a pointer; + * and like an array, we do not want cond_deref() to build an en_ref node) + * - type==bt_integral: set to 1 to indicate an enum (this feature is currently unused) + */ + char val_flag; + + char st_flag; // is the type already stored globally? + char const_flag; // is it a 'const' type? + char vol_flag; // is it a 'volatile' type? + char bit_width; + char bit_offset; +}; +#ifdef REGPARM +#define rp_dn bit_width +#define rp_an bit_offset +#endif + +/* a symbol table entry */ + +struct sym { + char *name; + struct sym *prev; + struct sym *next; + struct typ *tp; + union { + long i; + unsigned long u; + int splab; + char *s; + } value; + enum(e_sc) storage_class; + int used; // note: + // - for 'normal' symbols (C variables), this belongs to {-1,0,1} + // - for preprocessor symbols, the lower 8 bits is the number of arguments to the macro + // and the higher 8 bits are described in enum(e_ppsymflags) below +}; +enum e_ppsymflags { + PPSYM_UNDER_EXPANSION = 0x8000, // set if we are currently expanding this symbol (avoid recursive expansion) +#ifdef ASM + PPSYM_ASM_KEYWORD = 0x4000, // set if this an ASM reserved keyword ('move', 'b', 'w', 'l', 'd7', 'sp') + PPSYM_DEFINED_IN_ASM = 0x2000, // set if this symbol was defined inside an asm{} statement +#endif +}; + +#define SYM struct sym +#define TYP struct typ +#define TABLE struct stab + +#ifdef PC +#define MAX_ERROR_COUNT 1 +#else +#define MAX_ERROR_COUNT 1 +#endif +#define MAX_STRLEN 1500 +#define MAX_ID_LEN 50 +#ifdef OLD_MACRO +#define MAX_MAC_LEN 800 +#define LINE_LENGTH (1800+MAX_MAC_LEN+1) +#else +#define LINE_LENGTH (1800+1) +#endif +#define MAX_PARAMS 20 +#define REG_LIST 20 +#define AUTO_LIST 100 + +#define ERR_SYNTAX 0 /* general error */ +#define ERR_ILLCHAR 1 /* illegal character */ +#define ERR_FPCON 2 /* illegal floating-point constant */ +#define ERR_ILLTYPE 3 /* illegal type */ +#define ERR_UNDEFINED 4 /* undefined identifier */ +#define ERR_FIELD 5 /* no field allowed here */ +#define ERR_PUNCT 6 /* expected symbol not found */ +#define ERR_IDEXPECT 7 /* identifier expected */ +#define ERR_NOINIT 8 /* initialization invalid */ +#define ERR_INCOMPLETE 9 /* incomplete struct/union/enum declaration */ +#define ERR_ILLINIT 10 /* illegal initialization */ +#define ERR_INITSIZE 11 /* too many initializers */ +#define ERR_ILLCLASS 12 /* illegal storage class */ +#define ERR_BLOCK 13 /* function body expected */ +#define ERR_NOPOINTER 14 /* pointer type expected */ +#define ERR_NOFUNC 15 /* function type expected */ +#define ERR_NOMEMBER 16 /* struct/union member expected */ +#define ERR_LVALUE 17 /* l-value required */ +#define ERR_DEREF 18 /* error dereferencing a pointer */ +#define ERR_MISMATCH 19 /* type mismatch error */ +#define ERR_EXPREXPECT 20 /* expression expected */ +#define ERR_WHILEXPECT 21 /* 'while' expected in do-loop */ +#define ERR_ENUMVAL 22 /* enum value out of range */ +#define ERR_DUPCASE 23 /* duplicate case label */ +#define ERR_LABEL 24 /* undefined label */ +//#define ERR_PREPROC 25 /* preprocessing error */ +#define ERR_ARG 26 /* declared Argument missing */ +#define ERR_WIDTH 27 /* illegal field width */ +#define ERR_INTEXPR 28 /* illegal constant integer expression */ +#define ERR_CAST 29 /* error doing a cast */ +#define ERR_INTEGER 30 /* integer-valued type expected */ +#define ERR_CASTCON 31 /* error casting a constant */ +#define ERR_REDECL 32 /* illegal redeclaration */ +//#define ERR_PARMS 33 /* error while scanning a parameter list */ +#define ERR_FTYPE 34 /* bad host type for bit fields */ +#define ERR_INCLFILE 35 /* #include: no include file specified */ +#define ERR_CANTOPEN 36 /* can't open include file */ +#define ERR_DEFINE 37 /* wrong #define */ +#define ERR_CUSTOM 38 /* #error */ +#define ERR_DUPSYM 39 /* duplicate symbol */ +#define ERR_CONSTEXPECT 40 /* constant expression expected */ +#define ERR_OUTRANGE 41 /* value out of range */ +#define ERR_TOOMPARAMS 42 /* too many parameters to function */ +#define ERR_TOOFPARAMS 43 /* too few parameters to function */ +#define ERR_CASERANGE 44 /* invalid case range */ +#define ERR_UNEXPECTEOF 45 /* unexpected end of file */ +#define ERR_OTH 46 /* (custom error) */ +#define ERR_SYS 47 /* (system limitation) */ +#define ERRA_INVALIDREL 48 /* invalid relocation in expression */ + +/* alignment sizes */ + +#ifdef MC68000 +/* + * MC68000 is a 16-bit processor. Word alignment is OK in all cases + */ +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 2 +#define AL_POINTER 2 +#define AL_FLOAT 2 +#define AL_DOUBLE 2 +#define AL_STRUCT 2 +#define AL_FUNC 2 + +#define AL_DEFAULT 2 /* alignment suitable for all types */ +#endif /* MC68000 */ + +#ifdef MC68010 +/* + * MC68010 is a 16-bit processor. Word alignment is OK in all cases + */ +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 2 +#define AL_POINTER 2 +#define AL_FLOAT 2 +#define AL_DOUBLE 2 +#define AL_STRUCT 2 +#define AL_FUNC 2 + +#define AL_DEFAULT 2 /* alignment suitable for all types */ +#endif /* MC68010 */ + +#ifdef MC68020 +/* + * perhaps not necessary, but useful: 32-bit alignment for 32-bit types + */ +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 4 +#define AL_POINTER 4 +#define AL_FLOAT 4 +#define AL_DOUBLE 4 +#define AL_STRUCT 4 +#define AL_FUNC 4 + +#define AL_DEFAULT 4 /* alignment suitable for all types */ +#endif /* MC68020 */ + +#ifdef MC68030 +/* + * perhaps not necessary, but useful: 32-bit alignment for 32-bit types + */ +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 4 +#define AL_POINTER 4 +#define AL_FLOAT 4 +#define AL_DOUBLE 4 +#define AL_STRUCT 4 +#define AL_FUNC 4 + +#define AL_DEFAULT 4 /* alignment suitable for all types */ +#endif /* MC68030 */ + +#ifdef MC68040 +/* + * perhaps not necessary, but useful: 32-bit alignment for 32-bit types + */ +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 4 +#define AL_POINTER 4 +#define AL_FLOAT 4 +#define AL_DOUBLE 4 +#define AL_STRUCT 4 +#define AL_FUNC 4 + +#define AL_DEFAULT 4 /* alignment suitable for all types */ +#endif /* MC68040 */ + +#ifdef INTEL_386 +/* + * perhaps not necessary, but useful: 32-bit alignment for 32-bit types + */ +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 4 +#define AL_POINTER 4 +#define AL_FLOAT 4 +#define AL_DOUBLE 4 +#define AL_STRUCT 4 +#define AL_FUNC 4 + +#define AL_DEFAULT 4 /* alignment suitable for all types */ +#endif /* INTEL_386 */ + + +#ifdef SPARC +#define AL_CHAR 1 +#define AL_SHORT 2 +#define AL_LONG 4 +#define AL_POINTER 4 +#define AL_FLOAT 4 +#define AL_DOUBLE 8 +#define AL_STRUCT 8 +#define AL_FUNC 4 + +#define AL_DEFAULT 8 /* alignment suitable for all types */ +#endif /* SPARC */ + + +int *_xalloc(int); +struct sym *search(); +struct sym *gsearch(); +char *strsave(); +TYP *expression(); +TYP *exprnc(); +TYP *cast_op(); +TYP *mk_type(); +long intexpr(); +int getch(); +//void error(); +void getsym(); +void needpunc(); +void initsym(); +void append(); +long strip_icon(); +long push_param(); +void do_warning(char *,...); + +struct sym *symremove(); +void getidstr(); +void skipspace(); +void msg(char *s); + +void rel_local(); +void rel_global(); +void clean_up(); + +void out_init(); +void out_close(); +void do_compile(); +void initpch(); +void closepch(); + +void insert(SYM *sp,HTABLE *table); + +#ifdef DUAL_STACK +extern void *dualstack; +extern void *ds_currentlo,*ds_currenthi; +void ds_allocatleast(unsigned int size); +void ds_free(void); +#define ds_remaining (unsigned int)((char *)ds_currenthi-(char *)dualstack) +#define ds_ensure(size) ((ds_remaining>=(size) ? 0 : ds_allocatleast(size),0), dualstack) +#define ds_pop(target) (void)((target)!=ds_currentlo ? (dualstack = (target)) : ds_free(),0) +#ifdef PC +#define ds_update(ptr) (void)(dualstack=(ptr),dualstack+=(-(size_t)dualstack)&3,0) +#else +#define ds_update(ptr) (void)(dualstack=(ptr),1&(short)(long)dualstack ? ++dualstack,0 : 0,0) +#endif +#define ds_var(type) (type)dualstack +#define DS_BSIZE 6000 // we set aside 6 kb for each stack block +#endif +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/cglbdec.h b/gtc/src/cglbdec.h new file mode 100644 index 0000000..9ec330f --- /dev/null +++ b/gtc/src/cglbdec.h @@ -0,0 +1,303 @@ +/* + * GTools C compiler + * ================= + * source file : + * C global declarations + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef CGLBDEC_H +#define CGLBDEC_H +#ifdef PC +#define outstr stderr +#define msg(s) fprintf(outstr,s) +#define msg2(s,a) fprintf(outstr,s,a) +#define msg3(s,a,b) fprintf(outstr,s,a,b) +#define msg4(s,a,b,c) fprintf(outstr,s,a,b,c) +#define msg5(s,a,b,c,d) fprintf(outstr,s,a,b,c,d) +#define msg6(s,a,b,c,d,e) fprintf(outstr,s,a,b,c,d,e) +#define vmsg(s,va) vfprintf(outstr,s,va) +#else +#define msg printf +#define msg2(s,a) printf(s,a) +#define msg3(s,a,b) printf(s,a,b) +#define msg4(s,a,b,c) printf(s,a,b,c) +#define msg5(s,a,b,c,d) printf(s,a,b,c,d) +#define msg6(s,a,b,c,d,e) printf(s,a,b,c,d,e) +#undef vcbprintf +#define vcbprintf ({register long __a=32+*(long*)(*(long*)0xC8+0x14C); \ + (void(*)(void(*)(char,void**),void**,char*,void*))(__a+*(short*)__a);}) +#define vmsg(s,va) vcbprintf((void(*)(char,void**))fputchar,NULL,s,va) +#endif + +#define int_bits 16 +#define tp_int tp_short +#define tp_uint tp_ushort +#define fpu_option 0 +#define short_option 1 +#ifdef LISTING +#define list_option 1 +#else +#define list_option 0 +#endif +#define reg_option 1 +#define opt_option 1 +#define warn_option 1 +#define trans_option 0 +#ifdef ICODE +#define icode_option 1 +#else +#define icode_option 0 +#endif +enum e_xt { + X_MID_DECL=0x1, X_COMP_STRING=0x2, X_LANG_EXT=0x4, +}; +#define flags_fullgtc -1 /* all flags, even those that break compatibility */ +#define flags_basegtc (X_MID_DECL|X_COMP_STRING) /* all flags, except those that break compatibility */ +#define flags_cplusplus X_MID_DECL +#define flags_ansi 0 +extern int flags; +#ifdef SPEED_OPT +extern int speed_opt_value; +extern int default_speed_opt_value; +#endif +extern int verbose; +#ifdef PC +enum { + VERBOSITY_PRINT_SEARCH_DIRS=0x1, + VERBOSITY_PRINT_INCLUDES=0x2, +}; +extern int verbosity; +#endif + +extern FILE *input, *list, *output; +extern char *outputname,*calcname; +extern char proj_file[]; +extern char export_pfx[]; extern short_size export_pfx_len; +#ifdef ICODE +extern FILE *icode; +#endif +extern int nextlabel; +extern int lastch; +extern enum(e_sym) lastst; +#ifdef PC +extern enum(e_sym) cached_sym; +#else +extern enum(e_sym) _cached_sym; +#endif +extern int cached_flag; +extern char lastid[MAX_ID_LEN+1]; +extern int lastcrc; +extern int lastreg; +extern struct sym *lastsp; +extern char laststr[MAX_STRLEN + 1]; +extern int lstrlen; +extern unsigned long ival; +#ifndef NOFLOAT +extern double rval; +#endif + +extern HTABLE gsyms, lsyms, labsyms, gtags, ltags; + +extern struct slit *strtab; +extern struct slit *datatab; +extern XLST_TYPE lc_auto; +extern XLST_TYPE reg_size; +extern XLST_TYPE max_scratch; +extern XLST_TYPE act_scratch; +extern long lc_bss; /* local bss counter */ +extern int global_flag; +extern int global_strings; +extern int temp_mem,temp_local,min_temp_mem; +extern int asm_flag,asm_xflag,asm_zflag; +extern int nostub_mode; +extern int exestub_mode; +#ifdef MC680X0 +extern unsigned int save_mask; /* register save mask */ +#endif +extern char *declid; +extern int nparms; +extern int store_lst; +extern int pch_init; +extern int middle_decl; +extern char *names[MAX_PARAMS]; +extern int bit_offset; /* the actual offset */ +extern int bit_width; /* the actual width */ +extern int bit_next; /* offset for next variable */ +extern int decl1_level; + +#ifdef ASM +extern struct ocode *asm_head; +#endif +#ifdef AS +extern struct ocode *scope_head; +#else +#ifdef ASM +extern struct ocode *peep_head; +#endif +#endif + +#ifdef FLINE_RC +extern int fline_rc; +#endif + +//extern int list_option; +//extern int short_option; +//extern int opt_option; +//extern int trans_option; +//extern int warn_option; +//extern int fpu_option; +//extern int reg_option; +//#ifdef ICODE +//extern int icode_option; +//#endif +extern TYP *ret_type; + +extern int regptr; +extern XLST_TYPE reglst[REG_LIST]; +extern int autoptr; +extern XLST_TYPE autolst[AUTO_LIST]; + +extern struct enode *init_node; +#ifdef MID_DECL_IN_EXPR +extern struct enode *md_expr; +extern struct typ *md_type; +#endif + +#ifdef VERBOSE +extern struct tms tms_buf; +extern long decl_time, parse_time, opt_time, gen_time, flush_time; +#endif /* VERBOSE */ + +extern readonly TYP tp_void, tp_long, tp_ulong, tp_char, tp_uchar; +extern readonly TYP tp_short, tp_ushort, tp_float; +extern readonly TYP tp_econst, tp_string, tp_void_ptr, tp_int, tp_uint, tp_func; +extern readonly TYP tp_double; + +//extern int int_bits; + +#ifdef MC680X0 +extern readonly struct amode push, pop; +#define push_am (struct amode *)&push +#define pop_am (struct amode *)&pop +#endif +/*extern int uses_structassign;*/ +extern int regs_used; +extern int pushed; +extern int is_leaf_function, uses_link; +#ifdef INTEL_386 +extern int edi_used, esi_used, ebx_used; +#endif + +extern int lineno,lineid,lastch; +extern int prevlineid,cached_lineid; + +extern int err_force_line,err_cur_line,err_assembly; + +#ifdef DECLARE +extern TYP *head, *tail; + +extern int total_errors; + +/*extern FILE *input, + *list, + *output, + *bin;*/ + +//extern long ival; +extern double rval; + +extern SYM *lasthead; +extern struct slit *strtab; +extern struct slit *datatab; +extern int lc_static; +//extern int lc_auto; +extern struct snode *bodyptr; +extern int global_flag; +//extern int save_mask; /* register save mask */ +extern SYM *func_sp; + +extern TYP *lastexpr_tp; +extern int lastexpr_size, lastexpr_type; +#endif +extern struct amode *lastexpr_am; +extern int need_res; + +extern SYM *func_sp; + +#ifdef TWIN_COMPILE +extern int twinc_necessary; +extern int *twinc_info,*twinc_prev; +#endif + +SYM *search(char *na, int crc, HTABLE *tab); +void dodecl(enum(e_sc) defclass); +int eq_type(TYP *tp1, TYP *tp2); + +#ifndef integral +int integral(TYP *tp); +#endif +int isshort(struct enode *node); +int isbyte(struct enode *node); + +int radix36(char c); + +int equal_address(); + +int crcN(char *na); + +#ifdef ASM +void asm_getsym(); +#endif + +extern HTABLE defsyms; + +#define MAX_IF_DEPTH 50 +extern int ifdepth,ifreldepth,ifskip,ifsd; +extern int ifcount[MAX_IF_DEPTH]; +extern int ifval[MAX_IF_DEPTH]; +#endif + +#ifndef PCHS_MODES +#define PCHS_MODES +enum { PCHS_ADD=1, PCHS_UNLOAD=-1 }; +#endif + +#ifdef USE_MEMMGT +/* + * Memory is allocated in blocks of 4 kb, which form a linked list + */ + +#define BLKLEN 4096 + +#ifndef BLK_STRUCT +#define BLK_STRUCT +struct blk { + char m[BLKLEN]; /* memory area */ + struct blk *next; +}; +#endif + +#define NIL_BLK ((struct blk *)0) + +extern int glbsize, /* size left in current global block */ + locsize, /* size left in current local block */ + glbindx, /* global index */ + locindx; /* local index */ + +extern int glbmem,locmem; + +extern struct blk *locblk, /* pointer to local block list */ + *glbblk; /* pointer to global block list */ + +void tmp_use(); +void tmp_free(); +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/cmain.c b/gtc/src/cmain.c new file mode 100644 index 0000000..527513e --- /dev/null +++ b/gtc/src/cmain.c @@ -0,0 +1,675 @@ +/* + * GTools C compiler + * ================= + * source file : + * main entry point + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define CMAIN_C +#define DECLARE + +#ifdef PC +#ifdef _WIN32 +#define DIR_SEPARATOR '\\' +#define ENVPATH_SEPARATOR ';' +#else +#ifdef UNIXOID +#define DIR_SEPARATOR '/' +#define ENVPATH_SEPARATOR ':' +#else +#error Please define a directory and a $PATH separator for your platform. +#endif +#endif +#endif + +#ifdef PC +/* +#define memcmp memcmp2 +#define strcmp stricmp +//#define strlen strlen2 +#define abs abs2 +#define _rotl _rotl2 +#define _rotr _rotr2 +//#include + +// --> what was this crap ??? +*/ +#ifdef _MSC_VER +#include +#endif +#include +#endif + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +extern char *curname; + +#ifdef SPEED_OPT +int default_speed_opt_value CGLOB; +#endif + +static void openfile(); +static void closefile(); +static void initialize_files(); +static void close_files(); +#ifdef LISTING +static summary(); +#endif + +#ifdef PC +void fatal(char *s); +#else +void fatal(char *s) __attribute__ ((noreturn)); +#endif + +#ifdef PC +#ifndef debug +void debug(int c) { + fprintf(stderr,"debug step '%c'\n",c); +} +#endif +#ifdef EXCEPTION_MGT +static void exception(int sig) { + msg2("\n\nSIGNAL %d -- TERMINATING.\n", sig); + fatal("EXCEPTION"); +} +#endif +#define _exit __exit +int pause_on_error=0; +void _exit(int code) { + clean_up(); + if (pause_on_error) + getchar(); + exit(code); +} +#endif + +char export_pfx[20]; short_size export_pfx_len; + +#ifdef TWIN_COMPILE +int twinc_necessary CGLOB; +int *twinc_info CGLOB,*twinc_info0 CGLOB,*twinc_prev CGLOB,*twinc_prev0 CGLOB; +#endif + +#ifdef PC + char *calcfolder=0; + static char _calcfolder[100]; + char *outputname=0,*calcname=0; + static char _calcname[100]; + + #include + #include + #if 0 + void TempName(char *dest) { + int i; + srand(clock()); + *dest++='~'; + *dest++='g'; + *dest++='t'; + *dest++='c'; + for (i=0;i<4;i++) + *dest++='0'+(rand()*10)/(RAND_MAX+1); + strcpy(dest,".tmp"); + } + #endif + + /* warning: duplicated in getsym.c! */ + enum OptionModes { optn_parse=0, optn_global_init, optn_global_init_post, optn_preproc_init }; + size_t option_parse(size_t listc,char **listv,enum(OptionModes) ex_mode); + void option_parse_all(enum(OptionModes) ex_mode); + + char *incfolders[10] CGLOBL; + size_t incfoldernum CGLOB; + + size_t optnc,optnmax; char **optnv; + size_t filec,filemax; char **filev; + +#define LST_INIT(lst,len) (lst##c=0, lst##max=(len), lst##v=alloca((len)*sizeof(*lst##v))) +#define LST_ADD(lst,val) (lst##c>=lst##max?exit(EXIT_FAILURE):(void)0, lst##v[lst##c++]=(val)) + + void cmdline_parse(size_t argc, char **argv) { + size_t i; + int force_files = 0; + for (i=1; i 0) + _exit(1); + if (temp_mem) + printf("TEMP MEM LEAK\n"), temp_mem=0; + return 0; + } +#else /* !defined(PC) */ +#ifdef OPTIMIZE_BSS + #define PRI_MAIN + void _zmain(void); + #include "identity.h" + int has_error CGLOB; + #ifndef GTDEV + void _main(void) { + bssdata=malloc(BSS_SIZE); + if (!bssdata) return; + memset(bssdata,0,BSS_SIZE); + has_error=1; + asm("movem.l d0-d7/a0-a4/a6,-(a7)"); /* do not include 'a5' :o */ + _zmain(); + asm("movem.l (a7)+,d0-d7/a0-a4/a6"); + bssdata=identity(bssdata); /* volatilize 'bssdata' =) */ + if (bssdata) { /* in case 'input' or 'output' couldn't be opened... */ + if (bin) free(bin); + fclose(output); + fclose(input); + free(bssdata); + } + } + #else + void _main(void) { + ST_helpMsg("Please use the IDE to compile."); + ngetchx(); + } + #endif + #ifdef GTDEV + void _gtdevmain(void) { + has_error=1; + asm("movem.l d0-d7/a0-a4/a6,-(a7)"); /* do not include 'a5' :o */ + _zmain(); + asm("movem.l (a7)+,d0-d7/a0-a4/a6"); + bssdata=identity(bssdata); /* volatilize 'bssdata' =) */ + if (bssdata) { /* in case 'input' or 'output' couldn't be opened... */ + if (bin) free(bin); + fclose(output); + fclose(input); + } + } + #endif + void _zmain(void) { +#else + void _main(void) { +#endif + int n; + #ifndef GTDEV + clrscr(); + #endif +// __HALT; +/* tp_econst = tp_int; + tp_econst.val_flag=1;*/ + #ifndef PRI_MAIN + #ifdef OPTIMIZE_BSS + bssdata=malloc(BSS_SIZE); + if (!bssdata) return; + memset(bssdata,0,BSS_SIZE); + #endif + #endif + + #ifndef GTDEV + #define in_file "in" + #ifdef AS + #define out_file "outbin" + #else + #define out_file "out" + #endif + #endif + if (!(input=fopen(in_file,"r"))) goto quit; + #ifdef AS + if (!(output=fopen(out_file,"wb"))) { fclose(input); quit: free(bssdata); bssdata=0; return; } + #else + if (!(output=fopen(out_file,"w"))) { fclose(input); quit: free(bssdata); bssdata=0; return; } + #endif + + /********************************************************* + * [!BUG-SOURCE!] THE FOLLOWING LINE IS FAIRLY GORE SO * + * *ANY* MODIFICATION WHATSOEVER TO _MAIN (OR EVEN ANY * + * COMPILER UPDATE...) MIGHT BREAK COMPATIBILITY! * + * */ + #ifndef GTDEV + /**/ asm("lea 12(%sp),%a0\n move.l %a0,exit_a7"); /**/ + #else + /**/ asm("lea 4(%sp),%a0\n move.l %a0,exit_a7"); /**/ + #endif + /* * + *********************************************************/ + out_init(); + initpch(); + strcpy(export_pfx,strrchr(in_file,'\\')?:in_file); + strcat(export_pfx,"__"); export_pfx_len=strlen(export_pfx); + do_compile(); + closepch(); + debug('E'); + out_close(); + debug('Q'); +// rel_global(); in out_close() + if (ferror(output)) fatal("Memory"); + #ifndef PRI_MAIN + fclose(output); + fclose(input); + #endif + #ifndef GTDEV + if (temp_mem) printf("TEMP MEM LEAK\n"), temp_mem=0; + #endif +/* if (total_errors > 0) { printf("\nThere were errors."); while (!kbhit()); } + else*/ { + #ifdef PRI_MAIN + has_error=0; + #endif + #ifndef GTDEV + FILE *fp=fopen("gtcerr","wb"); + if (fp) { + fputc(0,fp); + fputc(POSINT_TAG,fp); + fclose(fp); + } + printf("\nsuccess"); + n=4000; + while (n-- && !kbhit()); + if (kbhit()) ngetchx(); + #endif + } + #ifndef PRI_MAIN + #ifdef OPTIMIZE_BSS + free(bssdata); + #endif + #endif + } +#endif /* !defined(PC) */ + + +#ifdef PC +int forbid_bss=0; + +char *fill_calcvar(char *buffer, char *input) { + int i=0; + while (*input) { + char c=tolower(*input++); + if (c=='-' || c==' ' || c=='.') + c='_'; + if (isalnum(c) && i<8) + buffer[i++] = c; + } + buffer[i]=0; + if (!buffer[0]) + fatal("bad calculator variable name"); + return buffer; +} + +// Takes as an input the list of remaining arguments, returning: +// * 0: can't parse the option +// * n>0: the option was parsed successfully, n = number of arguments +// to skip for this option +size_t option_parse(size_t listc,char **listv,enum(OptionModes) ex_mode) { + char *s = listv[0]; + size_t value = 1; // number of arguments read so far + char *next_chunk, *_next_chunk; + #define strscmp(s,t) (next_chunk=_next_chunk="", strcmp(s,t)) + #define strbcmp(s,t) (next_chunk=_next_chunk=s+strlen(t), strncmp(s,t,strlen(t))) + // get_next_chunk is only necessary if you want to handle options split into several arguments + #define get_next_chunk() \ + do { \ + next_chunk = *_next_chunk ? _next_chunk : listc > value ? listv[value++] : NULL; \ + if (!next_chunk) return 0; \ + } while (0) + + // PURELY SYNTACTIC TRANSFORMATIONS + if (!strscmp(s,"-exe")) + s = "-DEXE_OUT"; + + // STANDALONE OPTIONS (strscmp) + if (!strscmp(s,"-o")) { + get_next_chunk(); + if (ex_mode==optn_global_init) + outputname = next_chunk; + } else if (!strscmp(s,"-v")) { +#ifdef PC + verbose=1; +#endif +#ifdef PC + } else if (!strscmp(s,"-print-search-dirs")) { + verbosity|=VERBOSITY_PRINT_SEARCH_DIRS; + } else if (!strscmp(s,"-print-includes")) { + verbosity|=VERBOSITY_PRINT_INCLUDES; +#endif + } else if (!strscmp(s,"-mno-bss")) { + if (ex_mode==optn_global_init) + forbid_bss=1; + } else if (!strcmp(s,"-O2")) { + default_speed_opt_value = 1; + } else if (!strcmp(s,"-O3")) { + default_speed_opt_value = 3; + } else if (!strcmp(s,"-Os")) { + default_speed_opt_value = -1; + // CHUNKED OPTIONS (strbcmp) + } else if (!strbcmp(s,"-I")) { + get_next_chunk(); + if (ex_mode==optn_global_init) + if (incfoldernumname = (char *)xalloc(name_end-name+1, STR); + memcpy(sp->name, name, (size_t)(name_end-name)); + sp->name[name_end-name] = 0; + sp->value.s = *name_end ? name_end+1 : "1"; + insert(sp,&defsyms); + } + // LONG OPTIONS + } else if (!strbcmp(s,"--")) { + // STANDALONE OPTIONS (strscmp) + if (!strscmp(s,"--nobss")) { + if (ex_mode==optn_global_init) + forbid_bss=1; + // CHUNKED OPTIONS (strbcmp) + } else if (!strbcmp(s,"--folder=")) { + if (ex_mode==optn_global_init) + calcfolder = fill_calcvar(_calcfolder,next_chunk); + } else if (!strbcmp(s,"--output=")) { + if (ex_mode==optn_global_init) + calcname = fill_calcvar(_calcname,next_chunk); + // ERROR + } else + return 0; + // ERROR + } else + return 0; + return value; + #undef get_next_chunk + #undef strbcmp + #undef strscmp +} +void option_parse_all(enum(OptionModes) ex_mode) { + size_t i; + for (i=0; i "zzz", and "zzz" -> "zzz") +static char *strlast(char *s,char c) { + char *t = strrchr(s,c); + return t ? t+1 : s; +} + +static void initialize_files() { + if (filec < 1) { + msg("no input file specified!\n"); + _exit(2); + } + + if (!outputname) { + outputname = _outputname; + strncpy(outputname,filev[0],sizeof(_outputname)-1); + outputname[sizeof(_outputname)-1]=0; + if (strrchr(outputname,'.')) + *strrchr(outputname,'.')=0; + } + strncpy(proj_file,outputname,sizeof(proj_file)-4-1); + proj_file[sizeof(proj_file)-4-1]=0; + strcat(proj_file,".gtc"); + + if (!calcname) { + char *zcalcname; + calcname = outputname; + calcname = strlast(calcname,'\\'); // for Windows + calcname = strlast(calcname,'/'); // for Unix + zcalcname = alloca(strlen(calcname)+1); + strcpy(zcalcname,calcname); + if (strrchr(zcalcname,'.')) + *strrchr(zcalcname,'.')=0; + calcname = fill_calcvar(_calcname,zcalcname); + } + strcpy(export_pfx,calcname); + strcat(export_pfx,"__"); export_pfx_len=strlen(export_pfx); +#ifndef AS + { + char *buffer=alloca(strlen(outputname)+strlen(".asm")+1); + sprintf(buffer,"%s.asm",outputname); + if (!(output = fopen(buffer, "w"))) { + msg("can't open output file\n"); + _exit(2); + } + } +#endif +#ifdef LISTING + if (list_option && (list = fopen(LIST_NAME, "w")) == 0) { + msg("can't open listfile\n"); + _exit(1); + } +#endif +#ifdef ICODE + if (icode_option && ((icode = fopen(ICODE_NAME, "w")) == 0)) { + msg("can't open icode file\n"); + _exit(1); + } +#endif +} +#endif + +#ifdef LISTING +static void summary(void) { +// if (gsyms.head != NULL) { + fprintf(list, "\f\n *** global scope symbol table ***\n\n"); + list_table(&gsyms, 0); +// } +// if (gtags.head != NULL) { + fprintf(list, "\n *** structures and unions ***\n\n"); + list_table(>ags, 0); +// } +} +#endif + +#ifdef PC +static void close_files(void) { +#ifdef LISTING + if (list_option) + fclose(list); +#endif +#ifdef ICODE + if (icode_option) + fclose(icode); +#endif +} +#endif + +#ifdef PC +void fatal(char *message) { + debug('f'); + clean_up(); + msg2("Fatal error!\n%s\n", message); +#ifdef PC + fflush(outstr); + if (pause_on_error) + getchar(); + exit(EXIT_FAILURE); +#else +// while (!kbhit()); + ngetchx(); + exit(0); +#endif +} +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/decl.c b/gtc/src/decl.c new file mode 100644 index 0000000..9a7a5ba --- /dev/null +++ b/gtc/src/decl.c @@ -0,0 +1,1657 @@ +/* + * GTools C compiler + * ================= + * source file : + * misc declarations + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define DECLARE +#define USE_MEMMGT +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +static struct typ *save_type(struct typ *tp); +static int declbegin(enum(e_sym) st); +static void declenum(struct hstab *table); +static void decl2(void); +static void declstruct(enum(e_bt) ztype); +static void enumbody(struct hstab *table); +static void structbody(struct typ *tp, enum(e_bt) ztype); +long auto_init(long offs,TYP *typ,TYP **tpp,int brace_level,int offmod,int stroff); +void doinit(struct sym *sp, int align); + +TYP *head CGLOB, *tail CGLOB; +int regptr CGLOB; +XLST_TYPE reglst[REG_LIST] CGLOBL; +int regalloc[REG_LIST]; +int autoptr CGLOB; +XLST_TYPE autolst[AUTO_LIST] CGLOBL; +int global_flag CGLOB,global_strings CGLOB; +int asm_flag CGLOB,asm_xflag CGLOB,asm_zflag CGLOB; +char *declid CGLOB; +int store_lst CGLOB; +#ifdef NEW_ATTR +TI_SHORT func_attr CGLOBL; +#endif +#ifdef MID_DECL +int middle_decl CGLOB; +#endif + +#ifdef LISTING +#define LP 0, +#else +#define LP +#endif + +readonly TYP tp_void = {{0, 0}, 0, LP 1, bt_void, 0, 1};// 1 and not -1 as previously defined +readonly TYP tp_long = {{0, 0}, 0, LP 4, bt_long, 0, 1}; +readonly TYP tp_ulong = {{0, 0}, 0, LP 4, bt_ulong, 0, 1}; +readonly TYP tp_char = {{0, 0}, 0, LP 1, bt_char, 0, 1}; +readonly TYP tp_uchar = {{0, 0}, 0, LP 1, bt_uchar, 0, 1}; +readonly TYP tp_short = {{0, 0}, 0, LP 2, bt_short, 0, 1}; +readonly TYP tp_ushort = {{0, 0}, 0, LP 2, bt_ushort, 0, 1}; +#ifndef NOFLOAT +#ifndef BCDFLT +readonly TYP tp_float = {{0, 0}, 0, LP 4, bt_float, 0, 1}; +#else +readonly TYP tp_float = {{0, 0}, 0, LP 10, bt_float, 0, 1}; +#endif +#ifdef INTEL_386 +readonly TYP tp_double = {{0, 0}, 0, LP 8, bt_double, 0, 1}; +#endif +#endif +readonly TYP tp_constchar = {{0, 0}, LP 0, 1, bt_char, 0, 1, 1}; +readonly TYP tp_string = {{0, 0}, (TYP *)&tp_constchar, LP 4, bt_pointer, 0, 1}; +readonly TYP tp_void_ptr = {{0, 0}, (TYP *)&tp_void, LP 4, bt_pointer, 0, 1}; +readonly TYP tp_econst = {{0, 0}, 0, LP 2, bt_ushort, 1, 1}; // tp_uint + val_flag=1 +//readonly TYP tp_int, tp_uint; +readonly TYP tp_func = {{0, 0}, (TYP *)&tp_int, LP 4, bt_func, 1, 1}; +//int int_bits; + +extern int glblabel; + +/* variables for function parameter lists */ +int nparms CGLOB; +char *names[MAX_PARAMS] CGLOBL; + +/* variable for bit fields */ +int bit_offset CGLOB; /* the actual offset */ +int bit_width CGLOB; /* the actual width */ +int bit_next CGLOB; /* offset for next variable */ +int decl1_level CGLOB; + +int stringlit(char *s, int len) { +/* + * mk_ s a string literal and return its label number. + * 'len' should not include the terminating zero + */ + struct slit *lp; + char *p; + int l, local_global = global_flag; + global_flag = 0; /* always allocate from local space. */ + lp=strtab; + while (lp!=0) { + if (len==(l=lp->len)) { + char *a=s,*b=lp->str; + while (l--) + if (*a++!=*b++) + goto stringlit_not_same; + return lp->label; + } + stringlit_not_same: + lp=lp->next; + } + lp = (struct slit *) xalloc((int) sizeof(struct slit), SLIT+STRINGLIT); + lp->label = global_strings?nxtglabel():nxtlabel(); + p = lp->str = (char *) xalloc((int) len, STR+STRINGLIT); + lp->len = len; + while (len--) + *p++ = *s++; + lp->next = strtab; + strtab = lp; + global_flag = local_global; + return lp->label; +} +#ifdef USE_DATALIT +int datalit(char *s, int len) { +/* + * mk_ s a data literal and return its label number. + */ + struct slit *lp; + char *p; + int l, local_global = global_flag; + global_flag = 0; /* always allocate from local space. */ + lp=datatab; + while (lp!=0) { + if (len==(l=lp->len)) { + char *a=s,*b=lp->str; + while (l--) + if (*a++!=*b++) + goto datalit_not_same; + return lp->label; + } + datalit_not_same: + lp=lp->next; + } + lp = (struct slit *) xalloc((int) sizeof(struct slit), SLIT+STRINGLIT); + lp->label = global_strings?nxtglabel():nxtlabel(); + p = lp->str = (char *) xalloc((int) len, STR+STRINGLIT); + lp->len = len; + while (len--) + *p++ = *s++; + lp->next = datatab; + datatab = lp; + global_flag = local_global; + return lp->label; +} +#endif + +char *litlate(char *s) { + char *p, *q, m; + int string=0; + while (isspace(*s)) s++; + q = p = (char *)xalloc((int)strlen(s) + 1, STR+LITLATE); + while ((*p++=m=*s++) && m!='\n') + if (p-2>=q && p[-2]=='\\') {} + else if (m=='"') string=~string; + else if (m=='/' && !string) { + if (*s=='/') { + p[-1]=' ', *p++=0; break; + } else if (*s=='*') { + p--; if (!isspace(p[-1])) *p++=' '; + s+=2; /* since / * / isn't a valid comment */ + while (*s && (*s++!='/' || s[-2]!='*')); + } + } + if (m) *--p=0; + if (string) return 0; /* invalid if quotes are unbalanced */ + return q; +} + +static long imax(long i, long j) { + return (i > j) ? i : j; +} + +char *strsave(char *s) { + char *p, *q; + q = p = (char *)xalloc((int)strlen(s) + 1, STR+STRSAVE); + while ((*p++ = *s++)); + return q; +} + +TYP *copy_type(TYP *s) { + TYP *tp; + tp = (TYP *) xalloc((int) sizeof(TYP), _TYP); + *tp = *s; + //memcpy(tp, s, sizeof(TYP)); + return tp; +} + +TYP *mk_type(enum(e_bt) bt, int siz) { + TYP *tp; + tp = (TYP *) xalloc((int) sizeof(TYP), _TYP+MK_TYPE); + tp->size = siz; + tp->type = bt; + tp->st_flag = global_flag; +#ifdef NO_CALLOC +#ifdef LISTING + tp->sname = 0; +#endif + tp->btp = 0; + tp->lst.tail = tp->lst.head = 0; tp->lst.hash = 0; + tp->val_flag = tp->const_flag = tp->vol_flag = 0; + tp->bit_width = 0; +#endif + return tp; +} + +TI_SHORT process_attr(); +void decl(HTABLE *table) { /* table is used only for enum members */ +// struct sym *sp; + + /* + * at top level, 'int' is changed to 'short' or 'long' + */ + + switch (lastst) { + case kw_void: + head = tail = (TYP *)&tp_void; + getsym(); + break; + case kw_char: + head = tail = (TYP *)&tp_char; + getsym(); + break; + case kw_short: + getsym(); + if (lastst == kw_unsigned) { + getsym(); + head = tail = (TYP *)&tp_ushort; + } else { + if (lastst == kw_signed) getsym(); + head = tail = (TYP *)&tp_short; + } + if (lastst == kw_int) + getsym(); + break; + case kw_int: + head = tail = (TYP *)&tp_int; + getsym(); + break; + case kw_long: + getsym(); + if (lastst == kw_unsigned) { + getsym(); + head = tail = (TYP *)&tp_ulong; + } else { + if (lastst == kw_signed) getsym(); + head = tail = (TYP *)&tp_long; + } + if (lastst == kw_int) + getsym(); + break; + case kw_unsigned: + getsym(); + switch (lastst) { + case kw_long: + getsym(); + head = tail = (TYP *)&tp_ulong; + if (lastst == kw_int) + getsym(); + break; + case kw_char: + getsym(); + head = tail = (TYP *)&tp_uchar; + break; + case kw_short: + getsym(); + head = tail = (TYP *)&tp_ushort; + if (lastst == kw_int) + getsym(); + break; + case kw_int: + getsym(); + default: + head = tail = (TYP *)&tp_uint; + break; + } + break; + case kw_signed: + getsym(); + switch (lastst) { + case kw_long: + getsym(); + head = tail = (TYP *)&tp_long; + if (lastst == kw_int) + getsym(); + break; + case kw_char: + getsym(); + head = tail = (TYP *)&tp_char; + break; + case kw_short: + getsym(); + head = tail = (TYP *)&tp_short; + if (lastst == kw_int) + getsym(); + break; + case kw_int: + getsym(); + default: + head = tail = (TYP *)&tp_int; + break; + } + break; + case kw_const: + getsym(); + decl(table); + head = copy_type(head); + head->const_flag = 1; + tail = head; + break; + case kw_volatile: + getsym(); + decl(table); + head = copy_type(head); + head->vol_flag = 1; + tail = head; + break; + case kw_typeof: + getsym(); + needpunc(openpa); + { struct enode *en; + /*tmp_use(); -> TODO, but copy_type must be global/local*/ + head = copy_type(expression(&en)); + /*tmp_free();*/ } + head->const_flag = head->vol_flag = 0; + tail = head; + needpunc(closepa); + break; + case id: + if (lastsp != 0 && + lastsp->storage_class == sc_typedef) + /* type identifier */ + { + /* BUGGY/FIXME!!! I swapped these two lines, but I can't figure out why + * they had to be */ + head = tail = lastsp->tp; + getsym(); + break; + } + /* else fall through */ + case openpa: + case star: + /* default type is int */ + head = tail = (TYP *)&tp_int; + break; +#ifndef NOFLOAT + case kw_float: +#ifndef DOUBLE + case kw_double: +#endif + head = tail = (TYP *)&tp_float; + getsym(); + break; +#ifdef DOUBLE + case kw_double: + head = tail = (TYP *)&tp_double; + getsym(); + break; +#endif +#endif + case kw_enum: + getsym(); + declenum(table); + break; + case kw_struct: + getsym(); + declstruct(bt_struct); + break; + case kw_union: + getsym(); + declstruct(bt_union); + break; + case kw_attr: + func_attr=process_attr(); + decl(table); + break; + } + if (lastst==kw_volatile) { + head = copy_type(head); + head->vol_flag = 1; + tail = head; + getsym(); + } +} + +#ifdef PC +TI_SHORT unset_attr={-1,-1}; +TI_SHORT stkparm_attr={0,0}; +TI_SHORT regparm_attr={2,1}; +#define attr_isset(v) ((v).hi!=(unsigned char)-1) +#else +#define unset_attr -1 +#define stkparm_attr 0 +#define regparm_attr 0x0201 +#define attr_isset(v) ((int)(v) IS_VALID) +#endif + +TI_SHORT process_attr() { +#ifdef DEFAULT_STKPARM +#ifndef NEW_ATTR + unsigned char rp_dn=0,rp_an=0; +#endif +#define DEFLT_ATTR stkparm_attr +#else +#ifndef NEW_ATTR + unsigned char rp_dn=2,rp_an=1; +#endif +#define DEFLT_ATTR regparm_attr +#endif +#ifdef NEW_ATTR + unsigned char rp_dn=-1,rp_an=-1; +#endif + getsym(); + needpunc(openpa); + { + int n=1; + do { + if (lastst==openpa) n++; + else if (lastst==closepa) n--; + else if (lastst==id) { +#ifdef REGPARM + if (lastid[0]=='_' && lastid[1]=='_') + memmove(lastid,lastid+2,MAX_ID_LEN-2),lastid[strlen(lastid)-2]=0; + if (!strcmp(lastid,"stkparm")) + rp_dn=0, rp_an=0; + else if (!strcmp(lastid,"aregparm")) + rp_dn=3, rp_an=2; + else if (!strcmp(lastid,"regparm")) { + getsym(); + if (lastst==openpa) { + getsym(); + if (lastst!=iconst) error(ERR_SYNTAX); + else { + rp_dn = rp_an = (char)ival; + getsym(); + if (lastst==comma) { + getsym(); + if (lastst==iconst) + rp_an = (char)ival, getsym(); + } + } + if (rp_dn>CONVENTION_MAX_DATA+1 || rp_an>CONVENTION_MAX_ADDR+1) + error(ERR_OUTRANGE), rp_dn=0, rp_an=0; + if (lastst!=closepa) uerr(ERR_PUNCT,')'); + } else { rp_dn=2; rp_an=1; goto nxt_attr; } + } +#endif + } else if (lastst!=comma) + uerr(ERR_PUNCT,')'); + getsym(); + nxt_attr: + (void)0; + } while (n>0); + } +#ifdef PC + { + TI_SHORT ret; + ret.hi=rp_dn; + ret.lo=rp_an; + return ret; + } +#else + return (rp_dn<<8)+(rp_an); +#endif +} + +void decl1(void) { +/* handles *, :, ... */ + TYP *temp1, *temp2, *temp3, *temp4; + decl1_level++; + switch (lastst) { + case id: + declid = strsave(lastid); + getsym(); + if (lastst != colon) { + decl2(); + break; + } + /* FALLTHROUGH */ + case colon: + getsym(); + if (decl1_level != 1) + error(ERR_FIELD); + if (head->type != tp_int.type && head->type != tp_uint.type) +#if 0 + error(ERR_FTYPE); +#else + uwarn("field type should be unsigned or int"); +#endif + bit_width = (int)intexpr(); + bit_offset = bit_next; + if (bit_width < 0 || bit_width > int_bits) { + error(ERR_WIDTH); + bit_width = 1; + } + if (bit_width == 0 || bit_offset + bit_width > int_bits) + bit_offset = 0; + bit_next = bit_offset + bit_width; + break; + case star: + temp1 = mk_type(bt_pointer, 4); + temp1->btp = head; + head = temp1; + if (tail == NULL) + tail = head; + getsym(); + decl1(); + break; + case openpa: { +#ifndef NEW_ATTR + short attr=DEFLT_ATTR; +#endif + getsym(); + temp1 = head; + temp2 = tail; + head = tail = NULL; + decl1(); +#ifndef NEW_ATTR + if (lastst==kw_attr) + attr=process_attr(); +#endif + needpunc(closepa); + temp3 = head; + temp4 = tail; + head = temp1; + tail = temp2; + decl2(); +#ifndef NEW_ATTR +#ifdef REGPARM + assert(sizeof(short)==sizeof(TI_SHORT)); + if (*(short *)&head->rp_dn==DEFLT_ATTR) + *(short *)&head->rp_dn=attr; +#endif +#endif + if (temp4 != NULL) { + temp4->btp = head; + if (temp4->type == bt_pointer && + temp4->val_flag != 0 && head != NULL) + temp4->size = (long)((int)head->size)*((int)temp4->size); + head = temp3; + } + } break; +#ifdef NEW_ATTR + case kw_attr: + func_attr=process_attr(); + decl1(); + break; +#endif +/* case kw_attr: + process_attr();*/ + /* FALL THROUGH */ + case kw_const: + getsym(); + head = copy_type(head); + head->const_flag = 1; + tail = head; + decl1(); + break; + case kw_volatile: + getsym(); + head = copy_type(head); + head->vol_flag = 1; + tail = head; + decl1(); + break; + default: + decl2(); + break; + } + decl1_level--; + /* + * Any non-bitfield type resets the next offset + */ + if (bit_width IS_INVALID) + bit_next = 0; +} + +#ifdef REGPARM +#if 0 +short count_dn_an(struct enode *plist,int rp_dn,int rp_an) { + int true_dn=0,true_an=0; + int nr=rp_dn+rp_an,np=0,n; + int list[16],*p; + struct enode *ep=plist; + while (ep) np++, ep=ep->v.p[1]; + /* first, push stack params while all the temp registers are free */ + while (np>nr) np--,plist = plist->v.p[1]; + /* store the last params so we can examinate them in the correct order */ + n=np; while (n--) list[n]=plist->v.p[0]->etype-bt_pointer, plist=plist->v.p[1]; + /* now, get the real # of regs */ + p=list; + n=np; while (n--) { + if ((!*p++ && rp_an) || !rp_dn) + true_an++, rp_an--; + else true_dn++, rp_dn--; + } +#ifdef PC + return (true_dn)+(true_an<<8); +#else + return (true_dn<<8)+(true_an); +#endif +} +#endif +#endif + +#ifndef NO_VARARG_FUNC +char variable_arg_name[]="__vararg__"; +#define is_variable_arg(sp) ((sp)->name==variable_arg_name) +#define mk_variable_arg(sp) ((sp)->name=variable_arg_name) +#endif + +static long declare(HTABLE *table, enum(e_sc) al, long ilc, enum(e_bt) ztype, int regflag); +static void decl2(void) { +/* Handles __attribute__, [*] (for arrays) and (*) (for functions) */ + TYP *temp1,*temp2; + long i; + switch (lastst) { + case openbr: + getsym(); + if (lastst == closebr) + i = 0; + else + i = intexpr(); + needpunc(closebr); + if (lastst == openbr) + decl2(); + temp1 = mk_type(bt_pointer, 0); + temp1->val_flag = 1; + temp1->btp = head; + if (head != 0) + temp1->size = i * head->size; + else + temp1->size = i; + head = temp1; + if (tail == NULL) + tail = head; + decl2(); + break; + case openpa: + getsym(); + temp1 = mk_type(bt_func, 4); + temp1->val_flag = 1; + temp1->btp = head; + temp1->lst.head=temp1->lst.tail=0; temp1->lst.hash=0; + head = temp1; + if (tail == NULL) + tail = head; + temp2 = tail; + if (lastst == kw_void) { + getcache(-1); + if (cached_sym == closepa) + getsym(); + } + if (lastst == closepa) + getsym(); + else { + TABLE *tp; + struct sym *sp; + char *func_name; + long slc; + int regflag; + int old_nparms; + int old_middle_decl=middle_decl,old_store_lst=store_lst; +// int old_regptr=regptr,old_autoptr=autoptr; +#ifdef NO_PROTO + if (nparms != 0) // (void(*)(myparam1...))myfunc() *was* invalid + error(ERR_PARMS); +#endif +#ifdef REGPARM +#ifdef DEFAULT_STKPARM + head->rp_dn=0; head->rp_an=0; +#else + head->rp_dn=2; head->rp_an=1; +#endif +#endif + /*if (lineid==32) + bkpt();*/ + tp=(TABLE *)temp1; + old_nparms=nparms; + func_name = declid; + slc=34560; + store_lst=pch_init?0:global_flag; + /* + * Basically 'store_lst' is always equal to 1, except in two cases: + * - declaring a function inside a PCH initialization (pch_init!=0) + * - prototyping a function (global_flag==0) + * because we don't want the parameters of those functions to mess + * with the function we are declaring. + * + * In all the other cases, we reset 'regptr'/'autoptr' when + * parsing the declaration of the function (starting from the + * parameter list, of course). + */ + if (store_lst) { + regptr = 0; + autoptr = 0; + } + middle_decl=0; + while (1) { + if (nparms >= MAX_PARAMS) + uerrsys("too many params"); + regflag = 3; + switch (lastst) { + case kw_typedef: case kw_static: case kw_auto: case kw_extern: + error(ERR_ILLCLASS); + return; + case kw_register: + regflag = 4; + getsym(); + goto do_pdecl; + case id: + /* + * If it is a typedef identifier, fall through & do the declaration. + */ + if (!(sp = lastsp) || sp->storage_class != sc_typedef) { + names[nparms++] = strsave(lastid); + getsym(); + break; + } + case kw_char: case kw_short: case kw_unsigned: case kw_long: + case kw_struct: case kw_union: case kw_enum: case kw_void: + case kw_float: case kw_double: case kw_int: case kw_typeof: + case kw_signed: case kw_const: case kw_volatile: +do_pdecl: + slc+=declare((HTABLE *)tp, sc_parms2, slc, bt_struct, regflag); + if (isaggregate(head)) + func_attr=stkparm_attr; /* force the function to be stkparm... */ + names[nparms++] = declid; + break; + /*case closepa: + getsym(); + return; */ + case dots: + getsym(); +#ifdef NO_VARARG_FUNC + tp->head=tp->tail=NULL; +#else + func_attr=stkparm_attr; /* force the function to be stkparm... */ + { + SYM *sp=(SYM *)xalloc(sizeof(SYM),_SYM); + mk_variable_arg(sp); + append(&sp,(HTABLE *)tp); + goto args_done; + } +#endif + break; + default: + error(ERR_SYNTAX); + } + if (lastst == comma) getsym(); + else break; + } + args_done: + store_lst=old_store_lst; + middle_decl=old_middle_decl; + needpunc(closepa); + head = temp1; + tail = temp2; + if (lastst != begin && (!nparms || !castbegin(lastst))) + nparms=old_nparms; + declid=func_name; + } +#ifdef NEW_ATTR + *(TI_SHORT *)&head->rp_dn=DEFLT_ATTR; +#endif + if (lastst==kw_attr) +#ifdef REGPARM + *(TI_SHORT *)&head->rp_dn= +#endif + process_attr(); +#ifdef NEW_ATTR + if (attr_isset(func_attr)) + *(TI_SHORT *)&head->rp_dn=func_attr, func_attr=unset_attr; +#endif +/*#ifdef REGPARM + if (head->rp_dn || head->rp_an) + *(short *)&(head->rp_dn)=count_dn_an( +#endif*/ + break; +/* if (lastst == kw_void) { + getsym(); + if (lastst != closepa) + error(ERR_PARMS); + } + if (lastst == closepa) + getsym(); + else { + if (nparms != 0) + error(ERR_PARMS); + if (lastst != id) { + while (lastst != closepa) { + names[nparms++] = strsave(lastid); + } + } else while (lastst == id) { + if (nparms >= MAX_PARAMS) + fatal("MAX_PARAMS"); + names[nparms++] = strsave(lastid); + getsym(); + if (lastst == comma) + getsym(); + } + needpunc(closepa); + } + break;*/ + } +} + +int alignment(TYP *tp) { + switch (tp->type) { + case bt_uchar: + case bt_char: + return AL_CHAR; + case bt_ushort: + case bt_short: + return AL_SHORT; + case bt_ulong: + case bt_long: + return AL_LONG; + case bt_pointer: + if (tp->val_flag) + return alignment(tp->btp); + else + return AL_POINTER; + case bt_func: + return AL_FUNC; + case bt_float: + return AL_FLOAT; +#ifdef DOUBLE + case bt_double: + return AL_DOUBLE; +#endif + case bt_struct: + case bt_union: + return AL_STRUCT; + case bt_void: + return 1; + default: + ierr(ALIGNMENT,1); + return 0; // does not happen + } +} + +xstatic long old_nbytes CGLOB; + /* should be in declare(), but SConvert would put it in the text */ + /* segment, preventing it from being modified */ +static long declare(HTABLE *table, enum(e_sc) al, long ilc, enum(e_bt) ztype, int regflag) { +/* + * process declarations of the form: + * + * , ...; + * + * leaves the declarations in the symbol table pointed to by table and returns + * the number of bytes declared. al is the allocation type to assign, ilc is + * the initial location counter. if al is sc_member then no initialization + * will be processed. ztype should be bt_struct for normal and in structure + * declarations and sc_union for in union declarations. + * + * regflag values: + * -2: union component + * -1: struct component + * 0: static, global, extern + * 1: auto + * 2: register auto + * 3: argument + * 4: register argument + */ + struct sym *sp, *sp1; + TYP *dhead; + long nbytes; + int func_flag; + int no_append; + nbytes = 0; + decl(table); + dhead = head; + for (;;) { + declid = 0; + bit_width = -1; + decl1(); +#ifdef MID_DECL + if (middle_decl && !declid && lastst==closepa) + return 0; + /* if (middle_decl) + bkpt();*/ +#endif + if (!declid && al == sc_member) + declid = "__unnamed__"; + if (declid != 0) { /* otherwise just struct tag + * or unnamed argument in func prototype... */ + if (head->size == 0 && head->type == bt_pointer + && al == sc_typedef) { + uwarn("typedef with null size"); + } +#ifdef LISTING + if (al==sc_typedef) /* hack to display structs' real names */ + head->sname = declid; +#endif + func_flag = 0; + if (head->type == bt_func && + (lastst == begin || (nparms > 0 && castbegin(lastst)))) { + func_flag = 1; + concat((TABLE *)&lsyms,(TABLE *)head); + } + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+_DECLARE); + sp->name = declid; + sp->storage_class = (al==sc_parms2) ? sc_auto : al; +#ifdef NO_CALLOC + sp->used = 0; +#endif + + if (head->type != bt_func && bit_width > 0 && bit_offset > 0) { + /* + * share the storage word with the previously defined field + */ + nbytes = old_nbytes - ilc; + } + old_nbytes = ilc + nbytes; + while ((ilc + nbytes) % alignment(head)) + nbytes++; + //printf("%s: %d\n",sp->name,al); + if (al==sc_global) {/* don't store value.i (else pb w/ value.splab) */} + else if (al == sc_static) +#ifdef AS + sp->value.splab=0/*nxtglabel()*/;//->this will be done in genstorage() +#else + sp->value.i = nxtglabel(); +#endif + else if (ztype == bt_union) + sp->value.i = ilc; + else if (al != sc_auto) + sp->value.i = ilc + nbytes; + else + sp->value.i = -(ilc + nbytes + head->size); + + /* + * The following code determines possible candidates for register + * variables. Note that 'sp->value.i' could be modified later on, + * but only when auto_init()ing an array/struct/union; and these + * structures are excluded from here (except for arguments to the + * function with type array: they are really pointers). + */ + if (store_lst) + switch (head->type) { + case bt_pointer: + if (head->val_flag && regflag < 3) + break; + /* FALLTHROUGH */ + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + switch (regflag) { + case 1: + case 3: + if (autoptr < AUTO_LIST) + autolst[autoptr++] = sp->value.i; + break; + case 2: + case 4: + if (regptr < REG_LIST) + reglst[regptr++] = sp->value.i; + break; + } + } + + if (bit_width IS_INVALID) { + sp->tp = head; + } else { + sp->tp = (struct typ *) xalloc((int) sizeof(struct typ), + _TYP+_DECLARE); + *(sp->tp) = *head; + sp->tp->type = bt_bitfield; + sp->tp->size = tp_int.size; + sp->tp->bit_width = (char)bit_width; + sp->tp->bit_offset = (char)bit_offset; + } + /* + * The following stuff deals with inconsistencies in the + * C syntax and semantics, namely the scope of locally + * declared functions and its default storage class (extern, + * not auto) etc. + */ + no_append = 0; + /* + * The flag no_append will be set if some stuff is forwarded to the + * global symbol table here and thus should not be repeated in the local + * symbol table + */ + + /* + * extern function definitions with function body are global + */ + if (func_flag && sp->storage_class == sc_external) + sp->storage_class = sc_global; + /* + * global function declarations without function body are external + */ + if (sp->tp->type == bt_func && sp->storage_class == sc_global + && !func_flag) { + sp->storage_class = sc_external; + } + /* + * [auto] int test() is not an auto declaration, it should be + * external + */ + if (sp->tp->type == bt_func && sp->storage_class == sc_auto) { + /* + * althouh the following if-statement is not necessary since + * this check is performed in append() anyway, it saves + * global storage if the functions has previously been + * defined. + */ + if ((sp1 = search(sp->name, -1, &gsyms)) == 0) { + /* put entry in the global symbol table */ + ++global_flag; + sp1 = (struct sym *) xalloc((int) sizeof(struct sym), + _SYM+_DECLARE); + sp1->name = strsave(sp->name); + sp1->storage_class = sc_external; + sp1->tp = save_type(sp->tp); +#ifdef NO_CALLOC + sp1->used = 0; +#endif + append(&sp1, &gsyms); + --global_flag; + } else { + /* already defined in global symbol table */ + if (!eq_type(sp->tp, sp1->tp)) + uerr(ERR_REDECL,sp->name); + } + no_append = 1; + sp = sp1; + } + /* + * static local function declarations should be put in the + * global symbol table to retain the compiler generated + * label number + */ + if (sp->tp->type == bt_func && sp->storage_class == sc_static + && table == &lsyms) { + if (!(sp1 = search(sp->name, -1, &gsyms))) { + /* put it into the global symbol table */ + ++global_flag; + sp1 = (struct sym *) xalloc((int) sizeof(struct sym), + _SYM+_DECLARE); + sp1->name = strsave(sp->name); + sp1->storage_class = sc_static; + sp1->tp = save_type(sp->tp); + sp1->value.i = sp->value.i; +#ifdef NO_CALLOC + sp1->used = 0; +#endif + append(&sp1, &gsyms); + --global_flag; + } else { + if (!eq_type(sp->tp, sp1->tp)) + uerr(ERR_REDECL,sp->name); + } + no_append = 1; + sp = sp1; + } + if (ztype == bt_union) + nbytes = imax(nbytes, sp->tp->size); + else if (al != sc_external) + nbytes += sp->tp->size; + if (!no_append) + if (al == sc_member) + insert(sp, table); + else + append(&sp, table); + if (func_flag) { + /* function body follows */ + int local_nparms = nparms; + ret_type = sp->tp->btp; + if (!global_flag) + error(ERR_SYNTAX); + nparms = 0; + funcbody(sp, names, local_nparms); + return nbytes; + } + if ((al == sc_global || al == sc_static) && + sp->tp->type != bt_func && sp->used IS_VALID) + doinit(sp, alignment(head)); + else if (lastst == assign) { + if (regflag == 1 || regflag == 2) { + long old=sp->tp->size; + getsym(); +#ifdef MID_DECL_IN_EXPR +#error fix needed here... +#endif + {struct enode *bak=init_node; + init_node=NULL; + old-=auto_init(sp->value.i,sp->tp,&sp->tp,0,0,-1); + old-=old&1; + if (old<0) { + struct enode *en=init_node; + sp->value.i+=old; + if (en!=NULL) { + while (en->nodetype!=en_assign) { + struct enode *en2=en/*en_void*/->v.p[1]/*en_assign*/ + ->v.p[0]/*en_ref*/->v.p[0]/*en_autocon/en_add*/; + if (en2->nodetype==en_add) + en2=en2->v.p[0]; + en2->v.i += old; + en=en->v.p[0]; + } + en/*en_assign*/->v.p[0]/*en_ref*/ + ->v.p[0]/*en_autocon*/->v.i += old; + } + nbytes-=old; + } + if (bak) { + if (init_node) + init_node=mk_node(en_void,bak,init_node); + else + init_node=bak; + } + } + } else { + error(ERR_ILLINIT); + doinit(sp, alignment(head)); + } + /* just a small check, it was proposed that I should make it */ + /*if (sp->tp->size == 0 && sp->storage_class != sc_external + && sp->storage_class != sc_typedef + && !(head->type == bt_pointer && head->val_flag) + && regflag < 3) { + uwarn("declaration with null size"); + }*/ + } + } else if (al==sc_parms2) { /* in 'if (declid != 0)' ... */ + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+_DECLARE); + sp->name=""; + sp->tp=head; + append(&sp,table); + } + if (al == sc_parms2 +#ifdef MID_DECL + || middle_decl +#endif + ) return nbytes; + else if (lastst == semicolon) + break; + needpunc(comma); + if (declbegin(lastst) == 0) + break; + head = dhead; + } + getsym(); + return nbytes; +} + +static int declbegin(enum(e_sym) st) { + return (st == star || st == id || st == openpa || + st == openbr || st == colon); +} + +static void declenum(HTABLE *table) { + struct sym *sp; + TYP *tp; + if (lastst == id) { + if ((sp = search(lastid, lastcrc, <ags)) == 0 && + (sp = search(lastid, lastcrc, >ags)) == 0) { + sp = (struct sym *) xalloc((int) sizeof(struct sym), + _SYM+DECLENUM); + if (short_option) + sp->tp = mk_type(bt_ushort, 2); + else + sp->tp = mk_type(bt_ulong, 4); + sp->storage_class = sc_type; + sp->name = strsave(lastid); +#ifdef LISTING + sp->tp->sname = sp->name; +#endif +#ifdef NO_CALLOC + sp->used = 0; +#endif + getsym(); + if (lastst != begin) + error(ERR_INCOMPLETE); + else { + if (global_flag) + append(&sp, >ags); + else + append(&sp, <ags); + getsym(); + enumbody(table); + } + } else getsym(); + head = sp->tp; + } else { + if (short_option) + tp = mk_type(bt_ushort, 2); + else + tp = mk_type(bt_ulong, 4); + if (lastst != begin) + error(ERR_INCOMPLETE); + else { + getsym(); + enumbody(table); + } + head = tp; + } +} + +static void enumbody(HTABLE *table) { + long evalue; + struct sym *sp; + evalue = 0; + while (lastst == id) { + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+ENUMBODY); + sp->value.i = evalue++; + sp->name = strsave(lastid); + sp->storage_class = sc_const; + sp->tp = (TYP *)&tp_econst; + append(&sp, table); + getsym(); + if (lastst == assign) { + getsym(); + evalue = sp->value.i = intexpr(); + evalue++; + } + if (short_option && (sp->value.i < -32768 || sp->value.i > /*32767*/65535)) + error(ERR_ENUMVAL); + if (lastst == comma) + getsym(); + else if (lastst != end) + break; + } + needpunc(end); +} + +static void declstruct(enum(e_bt) ztype) { +/* + * declare a structure or union type. ztype should be either bt_struct or + * bt_union. + * + * References to structures/unions not yet declared are allowed now. The + * declaration has to be done before the structure is used the first time + */ + struct sym *sp; + TYP *tp; + if (lastst == id) { + if ((sp = search(lastid, lastcrc, <ags)) == 0 && + (sp = search(lastid, lastcrc, >ags)) == 0) { + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+DECLSTRUCT); + sp->name = strsave(lastid); + sp->tp = mk_type(ztype, 0); + sp->storage_class = sc_type; +#ifdef LISTING + sp->tp->sname = sp->name; +#endif + if (global_flag) + append(&sp, >ags); + else + append(&sp, <ags); + } + if (sp->tp->lst.head != 0) + getsym(); + else { + getsym(); + /* allow, e.g. struct x *p; before x is defined */ + if (lastst == begin) { + getsym(); + structbody(sp->tp, ztype); + } + } + head = sp->tp; + } else { + tp = mk_type(ztype, 0); + if (lastst != begin) + error(ERR_INCOMPLETE); + else { + getsym(); + structbody(tp, ztype); + } + head = tp; + } +} + +static void structbody(TYP *tp, enum(e_bt) ztype) { + long slc; + slc = 0; + bit_next = 0; + while (lastst != end) { + if (ztype == bt_struct) + slc += declare((HTABLE *)&(tp->lst), sc_member, slc, ztype, -1); + else + slc = imax(slc, declare((HTABLE *)&tp->lst, sc_member, 0l, ztype, -2)); + } + /* + * consider alignment of structs in arrays... + */ +#if AL_DEFAULT==2 + slc+=(slc&1); +#else + if (slc % AL_DEFAULT != 0) + slc += AL_DEFAULT - (slc % AL_DEFAULT); +#endif + tp->size = slc; + getsym(); + bit_next = 0; +} + +extern char linein[LINE_LENGTH]; +extern char *lptr; +#ifdef VCG +extern int vcg_lvl; +#endif +static int nologo=0; +void compile(void) { +/* + * main compiler routine. this routine parses all of the declarations using + * declare which will call funcbody as functions are encountered. + */ +#ifdef VERBOSE + time_t ltime; +#endif + + debugcls(); +#ifdef PC + if (!verbose) + nologo=1; +#endif + if (!nologo) +#ifdef PC + msg( + " --- GTC C compiler --- \n\n" + " 2001-2004 by Paul Froissart\n\n"),nologo++; +#else +#ifndef GTDEV + msg("GTC compiler - 2001-2004\n by Paul Froissart\n"),nologo++; +#endif +#endif + +#ifdef VERBOSE + times(&tms_buf); + ltime = tms_buf.tms_utime; +#endif + + strtab = 0; + lc_bss = 0; + debug('1'); + hashinit(&gsyms); + hashinit(>ags); + hashinit(&lsyms); + hashinit(<ags); + hashinit(&labsyms); + debug('6'); + nextlabel = 1; + store_lst = 1; + asm_flag = 0; + asm_xflag = 0; + asm_zflag = 0; + nparms = 0; + func_sp = NULL; +#ifdef DUAL_STACK + { + // create a 16-byte 'leak' (which will be freed in rel_global(), though) + // to avoid perpetual malloc()/free() of the dualstack + ds_ensure(16); + { + char *ptr = ds_var(char *); + ds_update(ptr+16); + } + } +#endif +#ifdef VCG + vcg_lvl=VCG_MAX; +#endif + getch(); + getsym(); + debug('7'); + while (lastst != eof) { + extern int got_sym; + got_sym = 0; + dodecl(sc_global); +#if 0 + if (lastst != eof) /* what the heck is this??? am I doing a mistake */ + getsym(); /* when I disable it? how come I find it only now? */ +#elif 1 /* UPDATE : the former seems to be a (missed) fix for the infinite loop * + * when a particular kind of syntax error occurred. This is now fixed. */ + if (!got_sym) + uerr(ERR_SYNTAX); +#endif + } +#ifdef VERBOSE + times(&tms_buf); + decl_time += tms_buf.tms_utime - ltime; +#endif + debug('8'); + dumplits(); + debug('9'); +} + +#ifdef VCG +extern struct ocode *vcg_peep_head[]; +#endif +void dodecl(enum(e_sc) defclass) { + long slc = 0; + struct sym *sp; + int regflag; + for (;;) { + regflag = 1; + switch (lastst) { + case kw_register: + regflag = 2; + getsym(); + if (defclass != sc_auto && defclass != sc_parms) + error(ERR_ILLCLASS); + goto do_decl; + case kw_auto: + getsym(); + if (defclass != sc_auto) + error(ERR_ILLCLASS); + goto do_decl; + case kw_asm: + if (!global_flag) /* more secure than 'if (defclass != sc_global)' ? */ + return; // so that while (x) { asm(...); ... } + getsym(); // works (as in-line asm) +#ifdef ASM + if (lastst != begin) { +#endif + #ifndef AS + if (lastst != openpa) + #endif + error(ERR_SYNTAX); + #ifndef AS + else { + getsym(); + if (lastst != sconst) + error(ERR_SYNTAX); + put_code(_op_asm,0,(struct amode *)strsave(laststr),NIL_AMODE); + getsym(); + needpunc(closepa); + needpunc(semicolon); + } + #endif +#ifdef ASM + } else { + int glob = global_flag; + #ifdef AS + struct ocode *sh = scope_head; + int nextlab = nextlabel; + #endif + global_flag = 0; +#ifdef PCH + push_local_mem_ctx(); /* because global_flag=0 is possible inside + * a function */ +#endif + #ifdef AS + put_align2(); + scope_head = 0; + scope_init(); + #endif + asm_flag++; + asm_head = 0; + asm_getsym(); + while (getasm_main()); + asm_flag--; + needpunc(end); + needpunc(semicolon); + if (strtab) + dumplits(); + #ifdef AS + scope_head = asm_head; + scope_flush(); + nextlabel = nextlab; + scope_head = sh; + local_clean(); + #else + #ifdef VCG + vcg_peep_head[vcg_lvl] = asm_head; + #else + peep_head = asm_head; + #endif + flush_peep(); + #endif +#ifdef PCH + pop_local_mem_ctx(); +#else + rel_local(); /* release local symbols */ +#endif + global_flag = glob; + } +#endif + break; + case id: + /* + * If it is a typedef identifier, do the declaration. + */ + if ((sp = lastsp) != 0 && sp->storage_class == sc_typedef) + goto do_decl; + /* else fall through */ + /* + * If defclass == sc_global (we are outside any function), almost + * anything can start a declaration, look, e.g. mined: + * (*escfunc(c))() ,,almost anything'' is not exact: id (no + * typedef id), star, or openpa. + */ + case openpa: + case star: + if (defclass == sc_global) + goto do_decl; + return; + /* else fall through to declare */ + case kw_char: + case kw_short: + case kw_unsigned: + case kw_long: + case kw_struct: + case kw_union: + case kw_enum: + case kw_void: + case kw_float: + case kw_double: + case kw_int: + case kw_typeof: + case kw_attr: + case kw_signed: case kw_const: case kw_volatile: +do_decl: + if (defclass == sc_global) + (void) declare(&gsyms, sc_global, 0l, bt_struct, 0); + else if (defclass == sc_auto) + lc_auto += + declare(&lsyms, sc_auto, lc_auto, bt_struct, regflag); + else /* defclass == sc_parms (parameter decl.) */ + slc += + declare(&lsyms, sc_auto, slc, bt_struct, regflag + 2); + break; + case kw_static: + getsym(); + if (defclass == sc_member) + error(ERR_ILLCLASS); + if (defclass == sc_auto) + (void) declare(&lsyms, sc_static, 0l, bt_struct, 0); + else + (void) declare(&gsyms, sc_static, 0l, bt_struct, 0); + break; + case kw_typedef: + getsym(); + if (defclass == sc_member) + error(ERR_ILLCLASS); + if (defclass == sc_auto) + (void) declare(&lsyms, sc_typedef, 0l, bt_struct, 0); + else + (void) declare(&gsyms, sc_typedef, 0l, bt_struct, 0); + break; + case kw_extern: + getsym(); + if (defclass == sc_member) + error(ERR_ILLCLASS); + if (defclass == sc_auto) + (void) declare(&lsyms, sc_external, 0l, bt_struct, 0); + else + (void) declare(&gsyms, sc_external, 0l, bt_struct, 0); + break; + default: + return; + } + } +} + +int eq_type(TYP *tp1, TYP *tp2) { +/* + * This is used to tell valid from invalid redeclarations + */ + if (tp1 == 0 || tp2 == 0) + return 0; + + if (tp1 == tp2) + return 1; + + if (tp1->type != tp2->type) + return 0; + + if (tp1->type == bt_pointer) + return eq_type(tp1->btp, tp2->btp); + if (tp1->type == bt_func) { + SYM *sp=tp1->lst.head,*sp2=tp2->lst.head; + if (!sp || !sp2) // one is only a prototype : OK + return eq_type(tp1->btp, tp2->btp); + while (sp && sp2) { + /* + * in vararg funcs we can have sp->tp==sp2->tp==NULL, but + * eq_type(NULL,NULL) is 0 hence the first check + */ + if (sp->tp!=sp2->tp && !eq_type(sp->tp,sp2->tp)) + return 0; + sp=sp->next; sp2=sp2->next; + } + if (sp || sp2) return 0; // != # of args + return eq_type(tp1->btp, tp2->btp); + } + if (tp1->type == bt_struct || tp1->type == bt_union) + return (tp1->lst.head == tp2->lst.head); + + return 1; +} + +int indir_num(TYP *tp) { + int n=0; + while (tp->type == bt_pointer || tp->type == bt_func) { + n++; + tp=tp->btp; + } + return n; +} + +static TYP *save_type(TYP *tp) { + TYP *ret_tp; +/* the type structure referenced by tp may be in local tables. + Copy it to global tables and return a pointer to it. + */ + if (tp->st_flag) + return tp; + ++global_flag; + ret_tp = (TYP *) xalloc((int) sizeof(TYP), _TYP+SV_TYPE); + +/* copy TYP structure */ + *ret_tp = *tp; + ret_tp->st_flag = 1; + + if (tp->type == bt_func || tp->type == bt_pointer) + ret_tp->btp = save_type(tp->btp); + + if (tp->type == bt_struct || tp->type == bt_union) { + /* + * It consumes very much memory to duplicate the symbol table, so we + * don't do it. I think we needn't do it if it is in local tables, so + * this warning is perhaps meaningless. + */ +// uwarn("didn't copy local struct/union in save_type"); + ret_tp->lst.tail = ret_tp->lst.head = 0; ret_tp->lst.hash = 0; + } + --global_flag; + return ret_tp; +} +// vim:ts=4:sw=4 diff --git a/gtc/src/define.h b/gtc/src/define.h new file mode 100644 index 0000000..7dc9691 --- /dev/null +++ b/gtc/src/define.h @@ -0,0 +1,378 @@ +/* + * GTools C compiler + * ================= + * source file : + * #define's + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +//#define SHOWSTEP + +#ifndef DEFINE_H +#define DEFINE_H +#if 0 + #ifdef PC + #define debugcls() (void)0 + #define debugf printf + #else + #define debugcls clrscr + extern int progr; + #define debugf(f...) (printf(f),progr_process(func_sp?func_sp->name:0,curname,progr),ngetchx()) + #endif + #define debugfq printf +#else + #define debugcls() (void)0 + #if defined(PC) && !defined(__GNUC__) + /*@unused@*/ static void debugf(char *s,...) {} + /*@unused@*/ static void debugfq(char *s,...) {} + #else + #define debugf(f...) (void)0 + #define debugfq(f...) (void)0 + #endif +#endif +#if !defined(PC) || !defined(DEBUGGING) +#define enum(tp) unsigned int // some compilers make enums signed, make them happy +#else +#define enum(tp) enum tp // we want nice debugging output +#endif +#define IS_VALID >=0 +#define IS_INVALID <0 +#define nxtlabel() (short)(nextlabel++) +#ifdef AS + #define nxtglabel() (short)(glblabel++) +#else + #define nxtglabel() (short)(nextlabel++) +#endif +#define local(__l) (__l>=0) +#define global(__l) (((unsigned short)__l)<0xC000) // only valid if !local(__l) +#define external(__l) (((unsigned short)__l)>=0xC000) +#ifdef PC +#define splbl(__sp) (__sp->value.splab?__sp->value.splab:(__sp->value.splab=label(__sp->name))) +#else +#define splbl(__sp) (__sp->value.splab?:(__sp->value.splab=label(__sp->name))) +#endif +#ifdef PC +#define TWIN_COMPILE +#endif +#define DUAL_STACK // save space on the stack by allocating on a temporary buffer just the size we need +#ifdef PC +#define OBJ_OUT +#endif + +//#define INFINITE_REGISTERS // compile for a virtual machine with an arbitrarily high number of registers +#ifdef DISABLE_OPTS +#undef VCG +#endif +#define USE_WORDS_IN_SWITCH // use dc.w instead of dc.l in 'real' switch statements +#define NEW_ATTR // allows TI-GCC-like attribute declaration +#ifdef PC +#ifndef DISABLE_OPTS +#define ADV_OPT // is it worth the extra exe size & comp time ? => disabled on-calc +#endif +#endif +#ifdef VCG +#define GENERATE_ROL_ROR // optimize (x<<12)|(x>>4) into a ror; depends on VCG because commutativity is not tested +#endif +//#define NO_ICONST_SCAN +//#define ALTERNATE_HOOK +#define OPT_ROMCALLS // assumes that *(void **)0xC8 is never modified +//#define DEFAULT_STKPARM +#define TWOBYTE_ARRAY_EXTRA_OPT // {add.w d3,a0;add.w d3,a0} instead of + // {move.w d3,d0;add.w d0,d0;add.w d0,a0} +//#define AREG_AS_DREG // some fine-tune should be done before this switch provides any benefit +#define PREFER_POS_VALUES // allows for better CSE collection (seems like there's a bug in + // Optimize which is fixed or reduced by this switch too...) +#define ADVANCED_TEMP_REGS // to be fit one day in Gen68k in order to optimize free temp regs +#if 0 +#define ADVANCED_MEMORY_MOVE // optimize contiguous sequences of move's (< auto_init/g_fcall) + // (rather time-consuming, for very low consequences... + // => disabled, even on PC) +#endif +#ifdef PC // only valid on PC! +#define REQ_MGT // enable required files management +#endif +#define MULTIFILE // enable multiple file support +#define OPTIMIZED_AINCDEC_TEST // allows for dbf too +#define LONG_ADDS_IN_AREG // so that lea can be used rather than addi.l +//#define NO_OFFSET_AUTOCON // useless as of now +#define ADD_REDUNDANCY // increases compression ratios at the cost of function-overhead speed +#define REGALLOC_FOR_SIZE +//#define HARDCORE_FOR_UNPACKED_SIZE // favour size wherever possible, with little improvement + // of packed size and even more probably regression (lsl.w #2...) +#define SPEED_OPT +//#define speed_opt_value 1 // we may add n instruction before the bra (1 : useful for dbf) +//#define G_CAST2 // this might remove some op_ext's : to be tested +#define RAM_CALLS // support for RAM_CALLs +#ifdef PC +#define FLINE_RC // support for F-Line ROM_CALLs +#endif +#define SHORT_STRUCT_PASSING // allows HSym to be defined as a structure +#ifdef PC +#define EXE_OUT // output an EXE program (implementation incomplete) +#endif +#define NO_SECURE_POINTERS // assert that all array accesses are less than 32kb +//#define POP_OPT // still buggy as of now +#define NO_TRIVIAL_CASTS // suppresses trivial en_cast's ; might add bugs, but not certain +#define NO_VERYTRIVIAL_CASTS // suppresses obvious en_cast's ; was already there, but possibly buggy +#define MID_DECL // allows for powerful middle decl handler +#define MINIMAL_SIZES // so that (long)x>>(char)y won't be converted to (long)x>>(long)y +//#define USE_SWAP_FOR_SHIFT16 // use op_swap wherever possible for shifts (buggy, FIXME) +#define AUTOINIT_PAD // pad auto_init statements ('side' requires this, for example) +#define MACRO_PPDIR +#define MEXP_SUPPORTS_PCH // this is mandatory for TiGccLib's RR_* support. + // The way speed is affected I don't know, but perhaps it's + // faster with this option enabled... (slightly more PCH + // searches, very slightly fewer HTable searches) + // Some tests should be performed about this. +// TODO: +// - add FAVOUR_RELATIVE_BSS directive so that once a BSS is CSE'd, all other BSS +// refer to it rather than to the classical BSS (what's more, CSE::scan should favour +// such optimizations by doing some sort of most_used_BSS_cse->desire += (other_BSS_cse's)>>1) +// This would allow for intensive use of BSS :) +// - add RELATIVE_CSE directive so that when constantly using mylib__0000+2, +// CSE searches for all mylib__0000 occurrences and finds out that it's better to use +// mylib__0000+2 (replacing should take this into a count) +// -- but complicated and not *that* useful... +#if !defined(NONSTD_MACRO_CONCAT) && !defined(NONSTD_MACRO_CONCAT_V2) +#define STD_MACRO_CONCAT +#endif +#define EXT_AS_ID // enabled since the dirty getch() management of .b/.w/.l is no more necessary +#if defined(NOFLOAT) || !defined(BCDFLT) +#define NOBCDFLT +#endif +#ifndef AS +#ifdef AS92p +#define FORBID_TABLES +#endif +#endif +#define push_local_mem_ctx() { int _locsize=locsize,_locindx=locindx; \ + struct blk *_locblk=locblk; locblk=0; locsize=0 +#define pop_local_mem_ctx() rel_local(); locsize=_locsize; locindx=_locindx; locblk=_locblk; } +#define put_align(__a) put_align2() +#ifdef VCG +#define VCG_MAX 5 +#endif +#ifdef EXE_OUT +#ifdef PC +//#ifndef _DEBUG +#define SIZE_STATS // include statistics to determine the part of code generated from C code +//#endif +#endif +#endif +#ifdef FLASH_VERSION +#define HAS_CMDLINE_EXTENSION +#endif +#ifdef BIGSTACK + #define XLST_TYPE long + #define REG_PARAMS 0xF000 + #define REG_PARAMLOG 12 +#else + #define XLST_TYPE int + /* limits the param size to 2 kb - not much of a problem ;) */ + #define REG_PARAMS 0x7800 + #define REG_PARAMLOG 11 +#endif +#ifndef HAS_TI_SHORT +#ifdef PC +typedef struct { + unsigned char x0,x1,x2,x3; +} TI_LONG; +typedef struct { + unsigned char hi,lo; +} TI_SHORT; +#else +typedef unsigned long TI_LONG; +typedef unsigned short TI_SHORT; +#endif +#ifdef PC +extern unsigned long _w2ul(TI_LONG *p); +extern unsigned short _w2us(TI_SHORT *p); +#define w2ul(x) _w2ul(&(x)) +#define w2us(x) _w2us(&(x)) +#else +#define w2ul(x) (x) +#define w2us(x) (x) +#endif +#endif +#ifndef NOFLOAT +#ifndef PC +#ifndef BCDFLT +#define double long +#endif +#endif +#endif +#ifndef NOBCDFLT +#define BCDLEN 8 +typedef struct bcd { + unsigned short exponent; + unsigned char mantissa[BCDLEN]; +} BCD; +#endif +#ifdef PC + #define infunc(f) if (!strcmp(func_sp->name,f)) + #define bkpt() printf("") + #define DB_POSSIBLE + #define DEBUG 1 + #ifdef SHORT_INT + #define int short + #endif + #ifdef CMAIN_C + long alloc[3][0xE000]; + #else + extern long alloc[][0xE000]; + #endif + enum myEnum { + ANONYMOUS=0, COPYNODE=1, ENTERNODE=2, STRINGLIT=3, LITLATE=4, + STRSAVE=5, MK_TYPE=6, _DECLARE=7, DECLENUM=8, ENUMBODY=9, + DECLSTRUCT=0xA, SV_TYPE=0xB, MK_NODE=0xC, MK_ICON=0xD, + NAMEREF=0xE, FUNCBODY=0xF, MK_INT=0x10, MK_SCRATCH=0x11, + MK_LABEL=0x12, MK_IMMED=0x13, MK_OFFSET=0x14, COPY_ADDR=0x15, + G_DEREF=0x16, G_EXPR=0x17, MK_REG=0x18, MK_MASK=0x19, + MK_STRLAB=0x1A, GENLOOP=0x1B, G_CODE=0x1C, G_LABEL=0x1D, + DODEFINE=0x1E, G_PUSH=0x1F, TEMP_DATA=0x20, TEMP_ADDR=0x21, + SYMBOL=0x22, REF_ADD=0x23, LAB_ADD_REF=0x24, RT_ADD_REF=0x25, + ENODE=0x1000, CSE=0x2000, SLIT=0x3000, STR=0x4000, _TYP=0x5000, + _SYM=0x6000, AMODE=0x7000, OCODE=0x8000, _TABLE=0x9000, + SNODE=0xA000, _TAB=0xB000, _REF=0xC000, _RT=0xD000, + }; + #define xalloc(s,c) (alloc[temp_mem?2:!!global_flag][(c)]+=(s)+((s)&1),_xalloc(((s)+3)&-4)) + #define _FILE(x) + #define dseg() while (0) + #define cseg() while (0) + #define compound_done getsym + #ifdef _MSC_VER + #pragma warning (disable : 4033 4013 4716 4715 4133) + #pragma warning (disable : 4996) // strcpy/fopen/... are declared deprecated in VC++ 2005 :D + #ifdef SHORT_INT + #pragma warning (disable : 4305 4244 4761) + #endif + #endif + #ifdef SHORT_INT + #undef int + #endif + #define debug(x) ((void)0) + #include + #include + #include + #include + #include + #ifndef _MSC_VER + #ifndef __MINGW32__ + #include + #else + #include + #endif + #else + #define alloca _alloca + #endif + #ifdef SHORT_INT + #define int short + #endif + #ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) + #endif + #define getline getline_gtc + typedef size_t short_size; +#else + #define infunc(f) if (0) + #define bkpt() {} + #define DB_POSSIBLE + #define DEBUG 0 + #define xalloc(__s,__c) _xalloc(__s+(__s&1)) + //#define _FILE(x) asm(".ascii \""x"\";.even"); + #define _FILE(__x) + #define cached_sym (int)_cached_sym + #define AS92p + #ifndef CMAIN_C + #define NOSTUB + #define _rom_call(type,args,ind) (*(type(**)args)(*(long*)0xC8+0x##ind*4)) + #else + #include "lib_map.h" + #define USE_KERNEL + //#define USE_FULL_LONGMUL_PATCH + //#define USE_FULL_LONGDIV_PATCH + int _ti89; + #endif + #ifndef gtc_compiled + #include + #else + #define FILE void + #define NULL (void *)0 + #endif + #undef off + //#define stkparm + #ifndef FLASH_VERSION + #define debug(x) ((void)0) + #undef clrscr + #define clrscr gtcrt__0000 + #undef printf + #define printf gtcrt__0001 + #undef vcbprintf + #define vcbprintf gtcrt__0002 + #undef fopen + #define fopen gtcrt__0008 + FILE *fopen(const char *,const char *); + #undef fclose + #define fclose gtcrt__0009 + #undef fputc + #define fputc gtcrt__000a + int fputc(int,FILE *); + #undef fgetc + #define fgetc gtcrt__000b + #undef fwrite + #define fwrite gtcrt__000c + int fwrite(void *,int,int,FILE *); + #undef fputs + #define fputs gtcrt__0010 + #undef fgets + #define fgets gtcrt__0011 + char *fgets(char *,int,FILE *); + #undef fprintf + #define fprintf gtcrt__0014 + #else + #define debug(x) ((void)0) // for flash ver + #undef fclose + #define fclose my_fclose // fix buggy fclose + void my_fclose(FILE *f); + #define OPTIMIZE_BSS + #define BSS_SIZE 8192 + #endif /* FLASH_VERSION */ + + typedef short short_size; + + //#undef printf + //#undef fputchar + //#define printf print + //#define printf(f...) (((void(*)(void*,char*,...))prtf)(fputchar,##f)) + //#define fputchar ((short(*)(char))ptch) +#endif +#ifndef FLASH_VERSION + #define CGLOB =0 + #define CGLOBL ={0} + #define xstatic static + #define readonly +#else + #define CGLOB + #define CGLOBL + #define xstatic + #define readonly const +#endif + +#include "protos.h" +#ifndef nl + void nl(void); +#endif +#ifndef PC +char *__attribute__((stkparm)) sUnpack(char *in,char *out,char *dic); +#else +char *sUnpack(char *in,char *out,char *dic); +#endif +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/error.c b/gtc/src/error.c new file mode 100644 index 0000000..a156356 --- /dev/null +++ b/gtc/src/error.c @@ -0,0 +1,150 @@ +/* + * GTools C compiler + * ================= + * source file : + * error handling + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +/*#include "define.h" +#include "c.h" +#include "cglbdec.h"*/ +#include +#include + +extern int pause_on_error; + +#ifndef GTDEV +//#ifdef PC +void _err_attr err_int(int m) { + clean_up(); + msg2("\nAn internal error occurred (error ID #%04d)\n" + "Please report this bug to paul.froissart@libertysurf.fr\n",m); +#ifdef PC + fflush(outstr); + if (pause_on_error) + getchar(); + exit(16); +#else + ngetchx(); + exit(0); +#endif +} +void err_usr(int m,...) { + va_list args; + va_start(args,m); +#ifdef PC + if (verbose) +#endif + msg("\nCompilation error:\n"); + if (err_force_line IS_INVALID && err_assembly) + err_force_line=err_cur_line; + locate(); + if (m==ERR_OTH) { + char *s=va_arg(args,char *); + vmsg(s,args); + } else + vmsg((char *)__err[m],args); + msg("\n"); + va_end(args); + clean_up(); +#ifdef PC + fflush(outstr); + if (pause_on_error) + getchar(); + exit(16); +#else + ngetchx(); + exit(0); +#endif +} +void _err_attr warn_int(int m) { + msg2("\nAn unexpected event occurred (event ID #%04d)\n" + "It might be possible to continue, but the generated code may " + "contain bugs.\nDo you want to continue [y/n]?",m); +#ifdef PC + fflush(outstr); + if ((pause_on_error && (msg("\nn\n"),1)) || getchar()=='n') { + clean_up(); + exit(16); + } + msg("\n"); +#else + while (!kbhit()); + if (ngetchx()=='n') { + clean_up(); + exit(0); + } else msg("\n"); +#endif +} +void warn_usr(char *s,...) { + va_list args; + va_start(args,s); + locate(); + msg("warning: "); + vmsg(s,args); + msg("\n"); + va_end(args); +} +//#endif +#else +void _err_attr error_do(char *msg,int type) { + char _func[100],file[40]; + char *func=0; + int line,chr=0; + if (func_sp) strcpy(func=_func,func_sp->name); + strcpy(file,curname); + if (err_force_line IS_INVALID && err_assembly) + err_force_line=err_cur_line; + if (err_force_line IS_VALID) + line=err_force_line; + else line=lineno,chr=0/*to be improved*/; + if (et_iserror(type)) + clean_up(); + msg_process(msg,type,func,file,line,chr); + if (et_iserror(type)) + exit(0); +} +void _noreturn assert_terminated(); +asm("assert_terminated:\n rts\n"); +void _err_attr err_int(int m) { + char b[30]; + sprintf(b,"error ID #%04d",m); + error_do(b,ET_INTERNAL_FAILURE); + assert_terminated(); +} +void err_usr(int m,...) { + va_list args; + va_start(args,m); + char b[200]; + if (m==ERR_OTH) { + char *s=va_arg(args,char *); + vsprintf(b,s,args); + } else + vsprintf(b,(char *)__err[m],args); + va_end(args); + error_do(b,ET_ERROR); + assert_terminated(); +} +void _err_attr warn_int(int m) { + char b[30]; + sprintf(b,"event ID #%04d",m); + error_do(b,ET_INTERNAL_WARNING); +} +void warn_usr(char *s,...) { + va_list args; + va_start(args,s); + char b[200]; + vsprintf(b,s,args); + va_end(args); + error_do(b,ET_WARNING); +} +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/error.h b/gtc/src/error.h new file mode 100644 index 0000000..3846bb7 --- /dev/null +++ b/gtc/src/error.h @@ -0,0 +1,58 @@ +/* + * GTools C compiler + * ================= + * source file : + * error handling + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define error(x) uerr(x) +#define ierr(f,n) err_int(((FUNC_##f)<<8)+n) +#define uerr err_usr +#define uerrc(m) uerr(ERR_OTH,m) +#define uerrc2(m,a) uerr(ERR_OTH,m,a) +#define uerrc3(m,a,b) uerr(ERR_OTH,m,a,b) +#define uerrsys(m) uerr(ERR_SYS,m) +#define iwarn(f,n) warn_int(((FUNC_##f)<<8)+n) +#define uwarn warn_usr + +#ifdef PC +#define _noreturn +#define _err_attr +#else +#define _noreturn __attribute__((noreturn)) +#define _err_attr +//#define _err_attr __attribute__((regparm(1))) +#endif + +void _noreturn fatal(char *message); +void _noreturn _err_attr err_int(int e); +void _noreturn err_usr(int e,...); +void _err_attr warn_int(int w); +void warn_usr(char *w,...); + +// rules for adding new items : add them *ALWAYS* at the end +enum { + FUNC_NONE=0, + +/*$01*/ FUNC_ALIGNMENT, FUNC_MK_LEGAL, FUNC_COPY_ADDR, FUNC_G_DEREF, FUNC_G_UNARY, +/*$06*/ FUNC_G_ADDSUB, FUNC_G_DIV, FUNC_G_MOD, FUNC_G_MUL, FUNC_G_HOOK, FUNC_G_ASADD, +/*$0C*/ FUNC_G_ASXOR, FUNC_G_ASSHIFT, FUNC_G_ASMUL, FUNC_G_ASDIV, FUNC_G_ASMOD, FUNC_G_AINCDEC, +/*$12*/ FUNC_G_PARMS, FUNC_REGPARM, FUNC_FUNC_RESULT, FUNC_G_CAST, FUNC_G_EXPR, FUNC_G_COMPARE, +/*$18*/ FUNC_TRUEJP, FUNC_FALSEJP, FUNC_GENLOOP, FUNC_GENRETURN, FUNC_GENSTMT, FUNC_ADD_CODE, +/*$1E*/ FUNC_ASM_GETSYM, FUNC_LISTING, FUNC_OPT0, FUNC_PASS3, FUNC_UNINIT_TEMP, __FUNC_UNUSED1, +/*$24*/ FUNC_G_CODE, FUNC_PEEP_DELETE, FUNC_G_PUSH, FUNC_G_POP, FUNC_CHECKSTACK, FUNC_TEMP_DATA, +/*$2A*/ FUNC_TEMP_ADDR, FUNC_FREEOP, FUNC_DOOPER, FUNC_PEEP_LABEL, FUNC_BBLK_INIT, + +/*$2F*/ FUNC_LINK_MISPL, FUNC_TABLE_HASH, +/*$31*/ FUNC_WARN_LC_STK, + +}; +// vim:ts=4:sw=4 diff --git a/gtc/src/expr.c b/gtc/src/expr.c new file mode 100644 index 0000000..44a07e3 --- /dev/null +++ b/gtc/src/expr.c @@ -0,0 +1,2157 @@ +/* + * GTools C compiler + * ================= + * source file : + * expressions + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define DECLARE +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifndef NOFLOAT +#include "ffplib.h" +#endif +#ifdef PC +#ifdef SHORT_INT +#undef int +#endif +#include +#ifdef SHORT_INT +#define int short +#endif +#else +#include "define.h" +#endif + +long inittype(); + +unsigned char sizeof_flag CGLOB; +unsigned char id_are_zero CGLOB; +#ifdef MID_DECL_IN_EXPR +struct enode *md_expr CGLOB; +struct typ *md_type CGLOB; +#endif +/* + * expression evaluation + * + * this set of routines builds a parse tree for an expression. no code is + * generated for the expressions during the build, this is the job of the + * codegen module. for most purposes expression() is the routine to call. it + * will allow all of the C operators. for the case where the comma operator + * is not valid (function parameters for instance) call exprnc(). + * + * each of the routines returns a pointer to a describing type structure. each + * routine also takes one parameter which is a pointer to an expression node + * by reference (address of pointer). the completed expression is returned in + * this pointer. all routines return either a pointer to a valid type or NULL + * if the hierarchy of the next operator is too low or the next symbol is not + * part of an expression. + */ + +static TYP *primary(); +static TYP *unary(); +static TYP *multops(); +static TYP *addops(); +#ifndef isscalar +static int isscalar(); +#endif +TYP *force_cast_op(); + +int not_lvalue(struct enode *node) { + while (node->nodetype==en_cast) node=node->v.p[0]; + return node->nodetype-en_ref; +} + +struct enode *mk_node(enum(e_node) nt, struct enode *v1, struct enode *v2) { +/* + * build an expression node with a node type of nt and values v1 and v2. + */ + struct enode *ep; + ep = (struct enode *) xalloc((int) sizeof(struct enode), ENODE+MK_NODE); + ep->nodetype = nt; + ep->etype = bt_void; + ep->esize = -1; + ep->v.p[0] = v1; + ep->v.p[1] = v2; + return ep; +} + +struct enode *mk_icon(long i) { +/* + * build an expression node forming an integer constant + */ + struct enode *ep; +/* if (i==0x4E0003) + __HALT;*/ +/* if (global_flag && !temp_mem) + printf("gfdiog");*/ +// ep = (struct enode *) xalloc((int) sizeof(struct enode), ENODE+MK_ICON); + ep = (struct enode *) xalloc((int) sizeof(struct xcon), ENODE+MK_ICON); + ep->nodetype = en_icon; + ep->etype = bt_void; +#ifdef NO_CALLOC + ep->esize = 0; +#endif + ep->v.i = i; + return ep; +} + +TYP *deref(struct enode **node, TYP *tp) { +/* + * build the proper dereference operation for a node using the type pointer + * tp. + */ + switch (tp->type) { + case bt_void: + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + case bt_long: + case bt_pointer: + case bt_ulong: + case bt_struct: + case bt_union: + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + *node = mk_node(en_ref, *node, NIL_ENODE); + (*node)->etype = tp->type; + (*node)->esize = tp->size; + break; + case bt_bitfield: + *node = mk_node(en_fieldref, *node, NIL_ENODE); + (*node)->bit_width = tp->bit_width; + (*node)->bit_offset = tp->bit_offset; + /* + * maybe it should be 'unsigned' + */ + (*node)->etype = tp_int.type; + (*node)->esize = tp_int.size; + tp = (TYP *)&tp_int; + break; + default: + error(ERR_DEREF); + break; + } + return tp; +} + +TYP *cond_deref(struct enode **node, TYP *tp) { + TYP *tp1; + /* + * dereference the node if val_flag is zero. If val_flag is non_zero and + * tp->type is bt_pointer (array reference), set the size field to the + * pointer size (if this code is not executed on behalf of a sizeof + * operator) + */ + +/* infunc("chk_curword") + bkpt();*/ + if (tp->val_flag == 0) + return deref(node, tp); + if (tp->type == bt_pointer && sizeof_flag == 0) { + tp1 = tp->btp; + tp = mk_type(bt_pointer, 4); + tp->btp = tp1; + } + return tp; +} + +TYP *nameref(struct enode **node) { +/* + * nameref will build an expression tree that references an identifier. if + * the identifier is not in the global or local symbol table then a + * look-ahead to the next character is done and if it indicates a function + * call the identifier is coerced to an external function name. non-value + * references generate an additional level of indirection. + */ + struct sym *sp; + TYP *tp; + sp = lastsp; + if (sp == 0) { + getcache(id); + if (cached_sym == openpa && !cached_flag) { + uwarn("function '%s' not defined; assuming extern returning int", lastid); + ++global_flag; + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+NAMEREF); + sp->tp = (TYP *)&tp_func; + sp->name = strsave(lastid); + sp->storage_class = sc_external; + append(&sp, &gsyms); + --global_flag; + tp = (TYP *)&tp_func; + *node = mk_node(en_nacon, NIL_ENODE, NIL_ENODE); + (*node)->v.ensp = sp->name; +#ifdef AS + (*node)->v.enlab = splbl(sp); +#endif + sp->used = 1; + (*node)->etype = bt_pointer; + (*node)->esize = 4; + if (asm_zflag) (*node)->etype = bt_ulong; + } else { + if (lastid[0]=='_' && lastid[1]=='R' && !strncmp(lastid+3,"M_CALL_",7)) { + ++global_flag; + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+NAMEREF); + sp->tp = (TYP *)&tp_void_ptr; + sp->name = strsave(lastid); + sp->storage_class = sc_external; + append(&sp, &gsyms); + --global_flag; + goto ok_sp; + } else { + if (!asm_xflag) { + tp = 0; + uerr(ERR_UNDEFINED,lastid); + } else { + tp = (TYP *)&tp_ulong; + *node = mk_node(en_nacon, NIL_ENODE, NIL_ENODE); + (*node)->v.ensp = strsave(lastid); + #ifdef AS + (*node)->v.enlab = label(lastid); + #endif + (*node)->etype = bt_ulong; + (*node)->esize = 4; + } + } + } + } else { + ok_sp: + if ((tp = sp->tp) == 0) { + uerr(ERR_UNDEFINED,lastid); + return 0; /* guard against untyped entries */ + } + switch (sp->storage_class) { + case sc_static: + *node = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); +#ifdef AS + (*node)->v.enlab = splbl(sp); +#else + (*node)->v.enlab = sp->value.i; +#endif + (*node)->etype = bt_pointer; + (*node)->esize = 4; + break; + case sc_global: + case sc_external: + *node = mk_node(en_nacon, NIL_ENODE, NIL_ENODE); + (*node)->v.ensp = sp->name; +#ifdef AS + (*node)->v.enlab = splbl(sp); +#endif + sp->used = 1; + (*node)->etype = bt_pointer; + (*node)->esize = 4; + break; + case sc_const: + *node = mk_icon((long) sp->value.i); + (*node)->etype = tp_econst.type; + (*node)->esize = tp_econst.size; + break; + default: /* auto and any errors */ + if (sp->storage_class != sc_auto) + error(ERR_ILLCLASS); + *node = mk_node(en_autocon, NIL_ENODE, NIL_ENODE); + (*node)->v.i = sp->value.i; + (*node)->etype = bt_pointer; + (*node)->esize = 4; +/* infunc("chk_curword") + if (sp->value.i==(long)(char)0xCF) + bkpt();*/ +/* infunc("chk_curword") + if (*(long *)node==0x7b4bf8) + bkpt();*/ + break; + } + if (asm_zflag) { + if ((*node)->etype == bt_pointer) + (*node)->etype = bt_ulong; + if (tp->type == bt_pointer || tp->type == bt_struct || tp->type == bt_union) + tp = (TYP *)&tp_ulong; + } else tp = cond_deref(node, tp); + } + getsym(); + return tp; +} + +#ifndef NO_VARARG_FUNC +extern char variable_arg_name[]; +#define is_variable_arg(sp) ((sp)->name==variable_arg_name) +#define mk_variable_arg(sp) ((sp)->name=variable_arg_name) +#endif + +struct enode *parmlist(SYM *f) { +/* + * parmlist will build a list of parameter expressions in a function call and + * return a pointer to the last expression parsed. since parameters are + * generally pushed from right to left we get just what we asked for... + */ + struct enode *ep1, *ep2; + TYP *tp; + ep1 = 0; + if (lastst != closepa) + for (;;) { + tp = exprnc(&ep2); /* evaluate a parameter */ + if (tp == 0) + error(ERR_EXPREXPECT); +#ifdef INTEL_386 + /* trap struct assigns */ + if (isaggregate(tp)) + uses_structassign=1; +#endif + /* + * do the default promotions + */ + if (f) { + if (tp->const_flag && f->tp->type==bt_pointer && !f->tp->btp->const_flag) + uwarn("read-only arg might be modified by function"); + tp = cast_op(&ep2, tp, f->tp); + } +#ifndef NOFLOAT +#ifdef DOUBLE + if (tp->type == bt_float) + tp = cast_op(&ep2, tp, (TYP *)&tp_double); +#endif +#endif + if (short_option) { + if (tp->type == bt_char || tp->type == bt_uchar) + (void) cast_op(&ep2, tp, (TYP *)&tp_short); + } else { + if (tp->type == bt_uchar || tp->type == bt_char || + tp->type == bt_short || tp->type == bt_ushort) + (void) cast_op(&ep2, tp, (TYP *)&tp_long); + } + ep1 = mk_node(en_void, ep2, ep1); + if (lastst != comma) + break; + getsym(); + if (f && !(f=f->next)) error(ERR_TOOMPARAMS); +#ifndef NO_VARARG_FUNC + if (f && is_variable_arg(f)) f=NULL; // switch to K&R mode for variable args... +#endif + } + if (f && f->next && !is_variable_arg(f->next)) error(ERR_TOOFPARAMS); + return ep1; +} + +int castbegin(enum(e_sym) st) { +/* + * return 1 if st in set of [ kw_char, kw_short, kw_long, kw_float, + * kw_double, kw_struct, kw_union ] CVW change: or kw_void CVW change: or an + * type identifier + */ + if (st == kw_char || st == kw_short || st == kw_int || + st == kw_long || st == kw_float || st == kw_double || + st == kw_struct || st == kw_union || st == kw_unsigned || + st == kw_void || st == kw_enum || st == kw_typeof || + st == kw_signed || st == kw_const || st == kw_volatile) + return 1; + if (st == id && lastsp != 0 && + lastsp->storage_class == sc_typedef) + return 1; + return 0; +} + +static TYP *primary(struct enode **node) { +/* + * primary will parse a primary expression and set the node pointer returning + * the type of the expression parsed. primary expressions are any of: + * id + * constant + * string + * ( expression ) + * primary[ expression ] +#ifndef OLD_PRIOR + * primary++ + * primary-- +#endif + * primary.id + * primary->id + * primary( parameter list ) + * -- or just a semicolon, yields empty expression -- + * + */ + struct enode *pnode, *qnode, *rnode; + struct sym *sp; + TYP *tptr; + TYP *tp1,*tp2; + switch (lastst) { + + case id: + if (id_are_zero) { + pnode = mk_icon(0l); + tptr = (TYP *)&tp_long; // dans #if, le type par dfaut est 'long' + pnode->etype = tp_long.type; + pnode->esize = tp_long.size; + getsym(); + break; + } + tptr = nameref(&pnode); + if (tptr == 0) + break; + /* + * function names alone are pointers to functions. + * If followed by '(', the reference is stripped off + * later. + */ + if (tptr->type == bt_func) { + tp1 = mk_type(bt_pointer, 4); + tp1->btp = tptr; + tptr = tp1; + } + break; + case iconst: + case uconst: + case lconst: + case ulconst: + pnode = mk_icon(0l); + pnode->v.i = ival; + if (lastst == uconst) { + tptr = (TYP *)&tp_uint; + pnode->etype = tp_uint.type; + pnode->esize = tp_uint.size; + } else if (lastst == lconst) { + tptr = (TYP *)&tp_long; + pnode->etype = bt_long; + pnode->esize = 4; + } else if (lastst == ulconst) { + tptr = (TYP *)&tp_ulong; + pnode->etype = bt_ulong; + pnode->esize = 4; + } else { + tptr = (TYP *)&tp_int; + pnode->etype = tp_int.type; + pnode->esize = tp_int.size; + } + getsym(); + break; +#ifndef NOFLOAT + case rconst: + tptr = (TYP *)&tp_double; + pnode = mk_node(en_fcon, NIL_ENODE, NIL_ENODE); + pnode->v.f = rval; + pnode->etype = tp_double.type; + pnode->esize = tp_double.size; + getsym(); + break; +#endif + case sconst: + if (sizeof_flag) { + tptr = mk_type(bt_pointer, 0); + tptr->size = lstrlen + 1; + tptr->btp = (TYP *)&tp_char; + tptr->val_flag = 1; + } else + tptr = (TYP *)&tp_string; + pnode = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + if (sizeof_flag == 0) + pnode->v.enlab = stringlit(laststr, lstrlen); + pnode->etype = bt_pointer; + pnode->esize = 4; + getsym(); + break; + case kw_softcast: + getsym(); + if (!castbegin(lastst)) { + error(ERR_SYNTAX); + tptr = 0; // just to avoid a compiler warning =) + } else { + struct typ *local_head = head, *local_tail=tail; + decl((HTABLE *)NULL); /* do cast declaration */ + decl1(); + tptr = head; + needpunc(closepa); + if (!(tp1 = unary(&pnode))) { + error(ERR_IDEXPECT); + tptr = 0; + } else + /* do the cast */ + tptr = cast_op(&pnode, tp1, tptr); + head = local_head; + tail = local_tail; + } + break; + case openpa: + getsym(); + if (!castbegin(lastst)) { + if (lastst==begin) { /* compound expression */ + struct snode *snp; + struct enode *old_init_node = init_node; + int old_middle_decl = middle_decl; + getsym(); + init_node = 0; + middle_decl = 0; + snp = compound(0); + init_node = old_init_node; + middle_decl = old_middle_decl; + tptr = lastexpr_tp; + pnode = mk_node(en_compound, (struct enode *)snp, NIL_ENODE); + pnode->etype=lastexpr_type; + pnode->esize=lastexpr_size; + } else tptr = expression(&pnode); + needpunc(closepa); + } else { /* cast operator or middle declaration */ + struct typ *local_head = head, *local_tail=tail; +#ifdef MID_DECL_IN_EXPR + struct enode *old_md_expr = md_expr; + struct typ *old_md_type = md_type; + md_expr = 0; + middle_decl++; + dodecl(sc_auto); /* if it's a real cast, same as decl(NULL);decl1(); */ + middle_decl--; +#else + decl((HTABLE *)NULL); /* do cast declaration */ + decl1(); +#endif + tptr = head; + needpunc(closepa); +#ifdef MID_DECL_IN_EXPR + if ((pnode = md_expr)) + tptr = md_type; /* we can't use head since parsing md_expr might change it */ + md_expr = old_md_expr; + md_type = old_md_type; + if (pnode) + break; +#endif + if (lastst==begin) { /* cast constructor */ + int lab=nxtlabel(); + TYP *tp=tptr; + nl(); + dseg(); + put_align(alignment(tptr)); + put_label(lab); + inittype(tp,&tp); + pnode = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + pnode->v.enlab=lab; + pnode->etype=bt_pointer; + pnode->esize=4; + tptr=cond_deref(&pnode,tp); + } else if ((tp1 = unary(&pnode)) == 0) { + error(ERR_IDEXPECT); + tptr = 0; + } else { + /* do the cast */ + tptr = force_cast_op(&pnode, tp1, tptr); + } + head = local_head; + tail = local_tail; + } + break; + default: + tptr=0; + break; + } + if (tptr == 0) + return 0; + for (;;) { + switch (lastst) { + case openbr: /* build a subscript reference */ + getsym(); +/* + * a[b] is defined as *(a+b), such exactly one of (a,b) must be a pointer + * and one of (a,b) must be an integer expression + */ + if (tptr->type == bt_pointer) { + tp2 = expression(&rnode); + tp1 = tptr; + } else { + tp2 = tptr; + rnode = pnode; + tp1 = expression(&pnode); + tptr = tp1; + } + +/* + * now, pnode and tp1 describe the pointer, + * rnode and tp2 describe the integral value + */ + + if (tptr->type != bt_pointer) + error (ERR_NOPOINTER); + else + tptr = tptr->btp; + + if (tptr->size==1) { /* doing this : 1) saves RAM; 2) allows file_ESI[filesize] */ + cast_op(&rnode, tp2, (TYP *)&tp_long); /* (even with fast_array on) */ + cast_op(&rnode, (TYP *)&tp_long, tp1); + qnode=rnode; + } else { + qnode = mk_icon((long) tptr->size); + #ifdef NO_SECURE_POINTERS + qnode->etype = bt_short; + qnode->esize = 2; + #else + qnode->etype = bt_long; + qnode->esize = 4; + #endif + /* + * qnode is the size of the referenced object + */ + #ifdef NO_SECURE_POINTERS + cast_op(&rnode, tp2, (TYP *)&tp_short); + #else + cast_op(&rnode, tp2, (TYP *)&tp_long); + #endif + /* + * we could check the type of the expression here... + */ + #ifdef NO_SECURE_POINTERS + qnode = mk_node(en_mul, qnode, rnode); + qnode->etype = bt_short; + qnode->esize = 2; + cast_op(&qnode, (TYP *)&tp_short, (TYP *)&tp_long); + cast_op(&qnode, (TYP *)&tp_long, tp1); + #else + qnode = mk_node(en_mul, qnode, rnode); + qnode->etype = bt_long; + qnode->esize = 4; + cast_op(&qnode, (TYP *)&tp_long, tp1); + #endif + } + pnode = mk_node(en_add, pnode, qnode); +// pnode = mk_node(en_add, qnode, pnode); + pnode->etype = bt_pointer; + pnode->esize = 4; + tptr = cond_deref(&pnode, tptr); + needpunc(closebr); + break; + case pointsto: + if (tptr->type != bt_pointer) + error(ERR_NOPOINTER); + else + tptr = tptr->btp; + /* + * tptr->type should be bt_struct or bt_union tptr->val_flag + * should be 0 the ref node will be stripped off in a minute + */ + tptr = cond_deref(&pnode, tptr); + /* + * fall through to dot operation + */ + case dot: + getsym(); /* past -> or . */ + if (lastst != id) + error(ERR_IDEXPECT); + else { + if (tptr->type!=bt_struct && tptr->type!=bt_union) + uerrc("not a structure/union"); + { + TABLE *tab=&tptr->lst; + long offs=0; + search_again: + sp = search(lastid, lastcrc, (HTABLE *)tab); + if (sp == 0) { + sp = search("__unnamed__", -1, (HTABLE *)tab); + if (!sp || (sp->tp->type!=bt_union && sp->tp->type!=bt_struct)) + uerr(ERR_NOMEMBER,lastid); + else { + offs += sp->value.i; + tab = &sp->tp->lst; + goto search_again; + } + } else { + /* strip off the en_ref node on top */ + if (lvalue(pnode)) + pnode = pnode->v.p[0]; + else { + pnode = mk_node(en_deref, pnode, NIL_ENODE); + pnode->etype = bt_pointer; + pnode->esize = 4; + } + tptr = sp->tp; + qnode = mk_icon((long) (offs+sp->value.i)); + qnode->etype = bt_long; + qnode->esize = 4; + pnode = mk_node(en_add, pnode, qnode); + pnode->etype = bt_pointer; + pnode->esize = 4; + tptr = cond_deref(&pnode, tptr); + } + } + getsym(); /* past id */ + } + break; + case openpa: /* function reference */ +#ifdef ASM +#ifndef OLD_AMODE_INPUT + if (asm_zflag) goto fini; +#endif +#endif + getsym(); + /* + * the '*' may be ommitted with pointers to functions + * we have included another indirection (see above, case id:) + */ + if (tptr->type == bt_pointer) + tptr = tptr->btp; + if (tptr->type != bt_func) + error(ERR_NOFUNC); + + /* + * This hack lets us remember that this function itself calls + * other functions. + * The code generator might use this information to generate + * safer register-pop-off code. + */ + is_leaf_function = 0; + + pnode = mk_node(en_fcall, pnode, parmlist(tptr->lst.head)); +#ifdef REGPARM + pnode->rp_dn = tptr->rp_dn; + pnode->rp_an = tptr->rp_an; +#endif + tptr = tptr->btp; + pnode->etype = tptr->type; + pnode->esize = tptr->size; + needpunc(closepa); + break; + case autoinc: + case autodec: + if (g_lvalue(pnode)) { + qnode = mk_icon((tptr->type==bt_pointer?(long)tptr->btp->size:1L)); + pnode = mk_node(lastst==autoinc?en_ainc:en_adec, pnode, qnode); + pnode->etype = tptr->type; + pnode->esize = tptr->size; + } else + error(ERR_LVALUE); + getsym(); + break; + default: + goto fini; + } + } +fini: + *node = pnode; + return tptr; +} + +static TYP *unary(struct enode **node) { +/* + * unary evaluates unary expressions and returns the type of the expression + * evaluated. unary expressions are any of: + * + * primary +#ifdef OLD_PRIOR + * primary++ + * primary-- +#endif + * !unary + * ~unary + * ++unary + * --unary + * -unary + * *unary + * &unary + * (typecast)unary + * sizeof(typecast) + * sizeof unary + * + */ + TYP *tp, *tp1; + struct enode *ep1, *ep2; + int flag; +// long i; + flag = 0; + switch (lastst) { + case autodec: + flag = 1; + /* fall through to common increment */ + case autoinc: + getsym(); + tp = unary(&ep1); + if (tp == 0) { + error(ERR_IDEXPECT); + return 0; + } + if (g_lvalue(ep1)) { + if (tp->type == bt_pointer) + ep2 = mk_icon((long) tp->btp->size); + else { + ep2 = mk_icon(1l); + if (!integral(tp)) + error(ERR_INTEGER); + } + + ep2->etype = bt_long; + ep2->esize = 4; + ep1 = mk_node(flag ? en_assub : en_asadd, ep1, ep2); + ep1->etype = tp->type; + ep1->esize = tp->size; + } else + error(ERR_LVALUE); + break; + case minus: + getsym(); + tp = unary(&ep1); + if (tp == 0) { + error(ERR_IDEXPECT); + return 0; + } + ep1 = mk_node(en_uminus, ep1, NIL_ENODE); + ep1->etype = tp->type; + ep1->esize = tp->size; + break; + case not: + getsym(); + tp = unary(&ep1); + if (tp == 0) { + error(ERR_IDEXPECT); + return 0; + } + if (!bt_comparable(tp->type)) + uerrc("cannot test expression"); + ep1 = mk_node(en_not, ep1, NIL_ENODE); + tp = (TYP *)&tp_int; + ep1->etype = tp_int.type; + ep1->esize = tp_int.size; + break; + case compl: + getsym(); + tp = unary(&ep1); + if (tp == 0) { + error(ERR_IDEXPECT); + return 0; + } + ep1 = mk_node(en_compl, ep1, NIL_ENODE); + ep1->etype = tp->type; + ep1->esize = tp->size; + if (!integral(tp)) + error(ERR_INTEGER); + break; + case star: + getsym(); + tp = unary(&ep1); + if (tp == 0) { + error(ERR_IDEXPECT); + return 0; + } + if (tp->type!=bt_pointer) + error(ERR_DEREF); + else + tp = tp->btp; + tp = cond_deref(&ep1, tp); + break; + case and: + getsym(); + /*if (lineid==0x216) + bkpt();*/ + tp = unary(&ep1); + if (tp == 0) { + error(ERR_IDEXPECT); + return 0; + } + if (lvalue(ep1)) { /* TODO: adapt this to g_lvalue */ +/* if (ep1->nodetype==en_cast */ + ep1 = ep1->v.p[0]; + tp1 = mk_type(bt_pointer, 4); + tp1->st_flag = 0; + tp1->btp = tp; + tp = tp1; + } else if (tp->type == bt_pointer && tp->btp->type == bt_func) { + uwarn("'&' operator ignored"); + } else + error(ERR_LVALUE); + break; + case kw_c: { + int zf=asm_zflag; + asm_zflag=0; + getsym(); + needpunc(openpa); + tp=expression(&ep1); + asm_zflag=zf; + needpunc(closepa); + } break; + case kw_defined: + skipspace(); + { int parenth=0; + if (lastch=='(') getch(),parenth=1; + skipspace(); + if ((lastch>='A'&&lastch<='Z') || (lastch>='a'&&lastch<='z') + || lastch=='_' || lastch=='$') { + getidstr(); + ep1=mk_icon((long)!!search(lastid,lastcrc,&defsyms)); + tp = (TYP *)&tp_int; + ep1->etype = tp_int.type; + ep1->esize = tp_int.size; + getsym(); + } else { + error(ERR_IDEXPECT); + tp = 0; // just to avoid a compiler warning =) + } + if (parenth) + needpunc(closepa); + } + break; + case kwb_constant_p: + getsym(); + needpunc(openpa); + if (!expression(&ep1)) error(ERR_EXPREXPECT); + needpunc(closepa); + opt0(&ep1); + ep1=mk_icon((long)(ep1->nodetype==en_icon || ep1->nodetype==en_fcon)); + tp = (TYP *)&tp_int; + ep1->etype = tp_int.type; + ep1->esize = tp_int.size; + break; + case kw_alloca: + getsym(); + needpunc(openpa); + if (!(tp=expression(&ep1))) error(ERR_EXPREXPECT); + needpunc(closepa); + uses_link = 1; + cast_op(&ep1,tp,(TYP *)&tp_short); + ep1 = mk_node(en_alloca,ep1,NIL_ENODE); + tp = (TYP *)&tp_void_ptr; + ep1->etype = tp_void_ptr.type; + ep1->esize = tp_void_ptr.size; + break; + case kw_sizeof: + getsym(); + if (lastst == openpa) { + flag = 1; + getsym(); + } + if (flag && castbegin(lastst)) { + /* + * save head and tail, since we may be called from inside decl + * imagine: int x[sizeof(...)]; + */ + tp = head; + tp1 = tail; + decl((HTABLE *) 0); + decl1(); + if (head != 0) { + ep1 = mk_icon((long) head->size); + /* + * Guard against the size of not-yet-declared struct/unions + */ + if (head->size == 0) { + uwarn("sizeof(item) = 0"); + } + } else + ep1 = mk_icon(1l); + head = tp; + tail = tp1; + } else { +/* + * This is a mess. + * Normally, we treat array names just as pointers, but with sizeof, + * we want to get the real array size. + * sizeof_flag != 0 tells cond_deref not to convert array names to pointers + */ + sizeof_flag++; + tp = unary(&ep1); + sizeof_flag--; + if (tp == 0) { + error(ERR_SYNTAX); + ep1 = mk_icon(1l); + } else + ep1 = mk_icon((long) tp->size); + } +/* if (short_option && ep1->v.i > 65535) + do_warning("'sizeof' value greater than 65535\n");*/ + tp = (TYP *)&tp_uint; + ep1->etype = tp_uint.type; + ep1->esize = tp_uint.size; + if (flag) + needpunc(closepa); + break; + default: + tp = primary(&ep1); + break; + } + *node = ep1; + return tp; +} + +#ifndef NO_TYPE_STR +int type_str_pos CGLOB; +typedef char type_str_content_type[32]; +type_str_content_type type_str_content[4]; +char *type_str(TYP *tp) { + char *p,*q; + int n; + switch (tp->type) { + case bt_char: + return "char"; + case bt_uchar: + return "unsigned char"; + case bt_short: + return "short"; + case bt_ushort: + return "unsigned short"; + case bt_long: + return "long"; + case bt_ulong: + return "unsigned long"; + case bt_float: + return "float"; +#ifdef DOUBLE + case bt_double: + return "double"; +#endif + case bt_void: + return "void"; + case bt_struct: +#ifdef LISTING + if (tp->sname) return tp->sname; +#endif + return ""; + case bt_union: + return ""; + case bt_func: + return ""; + case bt_bitfield: + return ""; + case bt_pointer: + n=type_str_pos; + q=p=type_str(tp->btp); + if (n==type_str_pos) { + type_str_pos++; + strcpy(type_str_content[n],p); + q=p=type_str_content[n]; + while (*p++); + p[-1]=' '; *p++=0; + } else while (*p++); + if (!tp->val_flag) p[-1]='*'; + else p[-1]='[',*p++=']'; + *p=0; + return q; + } + return ""; +} +#endif + +TYP *forcefit(struct enode **node1, TYP *tp1, struct enode **node2, TYP *tp2) { +/* + * forcefit will coerce the nodes passed into compatible types and return the + * type of the resulting expression. + */ + /* cast short and char to int */ + if (short_option) { + if (tp1->type == bt_char || tp1->type == bt_uchar) + tp1 = cast_op(node1, tp1, (TYP *)&tp_short); + if (tp2->type == bt_char || tp2->type == bt_uchar) + tp2 = cast_op(node2, tp2, (TYP *)&tp_short); + } else { + if (tp1->type == bt_char || tp1->type == bt_uchar || + tp1->type == bt_short || tp1->type == bt_ushort) + tp1 = cast_op(node1, tp1, (TYP *)&tp_long); + + if (tp2->type == bt_char || tp2->type == bt_uchar || + tp2->type == bt_short || tp2->type == bt_ushort) + tp2 = cast_op(node2, tp2, (TYP *)&tp_long); + } + +#ifndef NOFLOAT + /* cast float to double */ +#ifdef DOUBLE + if (tp1->type == bt_float) + tp1 = cast_op(node1, tp1, (TYP *)&tp_double); + if (tp2->type == bt_float) + tp2 = cast_op(node2, tp2, (TYP *)&tp_double); +#endif + + if (tp1->type == bt_double && isscalar(tp2)) + tp2 = cast_op(node2, tp2, (TYP *)&tp_double); + else if (tp2->type == bt_double && isscalar(tp1)) + tp1 = cast_op(node1, tp1, (TYP *)&tp_double); +#endif + + if (tp1->type == bt_ulong && isscalar(tp2)) + tp2 = cast_op(node2, tp2, tp1); + else if (tp2->type == bt_ulong && isscalar(tp1)) + tp1 = cast_op(node1, tp1, tp2); + + if (tp1->type == bt_long && isscalar(tp2)) + tp2 = cast_op(node2, tp2, tp1); + else if (tp2->type == bt_long && isscalar(tp2)) + tp1 = cast_op(node1, tp1, tp2); + + if (tp1->type == bt_ushort && isscalar(tp2)) + tp2 = cast_op(node2, tp2, tp1); + else if (tp2->type == bt_ushort && isscalar(tp2)) + tp1 = cast_op(node1, tp1, tp2); + + if (isscalar(tp1) && isscalar(tp2)) + return (tp1); + + /* pointers may be combined with integer constant 0 */ + if (tp1->type == bt_pointer && (*node2)->nodetype == en_icon && + (*node2)->v.i == 0) + return tp1; + if (tp2->type == bt_pointer && (*node1)->nodetype == en_icon && + (*node2)->v.i == 0) + return tp2; + + if (tp1->type == bt_pointer && tp2->type == bt_pointer) + return tp1; + + /* report mismatch error */ + + uerr(ERR_MISMATCH,type_str(tp1),type_str(tp2)); + return tp1; +} + +TYP *forceft2(struct enode **node1, TYP *tp1, struct enode **node2, TYP *tp2) { +/* + * ,,forcefit'' for comparisons: + * When comparing two char's, it is not necessary to cast + * both of them to long in advance + * + * Perhaps not strictly K&R, but more efficient. + * If you don't like it, use forcefit in ALL cases + */ + + /* short cut: */ + if (tp1->type == tp2->type) + return tp1; + + /* comparison with integer constant */ + + if ((*node1)->nodetype == en_icon) { + struct enode **node = node1; + TYP *tp = tp1; + node1 = node2; + tp1 = tp2; + node2 = node; + tp2 = tp; + } + opt4(node2); + if ((*node2)->nodetype == en_icon) { + long val = (*node2)->v.i; + enum(e_bt) typ1 = tp1->type; + if ((typ1 == bt_char && -128 <= val && val <= 127) || + (typ1 == bt_uchar && 0 <= val && val <= 255) || + (typ1 == bt_short && -32768 <= val && val <= 32767) || + (typ1 == bt_ushort && 0 <= val && val <= 65535) || + (typ1 == bt_pointer && val == 0)) + return cast_op(node2, tp2, tp1); + } + + switch (tp1->type) { + /* Type of first operand */ + case bt_char: + case bt_uchar: + switch (tp2->type) { + case bt_char: + case bt_uchar: + (void) cast_op(node1, tp1, (TYP *)&tp_short); + return cast_op(node2, tp2, (TYP *)&tp_short); + case bt_short: + case bt_long: + case bt_ushort: + case bt_ulong: + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return cast_op(node1, tp1, tp2); + } + break; + case bt_short: + case bt_ushort: + switch (tp2->type) { + case bt_char: + case bt_uchar: + return cast_op(node2, tp2, tp1); + case bt_ushort: + if (short_option) + return cast_op (node1, tp1, (TYP *)&tp_ushort); + else { + (void) cast_op (node1, tp1, (TYP *)&tp_long); + return cast_op (node2, tp2, (TYP *)&tp_long); + } + case bt_short: + if (short_option) + return cast_op(node2, tp2, (TYP *)&tp_ushort); + else { + (void) cast_op (node1, tp1, (TYP *)&tp_long); + return cast_op (node2, tp2, (TYP *)&tp_long); + } + case bt_long: + case bt_ulong: + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return cast_op(node1, tp1, tp2); + } + break; + case bt_long: + case bt_ulong: + switch (tp2->type) { + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + return cast_op(node2, tp2, tp1); + case bt_long: + return cast_op(node2, tp2, tp1); + case bt_ulong: + return cast_op(node1, tp1, tp2); + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return cast_op(node1, tp1, tp2); + } + break; + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + switch (tp2->type) { + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_float: + return cast_op(node2, tp2, tp1); +#ifdef DOUBLE + case bt_double: + return cast_op(node1, tp1, tp2); +#endif + } + break; + /* + * pointers are equivalent to function names + */ + case bt_pointer: + if (tp2->type == bt_func) + return cast_op(node2, tp2, tp1); + break; + case bt_func: + if (tp2->type == bt_pointer) + return cast_op(node1, tp1, tp2); + break; + } + uerr(ERR_MISMATCH,type_str(tp1),type_str(tp2)); + return 0; +} + +#ifndef isscalar +static int isscalar(TYP *tp) { +/* + * this function returns true when the type of the argument is a scalar type + * (enum included) + */ +/* return tp->type == bt_char || + tp->type == bt_uchar || + tp->type == bt_ushort || + tp->type == bt_short || + tp->type == bt_long || + tp->type == bt_ulong || + tp->type == bt_float || + tp->type == bt_double; */ + return bt_scalar(tp->type); +} +#endif + +static TYP *multops(struct enode **node) { +/* + * multops parses the multiply priority operators. the syntax of this group + * is: + * + * unary multop * unary multop / unary multop % unary + */ + struct enode *ep1, *ep2; + TYP *tp1, *tp2; + enum(e_sym) oper; + tp1 = unary(&ep1); + if (tp1 == 0) + return 0; + while (lastst == star || lastst == divide || lastst == modop) { + oper = lastst; + getsym(); /* move on to next unary op */ +/* if (lineid==77) + bkpt();*/ + tp2 = unary(&ep2); + if (tp2 == 0) { + error(ERR_IDEXPECT); + *node = ep1; + return tp1; + } +#ifdef INTEL_386 + tp1 = forcefit(&ep1, tp1, &ep2, tp2); +#endif + switch (oper) { + case star: + /*{extern SYM *func_sp; + if (!strcmp(func_sp->name,"bonus")) + printf("gjio");}*/ +/* if (lineid==1189) + bkpt();*/ + tp1 = forcefit(&ep1, tp1, &ep2, tp2); +#ifndef NOFLOAT +//#warning STUDY ME!!! +// uwarn("!!! study this !!!"); +// if (tp1->type==bt_float || tp2->type==bt_float) +// tp1 = forcefit(&ep1, tp1, &ep2, tp2); +// else +#endif +#ifdef MC68000 +// { +// tp1 = cast_op(&ep1, tp1, (TYP *)&tp_long); +// tp2 = cast_op(&ep2, tp2, (TYP *)&tp_long); +// } +#endif + ep1 = mk_node(en_mul, ep1, ep2); +#ifndef NOFLOAT + if (tp1->type!=bt_float) +#endif +#ifdef MC68000 +// tp1 = (TYP *)&tp_long; +#endif +/* if (bt_integral(tp1->type)) { + if (bt_uns(tp1->type)) tp1=(TYP *)&tp_ulong; + else tp1=(TYP *)&tp_long; + }*/ + break; + case divide: + case modop: +#ifndef NOFLOAT + if (tp1->type==bt_float || tp2->type==bt_float) + tp1 = forcefit(&ep1, tp1, &ep2, tp2); + else +#endif +#ifdef MC68000 + { +#ifdef OLD_STUPID_DIVIDE /* !!! n'importe quoi !!! */ + tp1 = cast_op(&ep1, tp1, (TYP *)&tp_long); + if (tp2->type==bt_long || tp2->type==bt_ulong) { + ep1 = mk_node(oper==divide?en_div:en_mod, ep1, ep2); + tp1 = (TYP *)&tp_long; + break; + } + tp2 = cast_op(&ep2, tp2, (TYP *)&tp_short); +#else + tp1 = forcefit(&ep1, tp1, &ep2, tp2); +#endif + } +#endif + ep1 = mk_node(oper==divide?en_div:en_mod, ep1, ep2); +#ifdef OLD_STUPID_DIVIDE /* !!! n'importe quoi !!! */ +#ifndef NOFLOAT + if (tp1->type!=bt_float) +#endif +#ifdef MC68000 + tp1 = (TYP *)&tp_short; +#endif +#endif + break; + } + ep1->etype = tp1->type; + ep1->esize = tp1->size; + } + *node = ep1; + return tp1; +} + +static TYP *addops(struct enode **node) { +/* + * addops handles the addition and subtraction operators. + */ + struct enode *ep1, *ep2, *ep3; + TYP *tp1, *tp2; + int oper; + tp1 = multops(&ep1); + if (tp1 == 0) + return 0; + while (lastst == plus || lastst == minus) { +/* if (asm_zflag) + printf("gfi");*/ +/* if (lineid==852) + bkpt();*/ + oper = (lastst - minus); + getsym(); + tp2 = multops(&ep2); + if (tp2 == 0) { + error(ERR_IDEXPECT); + *node = ep1; + return tp1; + } + if (tp1->type == bt_pointer && tp2->type == bt_pointer + && tp1->btp->size == tp2->btp->size && (!oper)) { + /* pointer subtraction */ + ep1 = mk_node(en_sub, ep1, ep2); + ep1->etype = bt_long; + ep1->esize = 4; + /* divide the result by the size */ + ep2 = mk_icon((long) tp1->btp->size); + ep2->etype = bt_long; + ep2->esize = 4; + ep1 = mk_node(en_div, ep1, ep2); + ep1->etype = bt_long; + ep1->esize = 4; +//#ifdef POINTER_DIFF_IS_SHORT + /* + * cast the result to ,,int''. K&R says that pointer subtraction + * yields an int result so I do it although it is not sensible on + * an 68000 with 32-bit pointers and 16-bit ints. In my opinion, + * it should remain ,,long''. + */ +// if (short_option) do_warning("pointer difference casted to 16-bit 'int'\n"); + if (tp1->btp->size!=1) /* if size is 1 maybe we want it bijective... */ + tp1 = cast_op(&ep1, (TYP *)&tp_long, (TYP *)&tp_int); + else tp1 = (TYP *)&tp_long; +//#endif + *node = ep1; + continue; + } + if (tp2->type == bt_pointer && oper) { + TYP *tpi; + /* integer + pointer */ + tpi=tp1; + tp1=tp2; + tp2=tpi; + ep3=ep1; + ep1=ep2; + ep2=ep3; + } + if (tp1->type == bt_pointer) { + /* pointer +/- integer */ + unsigned int s = tp1->btp->size;// int p; + if (!integral(tp2)) + error(ERR_INTEGER); + /*if ((p=pwrof2(s))>=0) { + if (tp2->type == bt_char || tp2->type == bt_uchar) + tp2 = cast_op(&ep2, tp2, (TYP *)&tp_short); + if (p) { + ep3 = mk_icon((long)p); + ep3->etype = bt_short; + ep3->esize = 2; + ep2 = mk_node(en_lsh, ep3, ep2); + ep2->etype = bt_short; + ep2->esize = 2; + } + ep1 = mk_node(oper ? en_add : en_sub, ep1, ep2); + ep1->etype = bt_pointer; + ep1->esize = 4; + continue; + } else {*/ + cast_op(&ep2, tp2, (TYP *)&tp_long); // g_xmul will restore all this to short if + ep3 = mk_icon(s); // necessary :) + ep3->etype = bt_long; + ep3->esize = 4; + ep2 = mk_node(en_mul, ep3, ep2); + ep2->etype = bt_long; + ep2->esize = 4; +// cast_op(&ep2, (TYP *)&tp_short, (TYP *)&tp_long); + ep1 = mk_node(oper ? en_add : en_sub, ep1, ep2); + ep1->etype = bt_pointer; + ep1->esize = 4; + continue; + /*}*/ + } + tp1 = forcefit(&ep1, tp1, &ep2, tp2); + ep1 = mk_node(oper ? en_add : en_sub, ep1, ep2); + ep1->etype = tp1->type; + ep1->esize = tp1->size; + } + *node = ep1; + return tp1; +} + +TYP *shiftop(struct enode **node) { +/* + * shiftop handles the shift operators << and >>. + */ + struct enode *ep1, *ep2; + TYP *tp1, *tp2; + int oper; + tp1 = addops(&ep1); + if (tp1 == 0) + return 0; + while (lastst == lshift || lastst == rshift) { + oper = (lastst == lshift); + getsym(); + tp2 = addops(&ep2); + if (tp2 == 0) + error(ERR_IDEXPECT); + else { +#ifndef MINIMAL_SIZES + tp1 = forcefit(&ep1, tp1, &ep2, tp2); +#else + /* + tp1 = forcefit(&ep1, tp1, &ep2, tp2); -> this is wrong: C89 specifies the type depends only on the left op. + cast_op(&ep2, tp2, (TYP *)&tp_char); + */ + if (tp1->type == bt_char || tp1->type == bt_uchar) + tp1 = cast_op(&ep1, tp1, (TYP *)&tp_short); + cast_op(&ep2, tp2, (TYP *)&tp_char); +#endif + ep1 = mk_node(oper ? en_lsh : en_rsh, ep1, ep2); + ep1->etype = tp1->type; + ep1->esize = tp1->size; + if (!integral(tp1)) + error(ERR_INTEGER); + } + } + *node = ep1; + return tp1; +} + +TYP *relation(struct enode **node) { +/* + * relation handles the relational operators < <= > and >=. + */ + struct enode *ep1, *ep2; + TYP *tp1, *tp2; + enum(e_node) nt; + tp1 = shiftop(&ep1); + if (tp1 == 0) + return 0; + for (;;) { + switch (lastst) { + case lt: + nt = en_lt; + break; + case gt: + nt = en_gt; + break; + case leq: + nt = en_le; + break; + case geq: + nt = en_ge; + break; + default: + goto fini; + } + getsym(); + tp2 = shiftop(&ep2); + if (tp2 == 0) + error(ERR_EXPREXPECT); + else { + tp1 = forceft2(&ep1, tp1, &ep2, tp2); + if (!iscomparable(tp1)) + uerr(ERR_ILLTYPE); + ep1 = mk_node(nt, ep1, ep2); + tp1 = (TYP *)&tp_int; + ep1->etype = tp_int.type; + ep1->esize = tp_int.size; + if (lastst>=lt && lastst<=geq) { + if (flags & X_COMP_STRING) { + uwarn("not implemented\n"); + } else uwarn("() suggested to clarify priority"); + } + } + } +fini:*node = ep1; + return tp1; +} + +TYP *equalops(struct enode **node) { +/* + * equalops handles the equality and inequality operators. + */ + struct enode *ep1, *ep2; + TYP *tp1, *tp2; + int oper; + tp1 = relation(&ep1); + if (tp1 == 0) + return 0; + while (lastst == eq || lastst == neq) { + oper = (lastst == eq); + getsym(); + tp2 = relation(&ep2); + if (tp2 == 0) + error(ERR_IDEXPECT); + else { + tp1 = forceft2(&ep1, tp1, &ep2, tp2); + ep1 = mk_node(oper ? en_eq : en_ne, ep1, ep2); + tp1 = (TYP *)&tp_int; + ep1->etype = tp_int.type; + ep1->esize = tp_int.size; + } + } + *node = ep1; + return tp1; +} + +TYP *binop(struct enode **node, TYP *(*xfunc)(), enum(e_node) nt, enum (e_sym) sy) { +/* + * binop is a common routine to handle all of the legwork and error checking + * for bitand, bitor, bitxor + */ + struct enode *ep1, *ep2; + TYP *tp1, *tp2; + tp1 = (*xfunc) (&ep1); + if (tp1 == 0) + return 0; + while (lastst == sy) { + getsym(); + tp2 = (*xfunc) (&ep2); + if (tp2 == 0) + error(ERR_IDEXPECT); + else { + tp1 = forceft2(&ep1, tp1, &ep2, tp2); + ep1 = mk_node(nt, ep1, ep2); + ep1->etype = tp1->type; + ep1->esize = tp1->size; + if (!integral(tp1)) + error(ERR_INTEGER); + } + } + *node = ep1; + return tp1; +} + +TYP *binlog(struct enode **node, TYP *(*xfunc)(), enum(e_node) nt, enum(e_sym) sy) { +/* + * binlog is a common routine to handle all of the legwork and error checking + * for logical and, or + */ + struct enode *ep1, *ep2; + TYP *tp1, *tp2; + tp1 = (*xfunc) (&ep1); + if (tp1 == 0) + return 0; + while (lastst == sy) { + getsym(); + tp2 = (*xfunc) (&ep2); + if (tp2 == 0) + error(ERR_IDEXPECT); + else { + ep1 = mk_node(nt, ep1, ep2); + tp1 = (TYP *)&tp_int; + ep1->etype = tp_int.type; + ep1->esize = tp_int.size; + } + } + *node = ep1; + return tp1; +} + +TYP *bitand(struct enode **node) { +/* + * the bitwise and operator... + */ + return binop(node, equalops, en_and, and); +} + +TYP *bitxor(struct enode **node) { + return binop(node, bitand, en_xor, uparrow); +} + +TYP *bitor(struct enode **node) { + return binop(node, bitxor, en_or, or); +} + +TYP *andop(struct enode **node) { + return binlog(node, bitor, en_land, land); +} + +TYP *orop(struct enode **node) { + return binlog(node, andop, en_lor, lor); +} + +TYP *conditional(struct enode **node) { +/* + * this routine processes the hook operator. + */ + TYP *tp1, *tp2, *tp3; + struct enode *ep1, *ep2, *ep3; + tp1 = orop(&ep1); /* get condition */ + if (tp1 == 0) + return 0; + if (lastst == hook) { + getsym(); + if (lastst==colon) { + ep2=NULL; tp2=tp1; + } else if ((tp2 = expression(&ep2)) == 0) { + error(ERR_IDEXPECT); + return 0; + } + needpunc(colon); + if ((tp3 = exprnc(&ep3)) == 0) { + error(ERR_IDEXPECT); + return 0; + } +/* + * If either type is void and the other is not, cast the other one to void. + * I dare not doing this in forceft2 + * Strict ANSI does not allow that only one part of the sentence is void, + * that is what gcc -pedantic tells me. + * But since such conditionals occur even in GNU Software (look at obstack.h), + * I allow such constructs here. + */ + if (tp2->type == bt_void && tp3->type != bt_void) + tp3 = cast_op(&ep3, tp3, tp2); + else if (tp3->type == bt_void && tp2->type != bt_void && ep2!=NULL) + tp2 = cast_op(&ep2, tp2, tp3); + + if (ep2==NULL) + tp1 = forceft2(&ep1, tp1, &ep3, tp3); + else tp1 = forceft2(&ep2, tp2, &ep3, tp3); + if (tp1 == 0) + return 0; + ep2 = mk_node(en_void, ep2, ep3); + ep1 = mk_node(en_cond, ep1, ep2); + ep1->etype = tp1->type; + ep1->esize = tp1->size; + } + *node = ep1; + return tp1; +} + +TYP *asnop(struct enode **node) { +/* + * asnop handles the assignment operators. + */ + struct enode *ep1, *ep2, *ep3; + TYP *tp1, *tp2, *tp0; + enum(e_node) op; + tp0 = NULL; + tp1 = conditional(&ep1); + if (tp1 == 0) + return 0; + for (;;) { + switch (lastst) { + case assign: + op = en_assign; + ascomm: getsym(); + tp2 = asnop(&ep2); + ascomm2: + if (tp2 == 0) + break; + if (ep1->nodetype != en_ref && ep1->nodetype != en_fieldref) { + if (ep1->nodetype==en_cast) { /* CAUTION : works well only with en_assign */ + enum(e_node) nt; + if ((nt=ep1->v.p[0]->nodetype) != en_ref && nt != en_fieldref) + error(ERR_LVALUE); + tp2 = cast_op(&ep2, tp2, tp1); + tp1 = (TYP *)ep1->v.p[1]; +/* } else if (ep1->nodetype==en_cond) { + struct enode *epvoid=ep1->v.p[1]; + + tp1 = cast_op(&epvoid->v.p[0], tp2, tp1); + tp1 = cast_op(&epvoid->v.p[1], tp2, tp1);*/ + } else error(ERR_LVALUE); + } + if (tp1->const_flag) + uwarn("assignment of read-only lvalue"); + if (tp0 != 0) tp1 = force_cast_op(&ep2, tp2, tp1); + else tp1 = cast_op(&ep2, tp2, tp1); + if (tp1 == 0) + break; + if (op!=en_assign && !iscomparable(tp1)) + uerr(ERR_ILLTYPE); + ep1 = mk_node(op, ep1, ep2); + ep1->etype = tp1->type; + ep1->esize = tp1->size; + if (tp0 != 0) tp1 = cast_op(&ep1, tp1, tp0); +#ifdef INTEL_386 + /* trap struct assigns */ + if (isaggregate(tp1)) + uses_structassign=1; +#endif + break; + case asplus: + op = en_asadd; + ascomm3: + getsym(); + tp2 = asnop(&ep2); + if (tp2 == 0) + break; + if (tp1->type == bt_pointer && integral(tp2)) { +#ifdef NO_SECURE_POINTERS + if (tp1->btp->size!=1) { + cast_op(&ep2, tp2, (TYP *)&tp_short); + ep3 = mk_icon((long) tp1->btp->size); + ep3->etype = bt_short; + ep3->esize = 2; + ep2 = mk_node(en_mul, ep2, ep3); + ep2->etype = bt_short; + ep2->esize = 2; + tp2 = cast_op(&ep2, (TYP *)&tp_short, (TYP *)&tp_long); + } else + tp2 = cast_op(&ep2, tp2, (TYP *)&tp_long); + tp2 = cast_op(&ep2, (TYP *)&tp_long, tp1); +#else + cast_op(&ep2, tp2, (TYP *)&tp_long); + ep3 = mk_icon((long) tp1->btp->size); + ep3->etype = bt_long; + ep3->esize = 4; + ep2 = mk_node(en_mul, ep2, ep3); + ep2->etype = bt_long; + ep2->esize = 4; + tp2 = cast_op(&ep2, (TYP *)&tp_long, tp1); +#endif + } + goto ascomm2; + case asminus: + op = en_assub; + goto ascomm3; + case astimes: + op = en_asmul; + goto ascomm; + case asdivide: + op = en_asdiv; + goto ascomm; + case asmodop: + op = en_asmod; + goto ascomm; + case aslshift: + op = en_aslsh; + goto ascomm; + case asrshift: + op = en_asrsh; + goto ascomm; + case asand: + op = en_asand; + goto ascomm; + case asor: + op = en_asor; + goto ascomm; + case asuparrow: + op = en_asxor; + goto ascomm; + default: + goto asexit; + } + } +asexit: + *node = ep1; + return tp1; +} + +TYP *exprnc(struct enode **node) { +/* + * evaluate an expression where the comma operator is not legal. + */ + TYP *tp; + tp = asnop(node); + if (tp == 0) + *node = 0; + return tp; +} + +TYP *commaop(struct enode **node) { +/* + * evaluate the comma operator. comma operators are kept as void nodes. + */ + TYP *tp1; + struct enode *ep1, *ep2; + tp1 = asnop(&ep1); + if (tp1 == 0) + return 0; + if (lastst == comma) { + getsym(); + tp1 = commaop(&ep2); + if (tp1 == 0) { + error(ERR_IDEXPECT); + goto coexit; + } + ep1 = mk_node(en_void, ep1, ep2); + ep1->esize = ep2->esize; + ep1->etype = ep2->etype; + } +coexit:*node = ep1; + return tp1; +} + +TYP *expression(struct enode **node) { +/* + * evaluate an expression where all operators are legal. + */ + TYP *tp; + tp = commaop(node); + if (tp == 0) + *node = 0; + return tp; +} + +int cast_ok(TYP *tp1, TYP *tp2, int need_physically_compatible) { +/* + * This is used to tell whether an implicit cast will generate a warning + * + * If need_physically_compatible is 0, then we do not make a difference between + * short[123], short[124], short[0] and short* (otherwise we do because they're + * not stored in memory the same way). + */ + if (tp1 == 0 || tp2 == 0) + return 0; + + if (tp1 == tp2 || tp2->type == bt_void) + return 1; + if (bt_integral(tp1->type)) + return (tp1->type^tp2->type)<=1; + + if (tp1->type != tp2->type) + return 0; + + /* from now on, tp1->type==tp2->type */ + if (tp1->type == bt_pointer) { + if (need_physically_compatible) + if (tp1->val_flag!=tp2->val_flag || + (tp1->val_flag && tp1->size!=tp2->size)) + return 0; + return tp1->btp->type == bt_void || cast_ok(tp1->btp, tp2->btp, 1); + } + if (tp1->type == bt_func) { + SYM *sp=tp1->lst.head,*sp2=tp2->lst.head; + if (!sp || !sp2) // one is only a prototype : OK + return eq_type(tp1->btp, tp2->btp); + while (sp && sp2) { + if (!eq_type(sp->tp,sp2->tp)) return 0; + sp=sp->next; sp2=sp2->next; + } + if (sp || sp2) return 0; // != # of args + return eq_type(tp1->btp, tp2->btp); + } + if (tp1->type == bt_struct || tp1->type == bt_union) + return (tp1->lst.head == tp2->lst.head); + + return 1; +} + +TYP *cast_op(struct enode **ep, TYP *tp1, TYP *tp2) { + struct enode *ep2; + + if (tp1 == 0 || tp2 == 0 || (tp1->type == bt_void && tp2->type != bt_void)) { + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + return 0; + } + if (tp1->type == tp2->type) { + if (!cast_ok(tp1, tp2, 0)) + uwarn("conversion between incompatible %stypes", + (tp1->type == bt_pointer) ? "pointer " : ""); + if (tp1->type == bt_struct || tp1->type == bt_union) { + if (tp1->size != tp2->size) + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + } +#ifdef NO_VERYTRIVIAL_CASTS + return tp2; +#endif + } + opt0(ep); /* to make a constant really a constant */ + + if ((*ep)->nodetype == en_icon) { + if (integral(tp2) || tp2->type == bt_pointer || tp2->type == bt_void) { + long j = (*ep)->v.i; + long d; + (*ep)->etype = tp2->type; + (*ep)->esize = tp2->size; + /* + * The cast may affect the value of (*ep)->v.i + */ + (*ep)->v.i = strip_icon(j, tp2->type); + d = j ^ (*ep)->v.i; + if (d && d!=0xFFFF0000 && d!=0xFFFFFF00) + uwarn("cast changed integer constant 0x%08lx to 0x%08lx", j, (*ep)->v.i); + return tp2; +#ifndef NOFLOAT + } else if (tp2->type == bt_float || tp2->type == bt_double) { +#ifdef XCON_DOESNT_SUPPORT_FLOATS +#error Fix me now :) +#endif + (*ep)->nodetype = en_fcon; + (*ep)->etype = tp2->type; +#ifdef PC + (*ep)->v.f = (double) (*ep)->v.i; +#else +#ifdef BCDFLT + (*ep)->v.f = ffpltof((*ep)->v.i); +#else + (*ep)->v.f = (float) (*ep)->v.i; +#endif +#endif + (*ep)->esize = +#if defined(DOUBLE) || defined(INTEL_386) + tp2->type == bt_float ? tp_float.size : tp_double.size; +#else + float_size; +#endif + return tp2; +#endif + } else { + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + return 0; + } + } +/* if (tp2->type != bt_void && tp1->size > tp2->size) + uwarn("cast to a narrower type loses accuracy");*/ + if (tp1->type == bt_pointer && tp2->type != bt_pointer) + uwarn("cast from pointer to integer is dangerous"); + if (tp2->type == bt_pointer && tp1->size < 4) + uwarn("cast from short to pointer is dangerous"); + if ((tp1->type == bt_func && tp2->type != bt_func) + || (tp2->type == bt_func && tp1->type != bt_func)) + uwarn("implicit cast from '%s' to '%s'",type_str(tp1),type_str(tp2)); + if ((bt_uncastable(tp1->type) || bt_uncastable(tp2->type)) && tp1->type!=tp2->type) + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + +#ifdef NO_TRIVIAL_CASTS + if (tp2->size==tp1->size && (tp2->type==tp1->type + || ((tp2->type^tp1->type)==1 && bt_integral(tp1->type)) + || (tp2->type==bt_pointer && (tp1->type==bt_long || tp1->type==bt_ulong)) + || (tp1->type==bt_pointer && (tp2->type==bt_long || tp2->type==bt_ulong)))) { + if (needs_trivial_casts((*ep)->nodetype)) + goto trivial_cast_do; + (*ep)->etype = tp2->type; + return tp2; + } +trivial_cast_do: +#endif + + ep2 = mk_node(en_cast, *ep, NIL_ENODE); + ep2->etype = tp2->type; + ep2->esize = tp2->size; + + *ep = ep2; + + return tp2; +} + +TYP *force_cast_op(struct enode **ep, TYP *tp1, TYP *tp2) { + struct enode *ep2; + + if (tp1 == 0 || tp2 == 0 || (tp1->type == bt_void && tp2->type != bt_void)) { + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + return 0; + } + if (tp1->type == tp2->type) { + if (tp1->type == bt_struct || tp1->type == bt_union) { + if (tp1->size != tp2->size) + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + } +// return tp2; so that an en_cast enode is generated & the old TYP is saved +#ifdef NO_VERYTRIVIAL_CASTS + return tp2; +#endif + } + opt0(ep); /* to make a constant really a constant */ + + if ((*ep)->nodetype == en_icon) { + if (integral(tp2) || tp2->type == bt_pointer || tp2->type == bt_void) { + long j = (*ep)->v.i; + (*ep)->etype = tp2->type; + (*ep)->esize = tp2->size; + /* + * The cast may affect the value of (*ep)->v.i + */ + (*ep)->v.i = strip_icon(j, tp2->type); + return tp2; +#ifndef NOFLOAT + } else if (tp2->type == bt_float || tp2->type == bt_double) { +#ifdef XCON_DOESNT_SUPPORT_FLOATS +#error Fix me now :) +#endif + (*ep)->nodetype = en_fcon; + (*ep)->etype = tp2->type; +#ifdef PC + (*ep)->v.f = (double) (*ep)->v.i; +#else + (*ep)->v.f = ffpltof((*ep)->v.i); +#endif + (*ep)->esize = +#if defined(DOUBLE) || defined(INTEL_386) + tp2->type == bt_float ? tp_float.size : tp_double.size; +#else + float_size; +#endif + return tp2; +#endif + } else { + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); + return 0; + } + } + if ((bt_uncastable(tp1->type) || bt_uncastable(tp2->type)) && tp1->type!=tp2->type) + uerr(ERR_CAST,type_str(tp1),type_str(tp2)); +/* if (tp2->type == bt_pointer && tp1->size < 4) + uwarn("cast from short to pointer is dangerous");*/ + +#ifdef NO_TRIVIAL_CASTS + if (tp2->size==tp1->size && (tp2->type==tp1->type + || ((tp2->type^tp1->type)==1 && bt_integral(tp1->type)) + || (tp2->type==bt_pointer && (tp1->type==bt_long || tp1->type==bt_ulong)) + || (tp1->type==bt_pointer && (tp2->type==bt_long || tp2->type==bt_ulong)))) { + if (needs_trivial_casts((*ep)->nodetype)) + goto trivial_cast_do; + (*ep)->etype = tp2->type; + return tp2; + } +trivial_cast_do: +#endif + + ep2 = mk_node(en_cast, *ep, (struct enode *)tp1); // the latter is for (int)x=value; + ep2->etype = tp2->type; + ep2->esize = tp2->size; + + *ep = ep2; + + return tp2; +} + +#ifndef isscalar +int integral(TYP *tp) { +/* returns true it tp is an integral type */ + return bt_integral(tp->type); +} +#endif + +long strip_icon(long i, enum(e_bt) type) { +/* + * This function handles the adjustment of integer constants upon + * casts. It forces the constant into the range acceptable for + * the given type. + * This code assumes somehow that longs are 32 bit on the + * machine that runs the compiler, but how do you get this + * machine independent? + */ + switch (type) { + case bt_uchar: /* 0 .. 255 */ +#ifdef PC + i &= 0xff; +#else + i = (long)((unsigned char)i); +#endif + break; + case bt_char: /* -128 .. 127 */ +#ifdef PC + i &= 0xff; + if (i >= 128) + i |= 0xffffff00; +#else + i = (long)((char)i); +#endif + break; + case bt_ushort: /* 0 .. 65535 */ +#ifdef PC + i &= 0xffff; +#else + i = (long)((unsigned short)i); +#endif + break; + case bt_short: /* -32768 .. 32767 */ +#ifdef PC + i &= 0xffff; + if (i >= 32768) + i |= 0xffff0000; +#else + i = (long)((short)i); +#endif + break; + } + return i; +} +// vim:ts=4:sw=4 diff --git a/gtc/src/expr.h b/gtc/src/expr.h new file mode 100644 index 0000000..6e34c41 --- /dev/null +++ b/gtc/src/expr.h @@ -0,0 +1,169 @@ +/* + * GTools C compiler + * ================= + * source file : + * expressions + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef EXPR_H +#define EXPR_H + +/* expression tree descriptions */ + +//enum e_node { +// en_void, +// en_icon/*1*/, en_fcon, en_labcon/*3*/, en_nacon/*4*/, en_autocon/*5*/, +// en_fcall, en_tempref, en_add, en_sub, en_mul, en_mod, +// en_div, en_lsh, en_rsh, en_cond, en_assign/*16*/, en_eq, en_ne, +// en_asadd, en_assub, en_asmul, en_asdiv, en_asmod, en_asrsh, +// en_asxor, +// en_aslsh, en_asand, en_asor, en_uminus, en_not, en_compl, +// en_lt/*32*/, en_le, en_gt, en_ge, en_and, en_or, en_land, en_lor, +// en_xor, en_ainc, en_adec, +// en_ref, en_cast, en_deref, +// en_fieldref, +//}; +/* BEWARE!!! en_add must be even, and en_sub=en_add+1 (used in opt0) */ +enum e_node { + // 0x00 + en_icon, en_fcon, en_labcon, en_nacon, en_autocon, + // 0x05 + en_tempref, en_ref, en_fieldref, + // 0x08 + en_void, + en_compound, + // 0x0A + en_fcall, en_cast, en_add, en_sub, en_mul, en_mod, + // 0x10 + en_div, en_lsh, en_rsh, en_cond, en_assign, en_eq, en_ne, + // 0x17 + en_asadd, en_assub, en_asmul, en_asdiv, en_asmod, en_asrsh, + en_asxor, + // 0x1E + en_aslsh, en_asand, en_asor, en_uminus, en_not, en_compl, + en_lt, en_le, en_gt, en_ge, en_and, en_or, en_land, en_lor, + en_xor, en_ainc, en_adec, + en_deref, +// extensions + en_alloca, +}; +/* below is the list of all nodes that need to have finer type considerations than below : + - char/uchar + - short/ushort + - long/ulong/pointer + - float + - struct + - union + - void + (these are considerations about the *parent* node, not about its children, whose type + may safely be accessed) + */ +#define needs_trivial_casts(x) ( \ + /* pointer vs long/ulong */ \ + (x)==en_fcall || \ + /* signed vs unsigned */ \ + (x)==en_div || (x)==en_mod || (x)==en_mul || (x)==en_rsh || \ + (x)==en_asdiv || (x)==en_asmod || (x)==en_asmul || (x)==en_asrsh || \ + 0) + +/* statement node descriptions */ + +enum e_stmt { + st_expr, st_while, st_for, st_do, st_if, st_switch, + st_case, st_goto, st_break, st_continue, st_label, + st_return, st_compound, st_default, + // GTC extensions + st_loop, st_asm, +}; + +struct xcon { + enum(e_node) nodetype; + enum(e_bt) etype; + long esize; + union { + long i; +#ifndef XCON_DOESNT_SUPPORT_FLOATS +#ifndef NOFLOAT + double f; +#endif +#endif + } v; +}; + +struct enode { + enum(e_node) nodetype; + enum(e_bt) etype; + long esize; + union { + long i; +#ifndef NOFLOAT + double f; +#endif + int enlab; + char *__sp[2]; + struct enode *p[2]; + struct snode *st; + } v; + char bit_width, bit_offset; /* possibly unsigned char */ +}; + +#ifdef AS + #define ensp __sp[1] +#else + #define ensp __sp[0] +#endif +int not_lvalue(struct enode *node); +#define g_lvalue(node) (!not_lvalue(node)) +#define lvalue(node) (!not_lvalue(node)) +#define NIL_ENODE ( (struct enode *) 0) + +struct snode { + enum(e_stmt) stype; + struct snode *next; /* next statement */ + struct enode *exp; /* condition or expression */ + struct snode *s1; /* internal statement */ + union { + struct enode *e; /* condition or expression */ + struct snode *s; /* internal statement (else) */ + long i; /* (case)label or flag */ + } v1, v2; + unsigned int count; /* execution count */ +#ifdef DB_POSSIBLE + int line; +#endif +}; + +#define NIL_SNODE ( (struct snode *) 0) + + +struct cse { + struct cse *next; + struct enode *exp; /* optimizable expression */ + unsigned long uses; /* number of uses */ + unsigned long duses; /* number of dereferenced uses */ + short voidf; /* cannot optimize flag */ +#ifdef INFINITE_REGISTERS + int reg; /* allocated register */ +#else + short reg; /* allocated register */ +#endif +}; + +struct enode *mk_node(enum(e_node) nt, struct enode *v1, struct enode *v2); +struct enode *mk_icon(long v); +struct enode *parmlist(); +struct enode *copynode(); +struct snode *statement(); +struct snode *compound(); + +void opt4(struct enode **); +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/ffplib.h b/gtc/src/ffplib.h new file mode 100644 index 0000000..6be987e --- /dev/null +++ b/gtc/src/ffplib.h @@ -0,0 +1,74 @@ +/* + * GTools C compiler + * ================= + * source file : + * Fast Floating Point routines + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef FFPLIB_H +#define FFPLIB_H +#ifndef str +#define STR(__x) #__x +#define str(__y) STR(__y) +#endif + +#define ffpver ffplib__0000 +#define ffpadd ffplib__0001 +#define ffpsub ffplib__0002 +#define ffpcmp ffplib__0003 +#define ffpcmp_c ffplib__0004 +#define ffpipart ffplib__0005 +#define ffputof ffplib__0006 +#define ffpltof ffplib__0007 +#define ffpftou ffplib__0008 +#define ffpftol ffplib__0009 +#define ffpmul ffplib__000A +#define ffpmulxp ffplib__000B +#define ffpsqr ffplib__000C +#define ffpdiv ffplib__000D +#define ffpftoa ffplib__000E +#define ffpftobcd ffplib__000F +#define ffplog ffplib__0010 +#define ffplog2 ffplib__0011 +#define ffpexp ffplib__0012 +#define ffpexp2 ffplib__0013 +#define ffppwr ffplib__0014 +#define ffpsincos ffplib__0015 +#define ffpsin ffplib__0016 +#define ffpcos ffplib__0017 +#define ffptan ffplib__0018 +#define sqrt ffplib__0019 + +double ffpadd(double a,double b); +double ffpsub(double a,double b); +void ffpcmp(double a,double b); +long ffpcmp_c(double a,double b); +double ffpipart(double a); +double ffputof(unsigned long x); +double ffpltof(long x); +unsigned long ffpftou(double a); // + round +long ffpftol(double a); // + round / floor +double ffpmul(double a,double b); +double ffpdiv(double a,double b); +void ffpftoa(double a,char *s); +void ffpftobcd(double a,void *d); +double ffplog(double a); +double ffplog2(double a); +double ffpexp(double a); +double ffpexp2(double a); +double ffppwr(double a,double b); +// {d0:double, d1:double} ffpsincos(double a); +double ffpsin(double a); +double ffpcos(double a); +double ffptan(double a); +int sqrt(long x); +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/flashend.c b/gtc/src/flashend.c new file mode 100644 index 0000000..9c18919 --- /dev/null +++ b/gtc/src/flashend.c @@ -0,0 +1,24 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) end of flashapp marker + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +asm( +" .text\n" +" .align 4\n" +" .fdat\n" +" .align 4\n" +" .bss\n" +" .align 4\n" +" .fdat\n"); +// vim:ts=4:sw=4 diff --git a/gtc/src/flashhdr.c b/gtc/src/flashhdr.c new file mode 100644 index 0000000..09bc63b --- /dev/null +++ b/gtc/src/flashhdr.c @@ -0,0 +1,210 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) flashapp header + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +//#define TEXT_SEG_SUPPORTED +#ifdef GTDEV +extern const SecureTab SecTab; +const SecureTab *SecTabPtr=&SecTab; +#endif + +#ifdef TEXT_SEG_SUPPORTED +/* note that this is only useful to generate the ASM code below */ #ifdef VERYBASIC_OO +/* note that this is only useful to generate the ASM code below */ static void AP_app(pFrame self, EVENT *ev); +/* note that this is only useful to generate the ASM code below */ FRAME(appObj, OO_SYSTEM_FRAME, 0, OO_APP_FLAGS, 3) +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_FLAGS, APP_INTERACTIVE) +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_NAME, "GTC") +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_PROCESS_EVENT, &AP_app) +/* note that this is only useful to generate the ASM code below */ // ATTR(OO_APP_DEFAULT_MENU, &AppMenu ) +/* note that this is only useful to generate the ASM code below */ ENDFRAME +/* note that this is only useful to generate the ASM code below */ #else +/* note that this is only useful to generate the ASM code below */ #define H_Compile 0 +/* note that this is only useful to generate the ASM code below */ #define H_HELP 100 +/* note that this is only useful to generate the ASM code below */ APP_EXTENSION const extensions[] = { +/* note that this is only useful to generate the ASM code below */ /* function name #, help string #, function index */ +/* note that this is only useful to generate the ASM code below */ #ifdef HAS_CMDLINE_EXTENSION +/* note that this is only useful to generate the ASM code below */ {OO_APPSTRING+H_Compile, OO_APPSTRING+H_HELP+H_Compile, H_Compile }, +/* note that this is only useful to generate the ASM code below */ #endif +/* note that this is only useful to generate the ASM code below */ }; +/* note that this is only useful to generate the ASM code below */ void _scr_main(); +/* note that this is only useful to generate the ASM code below */ APP_EXT_ENTRY const extEntries[] = { +/* note that this is only useful to generate the ASM code below */ {_scr_main, APP_EXT_PROGRAM}, +/* note that this is only useful to generate the ASM code below */ }; +/* note that this is only useful to generate the ASM code below */ void AP_app(pFrame self, EVENT *ev); +/* note that this is only useful to generate the ASM code below */ const char *AP_about(AppID self); +/* note that this is only useful to generate the ASM code below */ FRAME(appObj, OO_SYSTEM_FRAME, 0, OO_APP_FLAGS, 10) +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_FLAGS, APP_INTERACTIVE) +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_NAME, "GTC") +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_TOK_NAME, "gtc") +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_PROCESS_EVENT, &AP_app) +/* note that this is only useful to generate the ASM code below */ #ifdef HAS_CMDLINE_EXTENSION +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_EXT_COUNT, 1) +/* note that this is only useful to generate the ASM code below */ #else +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_EXT_COUNT, 0) +/* note that this is only useful to generate the ASM code below */ #endif +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_EXTENSIONS, extensions) +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_EXT_ENTRIES, extEntries) +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APP_ABOUT, &AP_about) +/* note that this is only useful to generate the ASM code below */ #ifdef HAS_CMDLINE_EXTENSION +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APPSTRING+H_Compile, "compile") +/* note that this is only useful to generate the ASM code below */ ATTR(OO_APPSTRING+H_HELP+H_Compile, "COMPILE A C PROGRAM") +/* note that this is only useful to generate the ASM code below */ #endif +/* note that this is only useful to generate the ASM code below */ ENDFRAME +/* note that this is only useful to generate the ASM code below */ #endif +/* note that this is only useful to generate the ASM code below */ +/* note that this is only useful to generate the ASM code below */ pFrame pAppObj = (pFrame)&appObj; /* Must be 1st! */ +#else +#define CODESEG ".text" +#define DATASEG ".fdat" +#ifdef VERYBASIC_OO +asm( +" .globl appObj\n" +" " CODESEG "\n" +" .align 4\n" +"appObj:\n" +" .long -16777216\n" +" .long 0\n" +" .word 3\n" +" .long 1\n" +" .long 3\n" +"appObjAttr:\n" +" .long 1\n" +" .long 1\n" +" .long 2\n" +" .long __GTC_str\n" +" .long 4\n" +" .long AP_app\n" +"__GTC_str:\n" +" .ascii \"GTC\\0\"\n" +" .align 4\n" +" .globl pAppObj\n" +" " DATASEG "\n" +" .even\n" +"pAppObj:\n" +" .long appObj\n" +" " CODESEG "\n"); +#else +asm( +" " CODESEG "\n" +" .even\n" +#ifdef HAS_CMDLINE_EXTENSION +" .globl extensions\n" +"extensions:" +" .long 4096\n" +" .long 4196\n" +" .word 0\n" +" .globl extEntries\n" +" .even\n" +"extEntries:" +" .long _scr_main\n" +" .word 0\n" +#endif +" .globl appObj\n" +" .even\n" +"appObj:" +" .long -16777216\n" +" .long 0\n" +" .word 3\n" +" .long 1\n" +" .long 10\n" +" .even\n" +"appObjAttr:" +" .long 1\n" +" .long 1\n" +" .long 2\n" +" .long MC0\n" +" .long 3\n" +" .long MC1\n" +" .long 4\n" +" .long AP_app\n" +" .long 7\n" +#ifdef HAS_CMDLINE_EXTENSION +" .long 1\n" +" .long 8\n" +" .long extensions\n" +" .long 9\n" +" .long extEntries\n" +#else +" .long 0\n" +#endif +" .long 18\n" +" .long AP_about\n" +#ifdef HAS_CMDLINE_EXTENSION +" .long 4096\n" +" .long MC2\n" +" .long 4196\n" +" .long MC3\n" +#endif +"MC0:" +" .ascii \"GTC\\0\"\n" +"MC1:" +" .ascii \"gtc\\0\"\n" +#ifdef HAS_CMDLINE_EXTENSION +"MC2:" +" .ascii \"compile\\0\"\n" +"MC3:" +" .ascii \"COMPILE A C PROGRAM\\0\"\n" +#endif +" .globl pAppObj\n" +" " DATASEG "\n" +" .even\n" +"pAppObj:" +" .long appObj\n" +" " CODESEG "\n"); +#endif +#endif + +void _main(); +void _scr_main(); +#define EV_quit() asm(".word $F800+1166") +void AP_app(pFrame self, EVENT *ev) { + switch (ev->Type) { + case CM_STARTTASK: + _scr_main(); + EV_quit(); + break; + } +} + +const char *AP_about(AppID self) { + return "GTC compiler\n\n(c) 2001-2003 by Paul Froissart\n\nInternal beta i1"; +} + +void _scr_main() { + _main(); + // now redraw the screen... (thanks to PpHd for this code) + // 1) the current application + { WINDOW w; + WinOpen(&w,&(WIN_RECT){0,0,239,127},WF_NOBOLD|WF_NOBORDER); + WinActivate(&w); + WinClose(&w); } + // 2) the status bar + ST_showHelp(""); + ST_eraseHelp(); + // 3) the black line +#if !defined(_92) && !defined(_V200) + memset(LCD_MEM+30*(100-7),-1,30); +#else + memset(LCD_MEM+30*(128-7),-1,30); +#endif +} + +#ifdef GTDEV +#include "gtdevcomm.c" +const SecureTab SecTab = { + 0, + Compile +}; +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/flashhdr.h b/gtc/src/flashhdr.h new file mode 100644 index 0000000..24434ee --- /dev/null +++ b/gtc/src/flashhdr.h @@ -0,0 +1,301 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) flashapp header define's + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define OO_HANDLE (0xFF000000u) +#define OO_SYSTEM_FRAME OO_HANDLE +typedef ULONG pFrame; +typedef HANDLE AppID; + +typedef void (* APP_EXT_FUNC)(void); +typedef struct SAppExtension +{ + unsigned long name; + unsigned long help; + unsigned short index; +} APP_EXTENSION; +typedef struct SAppExtEntry +{ + APP_EXT_FUNC extension; + unsigned short flags; +} APP_EXT_ENTRY; +enum {APP_EXT_PROGRAM=0x0000, APP_EXT_FUNCTION=0x0001}; +typedef enum +{ + ACB_BUILTIN =0x0001, + ACB_INSTALLED =0x0002, + ACB_LOCALIZER =0x0004, + ACB_LOCK =0x0008, + ACB_JT_VERSION=0x0010, + ACB_SELECTED =0x0020, + ACB_COLLAPSE =0x0800, + ACB_BG =0x1000, + ACB_COMPRESS =0x4000, + ACB_DELETE =0x8000 +} ACB_Flags; + +#define MAKE_OO_HANDLE(h) ((h) | OO_HANDLE) +#define OO_GET_HANDLE(h) ((h) & ~OO_HANDLE) +#define IS_OO_HANDLE(h) ((h) > OO_HANDLE) +typedef enum {OO_RW=0, OO_RO=1, + OO_SEQ=0, OO_KEYED=2} OO_Flags; +typedef struct +{ + ULONG key; + void *value; +} OO_Attr; +typedef struct SFrameHdr +{ + pFrame parent; + pFrame prototype; + OO_Flags flags; + ULONG first; + ULONG count; +} OO_Hdr; +typedef struct SFrame +{ + OO_Hdr head; + union + { + void *value[65000]; + OO_Attr pair[65000]; + } attr; +} Frame; +typedef void (* const OO_MethodPtr)(void); +#define STRING_FRAME(name, parent, proto, first, count) \ +const OO_Hdr name = \ +{ \ + (pFrame)parent, \ + (pFrame)proto, \ + OO_RO | OO_SEQ, \ + first, \ + count \ +}; \ +static const char * const name##Attr[count] = \ +{ +#define FRAME(name, parent, proto, first, count) \ +const OO_Hdr name = \ +{ \ + (pFrame)parent, \ + (pFrame)proto, \ + OO_RO | OO_KEYED, \ + first, \ + count \ +}; \ +static const OO_Attr name##Attr[count] = \ +{ +#define ATTR(selector, val) {selector, (void *)(val)}, +#define STRING_ATTR(sel, s) {OO_FIRST_STRING+(sel), s}, +#define ENDFRAME }; +#define MAX_APPLET_NAME_SIZE (8) + +#define OO_APP_FLAGS (1) +#define GetAppFlags(obj) \ + (APP_Flags)OO_GetAppAttr(obj,1) +#define SetAppFlags(obj,value) \ + OO_SetAppAttr(obj,1,(void *)value) +#define OO_APP_NAME (2) +#define GetAppName(obj) \ + (UCHAR *)OO_GetAppAttr(obj,2) +#define SetAppName(obj,value) \ + OO_SetAppAttr(obj,2,(void *)value) +#define OO_APP_TOK_NAME (3) +#define GetAppTokName(obj) \ + (UCHAR *)OO_GetAppAttr(obj,3) +#define SetAppTokName(obj,value) \ + OO_SetAppAttr(obj,3,(void *)value) +#define OO_APP_PROCESS_EVENT (4) +#define AppProcessEvent(obj,a) \ + ((void (* const)(pFrame, PEvent))OO_GetAttr(obj,4))(obj,a) +#define OO_APP_DEFAULT_MENU (5) +#define GetAppDefaultMenu(obj) \ + (MENU *)OO_GetAppAttr(obj,5) +#define SetAppDefaultMenu(obj,value) \ + OO_SetAppAttr(obj,5,(void *)value) +#define OO_APP_DEFAULT_MENU_HANDLE (6) +#define GetAppDefaultMenuHandle(obj) \ + (HANDLE)OO_GetAppAttr(obj,6) +#define SetAppDefaultMenuHandle(obj,value) \ + OO_SetAppAttr(obj,6,(void *)value) +#define OO_APP_EXT_COUNT (7) +#define GetAppExtCount(obj) \ + (long)OO_GetAppAttr(obj,7) +#define SetAppExtCount(obj,value) \ + OO_SetAppAttr(obj,7,(void *)value) +#define OO_APP_EXTENSIONS (8) +#define GetAppExtensions(obj) \ + (APP_EXTENSION const *)OO_GetAppAttr(obj,8) +#define SetAppExtensions(obj,value) \ + OO_SetAppAttr(obj,8,(void *)value) +#define OO_APP_EXT_ENTRIES (9) +#define GetAppExtEntries(obj) \ + (APP_EXT_ENTRY const *)OO_GetAppAttr(obj,9) +#define SetAppExtEntries(obj,value) \ + OO_SetAppAttr(obj,9,(void *)value) +#define OO_APP_LOCALIZE (10) +#define AppLocalize(obj,a) \ + ((BOOL (* const)(AppID, UCHAR const *))OO_GetAppAttr(obj,10))(obj,a) +#define OO_APP_UNLOCALIZE (11) +#define AppUnlocalize(obj) \ + ((void (* const)(AppID))OO_GetAppAttr(obj,11))(obj) +#define OO_APP_CAN_DELETE (12) +#define AppCanDelete(obj) \ + ((BOOL (* const)(AppID))OO_GetAppAttr(obj,12))(obj) +#define OO_APP_CAN_MOVE (13) +#define AppCanMove(obj) \ + ((BOOL (* const)(AppID))OO_GetAppAttr(obj,13))(obj) +#define OO_APP_VIEWER (14) +#define AppViewer(obj,a,b,c) \ + ((BOOL (* const)(AppID, BYTE *, WINDOW *, HSYM))OO_GetAppAttr(obj,14))(obj,a,b,c) +#define OO_APP_ICON (15) +#define GetAppIcon(obj) \ + (BITMAP *)OO_GetAppAttr(obj,15) +#define SetAppIcon(obj,value) \ + OO_SetAppAttr(obj,15,(void *)value) +#define OO_APP_EXT_HELP (16) +#define AppExtHelp(obj,a) \ + ((void (* const)(AppID, USHORT))OO_GetAppAttr(obj,16))(obj,a) +#define OO_APP_NOTICE_INSTALL (17) +#define AppNoticeInstall(obj,a) \ + ((void (* const)(AppID, ACB const *))OO_GetAppAttr(obj,17))(obj,a) +#define OO_APP_ABOUT (18) +#define AppAbout(obj) \ + ((char const * (* const)(AppID))OO_GetAppAttr(obj,18))(obj) +#define OO_SFONT (768) +#define Getsfont(obj) \ + (SF_CHAR *)OO_GetAttr(obj,768) +#define Setsfont(obj,value) \ + OO_SetAttr(obj,768,(void *)value) +#define OO_LFONT (769) +#define Getlfont(obj) \ + (LF_CHAR *)OO_GetAttr(obj,769) +#define Setlfont(obj,value) \ + OO_SetAttr(obj,769,(void *)value) +#define OO_HFONT (770) +#define Gethfont(obj) \ + (HF_CHAR *)OO_GetAttr(obj,770) +#define Sethfont(obj,value) \ + OO_SetAttr(obj,770,(void *)value) +#define OO_APP_SFONT (768) +#define GetAppSFont(obj) \ + (SF_CHAR *)OO_GetAppAttr(obj,768) +#define SetAppSFont(obj,value) \ + OO_SetAppAttr(obj,768,(void *)value) +#define OO_APP_LFONT (769) +#define GetAppLFont(obj) \ + (LF_CHAR *)OO_GetAppAttr(obj,769) +#define SetAppLFont(obj,value) \ + OO_SetAppAttr(obj,769,(void *)value) +#define OO_APP_HFONT (770) +#define GetAppHFont(obj) \ + (HF_CHAR *)OO_GetAppAttr(obj,770) +#define SetAppHFont(obj,value) \ + OO_SetAppAttr(obj,770,(void *)value) +#define OO_LANGUAGE (784) +#define GetLanguage(obj) \ + (WORD)OO_GetAttr(obj,784) +#define SetLanguage(obj,value) \ + OO_SetAttr(obj,784,(void *)value) +#define OO_DATE_FORMAT (785) +#define GetDateFormat(obj) \ + (char const *)OO_GetAttr(obj,785) +#define SetDateFormat(obj,value) \ + OO_SetAttr(obj,785,(void *)value) +#define OO_BUILTIN_HELP (786) +#define BuiltinHelp(obj,a) \ + ((void (* const)(pFrame, USHORT))OO_GetAttr(obj,786))(obj,a) +#define OO_KTLIST (800) +#define GetKTList(obj) \ + (keytag const *)OO_GetAttr(obj,800) +#define SetKTList(obj,value) \ + OO_SetAttr(obj,800,(void *)value) +#define OO_CAT_TABLE (801) +#define GetCAT_table(obj) \ + (CATALOG const *)OO_GetAttr(obj,801) +#define SetCAT_table(obj,value) \ + OO_SetAttr(obj,801,(void *)value) +#define OO_CAT_INDEX (802) +#define GetCAT_index(obj) \ + (short const *)OO_GetAttr(obj,802) +#define SetCAT_index(obj,value) \ + OO_SetAttr(obj,802,(void *)value) +#define OO_CAT_COUNT (803) +#define GetCAT_count(obj) \ + (short)OO_GetAttr(obj,803) +#define SetCAT_count(obj,value) \ + OO_SetAttr(obj,803,(void *)value) +#define OO_CHAR_MENU (816) +#define GetCharMenu(obj) \ + (const MENU *)OO_GetAttr(obj,816) +#define SetCharMenu(obj,value) \ + OO_SetAttr(obj,816,(void *)value) +#define OO_CHAR_HANDLER (817) +#define CharHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,817))(obj) +#define OO_APPS_HANDLER (818) +#define AppsHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,818))(obj) +#define OO_FLASH_APPS_HANDLER (819) +#define FlashAppsHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,819))(obj) +#define OO_MATH_HANDLER (820) +#define MathHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,820))(obj) +#define OO_MEM_HANDLER (821) +#define MemHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,821))(obj) +#define OO_STO_HANDLER (822) +#define StoHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,822))(obj) +#define OO_QUIT_HANDLER (823) +#define QuitHandler(obj) \ + ((void (* const)(pFrame))OO_GetAttr(obj,823))(obj) + +#define OO_FIRST_STRING 2048 +#define OO_FIRST_APP_STRING 2048 +#define OO_APPSTRING (OO_FIRST_STRING+OO_FIRST_APP_STRING) +#define OO_FIRST_APP_ATTR 0x10000 +typedef enum {APP_NONE=0, + APP_INTERACTIVE=1, + APP_CON=2, + APP_ACCESS_SYSVARS=4, + APP_BACKGROUND=8} + APP_Flags; + +typedef struct SAppHdr +{ + ULONG magic; + UCHAR name[MAX_APPLET_NAME_SIZE]; + BYTE zeros[24]; + USHORT flags; + ULONG dataLen; + ULONG codeOffset; + ULONG initDataOffset; + ULONG initDataLen; + ULONG optlen; +} AppHdr; +typedef struct SACB +{ + USHORT flags; + AppID myID; + AppID next; + AppID prev; + ULONG publicstorage; + AppHdr const *appHeader; + BYTE const *certhdr; + pFrame appData; +} ACB; +#define MY_ACB(p) ((ACB*)((BYTE*)&(p)-OFFSETOF(ACB,appData))) +#define MY_APP_ID(p) (MY_ACB(p)->myID) +// vim:ts=4:sw=4 diff --git a/gtc/src/func.c b/gtc/src/func.c new file mode 100644 index 0000000..3f589f3 --- /dev/null +++ b/gtc/src/func.c @@ -0,0 +1,471 @@ +/* + * GTools C compiler + * ================= + * source file : + * function routines + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define DECLARE +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +int is_leaf_function CGLOB, uses_link CGLOB, pushed CGLOB; +XLST_TYPE reg_size CGLOB; + + +void funcbottom(void); +void block(struct sym *sp); /* CAUTION : always requires a compound_done() after call */ + +/* function compilation routines */ + +#ifdef REGPARM +SYM *parmsp[CONVENTION_MAX_DATA+1+CONVENTION_MAX_ADDR+1+1]; +#endif +void funcbody(SYM *sp, char *names[], int nparms) { +/* + * funcbody starts with the current symbol being the begin for the local + * block or the first symbol of the parameter declaration + */ + long poffset; + int i, j; + struct sym *sp1, *mk_int(); + int old_global; + long old_spvalue; + XLST_TYPE *p; +#ifdef REGPARM + int regs=sp->tp->rp_dn+sp->tp->rp_an; +#endif + +#ifdef VERBOSE + time_t ltime; +#endif /* VERBOSE */ + +#ifdef VERBOSE + times(&tms_buf); + ltime = tms_buf.tms_utime; +#endif /* VERBOSE */ +/* uses_structassign=0;*/ + lc_auto = 0; + max_scratch = 0; + is_leaf_function = 1; + uses_link = 0; + pushed = 0; + init_node = 0; + old_global = global_flag; + global_flag = 0; + poffset = 8; /* size of return block */ +#ifdef REGPARM + memset(parmsp,0,sizeof(parmsp)); +#endif + /*if (!strcmp(declid,"MnuSel")) + printf("sgio");*/ + if (bt_aggregate(sp->tp->btp->type)) + poffset = 12; + if (!start_block(0)) + dodecl(sc_parms); /* declare parameters */ + /* undeclared parameters are int's */ + if (!lc_auto) /* otherwise there are declared vars that aren't parameters : error */ + for (i = 0; i < nparms; ++i) { + if (!(sp1 = search(names[i], -1, &lsyms))) { + sp1 = mk_int(names[i]); + // do_warning("argument '%s' implicitly declared 'int'",names[i]); + } + old_spvalue = sp1->value.i; + sp1->value.i = poffset; + sp1->storage_class = sc_auto; + #ifdef REGPARM + if (regs) { + int siz; + if (sp1->tp->type==bt_pointer || sp1->tp->type==bt_func) { + /* + * arrays and functions are never passed. They are really + * Pointers + */ + if (sp1->tp->val_flag != 0) { + TYP *tp1 = (TYP *) xalloc((int) sizeof(TYP), _TYP+FUNCBODY); + *tp1 = *(sp1->tp); + sp1->tp = tp1; + tp1->st_flag = 0; + sp1->tp->val_flag = 0; + sp1->tp->size = 4; + } + } + siz=sp1->tp->size; + #ifdef AS + sp1->value.i = -(lc_auto+siz+(siz&1)/* dirty hack, but it works */); + #else + sp1->value.i = -(lc_auto+siz+(siz&1)/* dirty hack, but it works */); +// if (siz&1) printf("[crp]"),getchar(); + #endif + siz+=siz&1; + lc_auto+=siz; + parmsp[i]=sp1; + regs--; +// goto ok_param; + poffset -= siz; /* to undo the effect of the following statements */ + } + #endif + /* + * char, unsigned char, short, unsigned short, enum have been widened + * to int by the caller. This has to be un-done The same is true for + * float/double but float==double actually convert x[] to *x by + * clearing val_flag + * + * It is shown here how to do this correctly, but if we know something + * about the data representation, it can be done much more + * effectively. Therefore, we define MC680X0 and do the cast + * by hand. This means that we can retrieve a char, widened to short + * and put at machine address n, at machine address n+1. This should + * work on most machines. BIGendian machines can do it like it is + * shown here, LOWendian machines must not adjust sp1->value.i The + * function castback is still needed if someone decides to have a + * double data type which is not equivalent to float. + * This approach is, of course, ugly since some + * assumptions on the target machine enter the front end here, but + * they do anyway through the initial value of poffset which is the + * number of bytes that separate the local block from the argument + * block. On a 68000 this are eight bytes since we do a link a6,... + * always. + */ + switch (sp1->tp->type) { + case bt_char: + case bt_uchar: + #ifdef MC680X0 + if (short_option) { + sp1->value.i += 1; + poffset += 2; + } else { + sp1->value.i += 3; + poffset += 4; + } + #endif + #ifdef INTEL_386 + /* note that we only support 32-bit integers */ + poffset += 4; /* byte already right there */ + #endif + break; + case bt_short: + case bt_ushort: + #ifdef MC680X0 + if (short_option) { + poffset += 2; + } else { + sp1->value.i += 2; + poffset += 4; + } + #endif + #ifdef INTEL_386 + poffset += 4; /* word already right there */ + #endif + break; + case bt_float: + #ifdef MC68000 + /* float is the same as double in the 68000 implementation */ + poffset += float_size; + #endif + #ifdef INTEL_386 + castback(poffset, &tp_double, &tp_float); + poffset += 8; + #endif + break; + case bt_pointer: + case bt_func: + poffset += 4; + /* + * arrays and functions are never passed. They are really + * Pointers + */ + if (sp1->tp->val_flag != 0) { + TYP *tp1 = (TYP *) xalloc((int) sizeof(TYP), _TYP+FUNCBODY); + *tp1 = *(sp1->tp); + sp1->tp = tp1; + tp1->st_flag = 0; + sp1->tp->val_flag = 0; + sp1->tp->size = 4; + } + break; + default: + poffset += sp1->tp->size; + break; + } +// ok_param: + /* + * The following code updates the reglst and autolst arrays + * old_spvalue is zero for undeclared parameters (see mk_int), so it + * works. We do a linear search through the reglst and autolst array, + * so this is inefficient. Howewer, these arrays are usually short + * since they only contain the function arguments at moment. In + * short, function argument processing need not be efficient. + */ + p=reglst; j=regptr; while (j--) { + if ((XLST_TYPE)*p++ == (XLST_TYPE)old_spvalue) { + p[-1] = sp1->value.i; + break; + } + } + p=autolst; j=autoptr; while (j--) { + if ((XLST_TYPE)*p++ == (XLST_TYPE)old_spvalue) { + p[-1] = sp1->value.i; + break; + } + } + } + else + /* + * Check if there are declared parameters missing in the argument list. + * (this needs to be done iff lc_auto!=0, so with DETAILED_ERR not defined + * this is just OK) + */ +#ifdef DETAILED_ERR + for (i=0;ivalue.i <= 0) +#endif + error(ERR_ARG); +#ifdef DETAILED_ERR + sp1 = sp1->prev; + } + } +#endif +#ifdef REGPARM + reg_size=lc_auto; +#endif + if (!start_block(0)) + error(ERR_BLOCK); + else { + block(sp); + funcbottom(); + } + global_flag = old_global; + compound_done(); // due to block(sp) +#ifdef VERBOSE + times(&tms_buf); + parse_time += tms_buf.tms_utime - ltime; +#endif /* VERBOSE */ +} + +struct sym *mk_int(char *name) { + struct sym *sp; + TYP *tp; + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM+MK_INT); + tp = (TYP *) xalloc((int) sizeof(TYP),_TYP+MK_INT); + if (short_option) { + tp->type = bt_short; + tp->size = 2; + } else { + tp->type = bt_long; + tp->size = 4; + } +#ifdef NO_CALLOC + tp->btp = 0; + tp->lst.tail = tp->lst.head = 0; tp->lst.hash = 0; + tp->vol_flag = tp->val_flag = tp->const_flag = tp->st_flag = 0; +#ifdef LISTING + tp->sname = 0; +#endif +#endif + sp->name = name; + sp->storage_class = sc_auto; + sp->tp = tp; +#ifdef NO_CALLOC + sp->value.i = 0; /* dummy -> means param is undeclared */ +#endif + append(&sp, &lsyms); + return sp; +} + +void check_table(HTABLE *table) { + SYM *head; + struct htab *ptr; int i; + ptr=&table->h[0]; + i=N_HASH; + while (i--) { + head=ptr->head; + while (head != 0) { + if (head->storage_class == sc_ulabel) { + uerrc2("undefined label '%s'",head->name); +// msg2("*** UNDEFINED LABEL - %s\n", head->name); +#ifdef LISTING + if (list_option) + fprintf(list, "*** UNDEFINED LABEL - %s\n", head->name); +#endif + } + head = head->next; + } + ptr++; + } +} + +void funcbottom(void) { + nl(); + check_table(&labsyms); +#ifdef LISTING +// if (list_option && lsyms.head != 0) { + fprintf(list, "\n\n*** argument symbol table ***\n\n"); + list_table(&lsyms, 0); + fprintf(list, "\n\n\n"); +// } +// if (list_option && labsyms.head != 0) { + fprintf(list, "\n\n*** label symbol table ***\n\n"); + list_table(&labsyms, 0); + fprintf(list, "\n\n\n"); +// } +#endif +#ifdef AS + local_clean(); +#endif + rel_local(); /* release local symbols */ + hashinit(&lsyms); + hashinit(<ags); + hashinit(&labsyms); +} + +extern char *curname; +xstatic struct enode save_sp CGLOBL; +struct snode *dump_stmt; +SYM *func_sp CGLOB; +void block(struct sym *sp) { /* CAUTION : always requires a compound_done() after call */ + struct snode *stmt; + int local_total_errors = total_errors; + int line0; +#ifdef VERBOSE + time_t ltime; +#endif /* VERBOSE */ + +//#ifdef VERBOSE +#ifdef AS + scope_init(); +#endif + func_sp=sp; + /*infunc("fire") + bkpt();*/ +#ifndef GTDEV +#ifdef PC + if (verbose) +#endif + msg2("Compiling '%s'... ", sp->name); +#endif +//#endif /* VERBOSE */ + +#ifdef ICODE + if (icode_option) + if (sp->storage_class == sc_external || sp->storage_class == sc_global) + fprintf(icode, "%s:\n", sp->name); + else + fprintf(icode, "L%ld:\n", sp->value.i); +#endif +#ifdef SHOWSTEP + printf("\nparsing"); +#endif + start_block(1); + line0=prevlineid; + dump_stmt = stmt = compound(-1); +#ifdef SHOWSTEP + printf(" ok "); +#endif +#ifdef VERBOSE + times(&tms_buf); + ltime = tms_buf.tms_utime; +#endif /* VERBOSE */ +/* + * If errors so far, do not try to generate code + */ + if (total_errors > local_total_errors) { + cseg(); + dumplits(); + return; + } + lineid=line0; + genfunc(stmt); +#ifdef VERBOSE + times(&tms_buf); + gen_time += tms_buf.tms_utime - ltime; + ltime = tms_buf.tms_utime; +#endif /* VERBOSE */ + cseg(); + dumplits(); + put_align(AL_FUNC); +#ifndef AS + if (sp->storage_class == sc_external || sp->storage_class == sc_global) + g_strlab(sp->name); + else + put_label((unsigned int) sp->value.i); +#else + put_label(splbl(sp)); +#endif + if (!strcmp(sp->name,"__main") && !search("NO_EXIT_SUPPORT",-1,&defsyms)) { + save_sp.nodetype = en_nacon; + save_sp.etype = bt_pointer; + save_sp.esize = 4; + save_sp.v.ensp = "__save__sp__"; +#ifdef AS + save_sp.v.enlab = label("__save__sp__"); +#endif + g_coder(op_move,4,mk_reg(STACKPTR),mk_offset(&save_sp)); + } + flush_peep(); +#ifdef AS + scope_flush(); +#endif + func_sp=NULL; +#ifdef VERBOSE + times(&tms_buf); + flush_time += tms_buf.tms_utime - ltime; +#endif /* VERBOSE */ +} + +void castback(long offset, TYP *tp1, TYP *tp2) { +/* + * cast an argument back which has been widened on the caller's side. + * append the resulting assignment expression to init_node + */ + struct enode *ep1, *ep2; + + ep2 = mk_node(en_autocon, NIL_ENODE, NIL_ENODE); + ep2->v.i = offset; + ep2->etype = bt_pointer; + ep2->esize = 4; + + ep1 = copynode(ep2); + + ep2 = mk_node(en_ref, ep2, NIL_ENODE); + ep2->etype = tp1->type; + ep2->esize = tp1->size; + + ep2 = mk_node(en_cast, ep2, NIL_ENODE); + ep2->etype = tp2->type; + ep2->esize = tp2->size; + + ep1 = mk_node(en_ref, ep1, NIL_ENODE); + ep1->etype = tp2->type; + ep1->esize = tp2->size; + + ep1 = mk_node(en_assign, ep1, ep2); + ep1->etype = tp2->type; + ep1->esize = tp2->size; + + if (init_node == 0) + init_node = ep1; + else + init_node = mk_node(en_void, init_node, ep1); +} +// vim:ts=4:sw=4 diff --git a/gtc/src/gen.h b/gtc/src/gen.h new file mode 100644 index 0000000..303f938 --- /dev/null +++ b/gtc/src/gen.h @@ -0,0 +1,352 @@ +/* + * GTools C compiler + * ================= + * source file : + * code generator + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef GEN_H +#define GEN_H + +/* addressing modes */ + +#ifdef MC680X0 +#define F_DREG 1 /* data register direct mode allowed */ +#define F_AREG 2 /* address register direct mode allowed */ +#define F_MEM 4 /* memory alterable modes allowed */ +#define F_IMMED 8 /* immediate mode allowed */ +#define F_ALT 7 /* alterable modes */ +#define F_DALT 5 /* data-alterable modes */ +#define F_ALL 15 /* all modes allowed */ +#define F_VOL 16 /* need volatile operand */ +#define F_NOVALUE 32 /* dont need result value */ +#define F_USES 64 /* need result value more than once */ + /* (this forbids autoincrement modes) */ +#define F_DEREF 128 /* for derefenced use only (eg allow #L1) */ +#define F_SRCOP 256 /* for source operand only (eg allow L1(pc)) */ +#endif /* MC680X0 */ + +#ifdef INTEL_386 +#define F_REG 1 /* a register, like %eax, %edi etc. */ +#define F_MEM 2 /* direct, indirect, indexed */ +#define F_IMMED 4 /* immedate */ +#define F_FPSTACK 8 /* top of floating-point stack */ +#define F_NOVALUE 16 /* dont need result value */ +#define F_VOL 32 /* need scratch register */ +#define F_ALL 15 /* any mode */ +#define F_NOEDI 64 /* do not use %edi and %esi */ +#endif /* INTEL_386 */ + +/* The instructions */ + +#ifdef MC680X0 +/* + * The order of the branch instructions must not be changed + * since array revcond[] in the peephole optimizer and + * truejp/falsejp in the code generator rely on them. + * Beware of OUT_AS too. + * In addition, peep::SPEED_OPT assumes that (op_jmp,op_rts)=AREGBASE?2*((x)-AREGBASE-MAX_ADDR)+1:2*((x)-MAX_DATA)) +#define REGEXP_SIZE 20000 +#else +#define reg_t char +#define init_reg_t(x) (x) +#define nil_reg_t 0 +#define AREGBASE 8 +#define FIRSTREG 0 +#define reg_t_to_regexp(x) (x) +#define REGEXP_SIZE 16 +#define TDREGBASE 0 +#endif +#define CONVENTION_MAX_DATA 2 +#define CONVENTION_MAX_ADDR 1 + +/* addressing mode structure */ + +struct amode { + enum(e_am) mode; + struct enode *offset; +/* + * these chars may be unsigned... + */ + reg_t preg, sreg; + char deep, slen; +}; + +#define NIL_AMODE ( (struct amode *) 0) + +/* output code structure */ + +struct ocode { + enum(e_op) opcode; + struct ocode *fwd, *back; + struct amode *oper1, *oper2; + int length; +#ifdef DB_POSSIBLE + int line; +#endif +#ifdef AS + char sz,opt; +#endif +}; +struct lbls { + enum(e_op) opcode; + struct ocode *fwd, *back; + int lab; +}; + +/* register naming, special registers */ + +#ifdef MC680X0 +#ifdef INFINITE_REGISTERS +#define RESULT (TDREGBASE+0) /* register returning function results */ +#define PRESULT (TAREGBASE+0) /* register returning pointer function results */ +#ifdef USE_LINK +#define FRAMEPTR (TAREGBASE+6) /* frame pointer register */ +#else +#define TRUE_FRAMEPTR (TAREGBASE+6) +#define FRAMEPTR (TAREGBASE+8) /* frame pointer pseudo-register */ +#endif +#define STACKPTR (TAREGBASE+7) /* system stack pointer register */ +#else +#define RESULT 0 /* register returning function results */ +#define PRESULT 8 /* register returning pointer function results */ +#ifdef USE_LINK +#define FRAMEPTR 14 /* frame pointer register */ +#else +#define TRUE_FRAMEPTR 14 +#define FRAMEPTR 16 /* frame pointer pseudo-register */ +#endif +#define STACKPTR 15 /* system stack pointer register */ +#endif +#endif /* MC680X0 */ + +#ifdef INTEL_386 +#define RESULT 0 /* reg ret. integer-type function results */ +#define EAX 0 +#define EDX 1 +#define EBX 2 +#define ECX 3 +#define ESI 4 +#define EDI 5 +#define ESP 6 +#define STACKPTR 6 /* system stack pointer */ +#define EBP 7 /* frame pointer */ +#define FRAMEPTR 7 +/* attention: same order as above */ +#define AX 8 +#define DX 9 +#define BX 10 +#define CX 11 +#define SI 12 +#define DI 13 +/* attention: same order as above */ +#define AL 14 +#define DL 15 +#define BL 16 +#define CL 17 + +#define NUMREG REG8(EBP) + +/* + * The code generator does not distinguish between %eax, %ax, %al + * because some assemblers want it strict, the real register names + * are determined when the assembly instruction is PRINTED, e.g. + * code generator produces movb junk,%eax, + * assembly code printer prints movb junk,%al + * The conversion is done by the following macros + */ +#define REG16(X) ((X)-EAX+AX) +#define REG8(X) ((X)-EAX+AL) +#endif + +#ifdef MC680X0 +#ifndef INFINITE_REGISTERS +#define MAX_REG_STACK 30 + +#define MAX_ADDR 1 /* max. scratch address register (A1) */ +#define MAX_DATA 2 /* max. scratch data register (D2) */ +#endif +#endif +#ifdef INTEL_386 +#define MAX_REG 1 /* scratch registers: %eax..%edx */ +#endif + +struct reg_struct { + enum(e_am) mode; + int reg; + int flag; /* flags if pushed or corresponding reg_alloc + * number */ +}; + +struct amode *g_expr(); +struct amode *mk_reg(); +#ifdef MC680X0 +struct amode *temp_data(); +struct amode *temp_addr(); +#endif +#ifdef INTEL_386 +struct amode *get_register(); +#endif +struct amode *mk_offset(); +struct amode *g_cast(); +struct amode *g_fcall(); +struct amode *func_result(); +struct amode *as_fcall(); +#ifdef MC68000 +struct amode *mk_rmask(); +struct amode *mk_smask(); +#endif +struct amode *mk_label(); +struct amode *mk_strlab(); +struct amode *mk_immed(long i); +struct amode *g_offset(); +struct amode *mk_legal(); +struct amode *copy_addr(); +#endif +void truejp(); +void falsejp(); + +void g_code(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2); + +void initstack(); +void freeop(struct amode *ap); +// vim:ts=4:sw=4 diff --git a/gtc/src/gen68k.c b/gtc/src/gen68k.c new file mode 100644 index 0000000..6b7dabc --- /dev/null +++ b/gtc/src/gen68k.c @@ -0,0 +1,3536 @@ +/* + * GTools C compiler + * ================= + * source file : + * code generator for the 68000 + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifndef NOFLOAT +#include "ffplib.h" +#endif + +#ifdef VCG +extern int vcg_lvl; +#endif + +#ifdef MC680X0 +readonly struct amode push = {am_adec, 0, init_reg_t(STACKPTR - AREGBASE), nil_reg_t, 0}, + pop = {am_ainc, 0, init_reg_t(STACKPTR - AREGBASE), nil_reg_t, 0}; +#endif +XLST_TYPE act_scratch CGLOB; + +#ifdef FLINE_RC +int fline_rc CGLOB; +#endif + +/* + * this module contains all of the code generation routines for evaluating + * expressions and conditions. + */ + +#ifdef MC680X0 + +void swap_nodes(struct enode *node); +void opt_compare(struct enode *node); + +struct amode *mk_scratch(long size) { +/* + * returns addressing mode of form offset(FRAMEPTR) + * size is rounded up to AL_DEFAULT + */ + struct amode *ap; + + /* round up the request */ + if (size % AL_DEFAULT) + size += AL_DEFAULT - (size % AL_DEFAULT); + + /* allocate the storage */ + act_scratch += size; + +/* + * The next statement could be deferred and put into the + * routine checkstack(), but this is just safer. + */ + if (act_scratch > max_scratch) + max_scratch = act_scratch; + + ap = (struct amode *) xalloc((int) sizeof(struct amode),AMODE+MK_SCRATCH); + ap->mode = am_indx; + ap->preg = FRAMEPTR - AREGBASE; + ap->offset = mk_icon((long) -(lc_auto+act_scratch)); + return ap; +} + + +struct amode *mk_label(unsigned int lab) { +/* + * construct a reference node for an internal label number. + */ + struct enode *lnode; + struct amode *ap; + lnode = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + lnode->v.enlab = lab; + ap = (struct amode *) xalloc((int) sizeof(struct amode),AMODE+MK_LABEL); + ap->mode = am_direct; + ap->offset = lnode; + return ap; +} + +struct amode *mk_immed(long i) { +/* + * make a node to reference an immediate value i. + */ + struct amode *ap; + struct enode *ep; + ep = mk_icon(i); +/* ep = mk_icon(0l); + ep->v.i = i;*/ + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+MK_IMMED); + ap->mode = am_immed; + ap->offset = ep; + return ap; +} + +struct amode *mk_offset(struct enode *node) { +/* + * make a direct reference to a node. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+MK_OFFSET); + ap->mode = am_direct; + ap->offset = node; + return ap; +} + +struct amode *mk_legal(struct amode *ap, int flags, long size) { +/* + * mk_legal will coerce the addressing mode in ap1 into a mode that is + * satisfactory for the flag word. + */ + struct amode *ap2; + + if (flags & F_NOVALUE) { + freeop(ap); + return 0; + } + + if (size==1) + flags &= ~F_AREG; + + switch (ap->mode) { + case am_immed: + if (!(flags & F_DEREF) && ap->offset +#ifdef EXE_OUT + //&& !exestub_mode -> because it remains profitable to do this + // even with very efficient relocations... +#endif + && (ap->offset->nodetype == en_nacon + || ap->offset->nodetype == en_labcon) +#ifdef AS + && !external(ap->offset->v.enlab) +#else +#if defined(PC) && !defined(DISABLE_OPTS) + && ((long)ap->offset->v.ensp>0x1000 ? internal(ap->offset->v.ensp) : 1) +#endif +#endif + ) { + ap->mode = am_direct; + ap2 = temp_addr(); /* allocate to areg */ + g_code(op_lea, 0, ap, ap2); + if (flags & F_AREG) + return ap2; + freeop(ap2); + ap = temp_data(); + g_code(op_move, (int) (size+(size&1)), ap2, ap); /* if we want a byte, do a move.w, not a move.b */ + if (flags & F_DREG) + return ap; + ierr(MK_LEGAL,1); + } + if (flags & F_IMMED) { + return ap; /* mode ok */ + } + break; + case am_areg: + if (flags & F_AREG && (!(flags & F_VOL) || ap->preg <= MAX_ADDR)) + return ap; + break; + case am_dreg: + if (flags & F_DREG && (!(flags & F_VOL) || ap->preg <= MAX_DATA)) + return ap; + break; + case am_direct: +/* infunc("DrawColorLine") + bkpt();*/ + if (!(flags & F_SRCOP) && !(flags & F_DEREF) && ap->offset +#ifdef EXE_OUT + //&& !exestub_mode -> because it remains rentable to do this + // even with very efficient relocations... +#endif + && (ap->offset->nodetype == en_nacon + || ap->offset->nodetype == en_labcon) +#ifdef AS + && !external(ap->offset->v.enlab) +#else +#if defined(PC) && !defined(DISABLE_OPTS) + && ((long)ap->offset->v.ensp>0x1000 ? internal(ap->offset->v.ensp) : 1) +#endif +#endif + && (flags & F_MEM) + ) { + ap2 = temp_addr(); // allocate to areg + g_code(op_lea, 0, ap, ap2); + ap2 = copy_addr(ap2); + ap2->mode = am_ind; +// if (flags & F_MEM) + return ap2; +/* freeop(ap2); + if ((flags&(F_AREG|F_DEREF))==(F_AREG|F_DEREF) || !(flags&F_DREG)) + ap=temp_addr(); + else ap=temp_data(); +// ap = temp_data(); + g_code(op_move, (int) size, ap2, ap); +// if (flags & F_DREG) + return ap; + ierr(MK_LEGAL,2);*/ + } + /* FALL THROUGH */ + case am_ind: + case am_indx: + case am_indx2: + case am_indx3: + case am_ainc: + if (flags & F_MEM) + return ap; + break; + } + if ((flags & F_DREG) && (flags & F_AREG)) { + /* decide which mode is better */ + if (ap->mode == am_immed) { + if (isbyte(ap->offset)) + flags &= F_DREG; + else if (isshort(ap->offset) && size == 4) + flags &= F_AREG; + } + } + if (flags & F_DREG) { + freeop(ap); /* maybe we can use it... */ + ap2 = temp_data(); /* allocate to dreg */ + g_code(op_move, (int) size, ap, ap2); + return ap2; + } + if (!(flags & F_AREG)) + ierr(MK_LEGAL,3); + if (size < 2) + ierr(MK_LEGAL,4); + freeop(ap); + ap2 = temp_addr(); + g_code(op_move, (int) size, ap, ap2); + return ap2; +} + +int isshort(struct enode *node) { +/* + * return true if the node passed can be generated as a short offset. + */ + return node->nodetype == en_icon && + (node->v.i >= -32768 && node->v.i <= 32767); +} + +int isbyte(struct enode *node) { + return node->nodetype == en_icon && + (node->v.i >= -128 && node->v.i <= 127); +} + + +struct amode *copy_addr(struct amode *ap) { +/* + * copy an address mode structure. + */ + struct amode *newap; + if (ap == 0) + ierr(COPY_ADDR,1); + newap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+COPY_ADDR); + *newap = *ap; + return newap; +} + + +struct amode *g_index(struct enode *node) { +/* + * generate code to evaluate an index node and return the addressing + * mode of the result. + */ + struct amode *ap1, *ap2; + char size=4; +#ifndef FORBID_TABLES + if (node->v.p[0]->nodetype == en_tempref && + node->v.p[1]->nodetype == en_tempref && + (node->v.p[0]->v.i >= AREGBASE || node->v.p[1]->v.i >= AREGBASE)) { + /* both nodes are registers, one is address */ + if (node->v.p[0]->v.i < AREGBASE) { /* first node is data register */ + ap1 = g_expr(node->v.p[1], F_AREG); + ap1 = copy_addr(ap1); + ap1->sreg = (reg_t)node->v.p[0]->v.i; + ap1->mode = am_indx2; /* 0(Ax,Dx) */ + ap1->slen = 4; + ap1->offset = mk_icon(0l); + return ap1; + } else { /* first node is address register */ + ap1 = g_expr(node->v.p[0], F_AREG); + ap2 = g_expr(node->v.p[1], F_AREG | F_DREG); + validate(ap1); + ap1 = copy_addr(ap1); + if (ap2->mode == am_dreg) { + /* 0(Ax,Dx) */ + ap1->mode = am_indx2; + ap1->sreg = ap2->preg; + ap1->slen = 4; + } else { + /* 0(Ax,Ay) */ + ap1->mode = am_indx3; + ap1->sreg = ap2->preg; + ap1->slen = 4; + } + ap1->offset = mk_icon(0l); + return ap1; + } + } +#endif + /* The general case (no tempref) */ + /* put address temprefs first place, data temprefs second place */ + if (node->v.p[1]->nodetype == en_tempref && node->v.p[1]->v.i >= AREGBASE) + swap_nodes(node); + else if (node->v.p[0]->nodetype == en_tempref && node->v.p[0]->v.i < AREGBASE) + swap_nodes(node); + else if (node->v.p[1]->etype==bt_pointer && node->v.p[0]->etype!=bt_pointer) + swap_nodes(node); + + ap1 = g_expr(node->v.p[0], F_AREG | F_IMMED); + if (ap1->mode == am_areg) { + struct enode *ep=node->v.p[1],*tempep=ep; + while (tempep->nodetype==en_cast) /* avoid useless op_ext's */ + if ((tempep=tempep->v.p[0])->esize==2) + size=2, ep=tempep; + ap2 = g_expr(ep, F_AREG | F_DREG | F_IMMED); + validate(ap1); + } else { + ap2 = ap1; + ap1 = g_expr(node->v.p[1], F_AREG/* | F_IMMED*/); + validate(ap2); + } + /* + * possible combinations: + * + * F_AREG + F_IMMED, F_AREG + F_DREG and F_AREG + F_AREG + * (F_IMMED + F_IMMED is now impossible, since it would mean a bug + * in the optimizer, and it does no harm except for optimization + * if such a bug does exist) + */ + + + /* watch out for: tempref(addr) + temp_addr, tempref(addr) + temp_data */ + + if (/*ap1->mode == am_areg && */ap1->preg > MAX_ADDR) { + /* ap1 = tempref address register */ + ap1 = copy_addr(ap1); +#ifndef FORBID_TABLES + if (ap2->mode == am_dreg) { + /* 0(Ax,Dy) */ + ap1->mode = am_indx2; + ap1->sreg = ap2->preg; + ap1->slen = size; + ap1->deep = ap2->deep; + ap1->offset = mk_icon(0l); + return ap1; + } + if (ap2->mode == am_areg) { + /* 0(Ax,Ay) */ + ap1->mode = am_indx3; + ap1->sreg = ap2->preg; + ap1->slen = size; + ap1->deep = ap2->deep; + ap1->offset = mk_icon(0l); + return ap1; + } +#endif +#ifndef FORBID_TABLES + if (ap2->mode == am_immed && /* if FORBID_TABLES, then we */ + (!isshort(ap2->offset))) /* always want ap1 to be F_VOL */ +#endif + /* we want to add to ap1 later... */ + ap1 = mk_legal(ap1, F_AREG | F_VOL, 4l); + } + /* watch out for: temp_addr + tempref(data) */ + +#ifndef FORBID_TABLES + if (/*ap1->mode == am_areg && */ap2->mode == am_dreg && ap2->preg > MAX_DATA) { + ap1 = copy_addr(ap1); + ap1->mode = am_indx2; + ap1->sreg = ap2->preg; + ap1->slen = size; + ap1->offset = mk_icon(0l); + return ap1; + } +#endif +/* if (ap1->mode == am_immed && ap2->mode == am_immed) { + ap1 = copy_addr(ap1); + ap1->offset = mk_node(en_add, ap1->offset, ap2->offset); + ap1->mode = am_direct; + return ap1; + }*/ + if (ap2->mode == am_immed && isshort(ap2->offset)) { + ap1 = mk_legal(ap1, F_AREG, 4l); + ap1 = copy_addr(ap1); + ap1->mode = am_indx; + ap1->offset = ap2->offset; + return ap1; + } + /* ap1 is volatile ... */ + g_code(op_add, size, ap2, ap1);/* add left to address reg */ + ap1 = copy_addr(ap1); + ap1->mode = am_ind; /* mk_ indirect */ + freeop(ap2); /* release any temps in ap2 */ + return ap1; /* return indirect */ +} + +struct amode *g_deref(struct enode *node, enum(e_bt) type, int flags, long size) { +/* + * return the addressing mode of a dereferenced node. + */ + struct amode *ap1; +/* + * If a reference to an aggregate is required, return a pointer to the + * struct instead + */ + if (bt_aggregate(type)) { + return g_expr(node, /*F_ALL*/flags); // possibly BUGGY + } +#ifdef PREFER_POS_VALUES + if (node->nodetype == en_sub && node->v.p[1]->nodetype==en_icon) + node->nodetype = en_add, node->v.p[1]->v.i=-node->v.p[1]->v.i; +#endif + if (node->nodetype == en_add) { + return g_index(node); + } + if (node->nodetype == en_autocon) { +#ifdef BIGSTACK + if (node->v.i >= -32768 && node->v.i <= 32767) { +#endif + ap1 = (struct amode *) xalloc((int) sizeof(struct amode), + AMODE+G_DEREF); + ap1->mode = am_indx; + ap1->preg = FRAMEPTR-AREGBASE; + ap1->offset = mk_icon((long) node->v.i); +#ifdef BIGSTACK + } else { + ap1 = temp_addr(); + g_code(op_move, 4, mk_immed((long) node->v.i), ap1); + g_code(op_add, 4, mk_reg(FRAMEPTR), ap1); + ap1 = copy_addr(ap1); + ap1->mode = am_ind; + } +#endif + return ap1; + } + /* if (lineid==309) + bkpt();*/ + /* special 68000 instructions */ + if (node->nodetype == en_ainc + && (size ==1 || size ==2 || size ==4) + && node->v.p[1]->v.i == size + && node->v.p[0]->nodetype == en_tempref + && node->v.p[0]->v.i >= AREGBASE + && !(flags & F_USES)) { + /* (An)+ */ + ap1 = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+G_DEREF); + ap1->mode = am_ainc; + ap1->preg = (reg_t)(node->v.p[0]->v.i - AREGBASE); + return ap1; + } + if (node->nodetype == en_assub + && (size ==1 || size ==2 || size ==4) + && node->v.p[1]->v.i == -size + && node->v.p[0]->nodetype == en_tempref + && node->v.p[0]->v.i >= AREGBASE + && !(flags & F_USES)) { + /* -(An) */ + ap1 = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+G_DEREF); + ap1->mode = am_adec; + ap1->preg = (reg_t)(node->v.p[0]->v.i - AREGBASE); + return ap1; + } + ap1 = g_expr(node, F_AREG | F_IMMED | F_DEREF); /* generate address */ + ap1 = copy_addr(ap1); +#ifdef PC + if (ap1->mode != am_areg && ap1->mode != am_immed) + ierr(G_DEREF,1); +#endif + am_doderef(ap1->mode); + return mk_legal(ap1,flags,size); // mk_legal was missing here : F_VOL wasn't + // taken into a count... +} + +struct amode *g_fderef(struct enode *node, struct amode *ap0, int flags) { +/* + * get a bitfield value + */ + struct amode *ap, *ap1; + long mask; + int width = node->bit_width; + int offs = (node->esize<<3)-node->bit_offset-width; + + if (!ap0) + ap = g_deref(node->v.p[0], node->etype, flags, node->esize); + else ap = ap0; + ap = mk_legal(ap, F_DREG|F_VOL, node->esize); + if (offs > 0) { + if (offs <= 8) { + /* can shift with quick constant */ + g_code(op_lsr, (int) node->esize, + mk_immed((long) offs), ap); + } else { + /* must load constant first */ + ap1 = temp_data(); + g_code(op_moveq, 0, mk_immed((long) offs), ap1); + g_code(op_lsr, (int) node->esize, ap1, ap); + freeop(ap1); + } + } + /*mask = 0; + while (width--) + mask = mask + mask + 1;*/ + mask = (1<esize, mk_immed(mask), ap); + + return mk_legal(ap, flags, node->esize); +} + + +struct amode *g_unary(struct enode *node, int flags, enum(e_op) op) { +/* + * generate code to evaluate a unary minus or complement. float: unary minus + * calls a library function + */ + struct amode *ap; +#ifdef DOUBLE + long i; +#endif + if (flags & F_NOVALUE) { + return g_expr(node->v.p[0], flags); + } + switch (node->etype) { + case bt_uchar: + case bt_char: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_pointer: + ap = g_expr(node->v.p[0], F_DREG | F_VOL); + g_code(op, (int) node->esize, ap, NIL_AMODE); + return mk_legal(ap, flags, node->esize); +#ifndef NOFLOAT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + if (op == op_neg) { +#ifdef DOUBLE + temp_inv(); + i = push_param(node->v.p[0]); + call_library(str(ffpneg)); + return func_result(flags, i); +#else + int null_lab = nxtlabel(); + struct amode *ap = g_expr(node->v.p[0], F_DREG | F_VOL); + g_code(op_tst, 4, ap, NIL_AMODE); + g_code(op_beq, 0, mk_label(null_lab), NIL_AMODE); + g_code(op_neg, 4, ap, NIL_AMODE); + g_label(null_lab); + return mk_legal(ap, flags, node->esize); +#endif + } +#endif + } + ierr(G_UNARY,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_addsub(struct enode *node, int flags, enum(e_op) op) { +/* + * generate code to evaluate a binary node and return the addressing mode of + * the result. + */ + struct amode *ap1, *ap2; + long i; + if (flags & F_NOVALUE) { + g_expr(node->v.p[0], flags); + return g_expr(node->v.p[1], flags); + } + switch (node->etype) { + case bt_uchar: + case bt_char: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_pointer: + flags &= (F_DREG | F_AREG); +#ifdef LONG_ADDS_IN_AREG + if (node->v.p[1]->nodetype==en_icon && node->esize==4 +#if 1 + && !((unsigned long)(i=node->v.p[1]->v.i)+8<=16) + && (long)(short)i==i +#else + && (i=node->v.p[1]->v.i,(long)(short)i==i) +#endif + && (flags&F_AREG)) + flags = F_AREG; +#endif +#ifdef TWOBYTE_ARRAY_EXTRA_OPT + if (node->v.p[1]->nodetype==en_lsh && node->v.p[1]->v.p[1]->nodetype==en_icon + && node->v.p[1]->v.p[1]->v.i==1) { + ap1 = g_expr(node->v.p[0], F_VOL | flags); + ap2 = g_expr(node->v.p[1]->v.p[0], F_ALL | F_SRCOP | F_USES); + validate(ap1); /* in case push occurred */ + g_code(op, (int) node->esize, ap2, ap1); + g_code(op, (int) node->esize, ap2, ap1); + } else { +#endif + ap1 = g_expr(node->v.p[0], F_VOL | flags); + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + validate(ap1); /* in case push occurred */ + g_code(op, (int) node->esize, ap2, ap1); +#ifdef TWOBYTE_ARRAY_EXTRA_OPT + } +#endif + freeop(ap2); + return mk_legal(ap1, flags, node->esize); +#ifndef NOFLOAT + case bt_double: + temp_inv(); + i = push_param(node->v.p[1]); + i += push_param(node->v.p[0]); + switch (op) { + case op_add: + call_library(str(ffpadd)); + break; + case op_sub: + call_library(str(ffpsub)); + break; + } + return func_result(flags, i); +#endif + } + + ierr(G_ADDSUB,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_xbin(struct enode *node, int flags, enum(e_op) op) { +/* + * generate code to evaluate a restricted binary node and return the + * addressing mode of the result. + * these are bitwise operators so don't care about the type. + * This needs to be revised with scalar types longer than 32 bit + */ + struct amode *ap1, *ap2; + ap1 = g_expr(node->v.p[0], F_VOL | F_DREG); + ap2 = g_expr(node->v.p[1], F_DREG); + validate(ap1); /* in case push occurred */ + g_code(op, (int) node->esize, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, node->esize); +} + +struct amode *g_shift(struct enode *node, int flags, enum(e_op) op); +int equalnode(struct enode *node1, struct enode *node2); +struct amode *g_ybin(struct enode *node, int flags, enum(e_op) op) { +/* + * generate code to evaluate a restricted binary node and return the + * addressing mode of the result. + */ + struct amode *ap1, *ap2; +#ifdef GENERATE_ROL_ROR + if ( + (op==op_or || op==op_eor) && + node->v.p[0]->nodetype==en_lsh && node->v.p[1]->nodetype==en_rsh && bt_uns(node->v.p[1]->etype) && + node->v.p[0]->v.p[1]->nodetype==en_icon && node->v.p[1]->v.p[1]->nodetype==en_icon && + equalnode(node->v.p[0]->v.p[0],node->v.p[1]->v.p[0]) + ) { + long lsh = node->v.p[0]->v.p[1]->v.i; + long rsh = node->v.p[1]->v.p[1]->v.i; + long sz = lsh+rsh; + if (lsh>=0 && rsh>=0 && sz==8*node->esize) { + int need_swap = 0; + if (lsh>8 && rsh>8) { + need_swap = 1; + if (lsh>=16) + lsh-=16,rsh+=16; + else + rsh-=16,lsh+=16; + } + if (!lsh || !rsh) { + ap1 = g_expr(node->v.p[0]->v.p[0], F_DREG | F_VOL); + } else { + int shift_left = lsh<=8; + struct enode *ep1,*ep2; + ep1 = mk_icon(shift_left?lsh:rsh); + ep1->etype = bt_uchar; + ep1->esize = 1; + ep2 = mk_node(en_lsh, node->v.p[0]->v.p[0], ep1); + ep2->etype = node->etype; + ep2->esize = node->esize; + ap1 = g_shift(ep2, F_DREG|F_VOL, shift_left?op_rol:op_ror); + } + if (need_swap) + g_code(op_swap, (int)node->esize, ap1, NIL_AMODE); + return mk_legal(ap1, flags, node->esize); + } else { + // we could do better, but hey, we're lazy, aren't we? + } + } +#endif + ap1 = g_expr(node->v.p[0], F_VOL | F_DREG); + ap2 = g_expr(node->v.p[1], (F_ALL & ~F_AREG) | F_SRCOP); + validate(ap1); /* in case push occurred */ + g_code(op, (int) node->esize, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, node->esize); +} +#ifdef VCG +typedef struct amode *(*COMMUTATIVE_G)(struct enode *node,int flags,enum(e_op) op); +typedef struct amode *(*REVERSAL_G)(struct amode *ap, struct enode *ep,int flags); +//struct amode *symmetric(struct amode *ap, struct enode *ep,int flags) { +// if (ap==NULL) return (struct amode *)(void *)flags; +// return ap; +//} +//struct amode *antisymmetric(struct amode *ap, struct enode *ep,int flags) { +// if (ap==NULL) return (struct amode *)(void *)(F_DREG|F_VOL); +// g_code(op_neg, ep->esize, ap, NIL_AMODE); +// return mk_legal(ap,flags,ep->esize); +//} +enum { symmetric = 0 }; // antisymmetric is not supported +struct amode *g_commute(void *func,struct enode *node,int flags,enum(e_op) op,int dummy/*void *reversal*/) { + if (vcg_init()) { + struct amode *ap = NULL; + struct enode *n0=node->v.p[0],*n1=node->v.p[1]; + int o1,o2; + //struct amode *ap; + ((COMMUTATIVE_G)func)(node,flags,op); + o1=vcg_done(); + node->v.p[0]=n1,node->v.p[1]=n0; + vcg_init(); + ((COMMUTATIVE_G)func)(node,flags,op); + //((REVERSAL_G)reversal)(((COMMUTATIVE_G)func) + // (node,(int)((REVERSAL_G)reversal)(NULL,node,flags),op),node,flags); + o2=vcg_done(); + if (o2<=o1) + ap = ((COMMUTATIVE_G)func)(node,flags,op); + //ap = ((REVERSAL_G)reversal)(((COMMUTATIVE_G)func) + // (node,(int)((REVERSAL_G)reversal)(NULL,node,flags),op),node,flags); + node->v.p[0]=n0,node->v.p[1]=n1; /* always restore the original node, even when reverse is better! */ + if (ap) + return ap; + } + return ((COMMUTATIVE_G)func)(node,flags,op); +} +#endif + +struct amode *g_shift(struct enode *node, int flags, enum(e_op) op) { +/* + * generate code to evaluate a shift node and return the address mode of the + * result. + */ + struct amode *ap1,*ap2; + + if (op == op_lsl && node->v.p[1]->nodetype == en_icon + && (node->v.p[1]->v.i == 1 +#ifndef HARDCORE_FOR_UNPACKED_SIZE +#ifdef SPEED_OPT + || ((speed_opt_value>=0 +#ifdef EXE_OUT + || exestub_mode +#endif + ) && node->v.p[1]->v.i == 2) +#else + || node->v.p[1]->v.i == 2 +#endif +#endif + )) { + int i; + ap1 = g_expr(node->v.p[0], F_VOL | (flags & (F_DREG | F_AREG))); + i = node->v.p[1]->v.i-1; + do + g_code(op_add, (int) node->esize, ap1, ap1); + while (i--); + } else { + ap1 = g_expr(node->v.p[0], F_DREG | F_VOL); + ap2 = g_expr(node->v.p[1], F_DREG | F_IMMED); + validate(ap1); + + /* quick constant only legal if 1<=const<=8 */ + if (ap2->mode == am_immed && ap2->offset->nodetype == en_icon + && (ap2->offset->v.i > 8 || ap2->offset->v.i < 1)) { + if (ap2->offset->v.i <= 0 || ap2->offset->v.i > 32) + uwarn("shift constant out of range"); +#ifdef USE_SWAP_FOR_SHIFT16 + if ((unsigned int)ap2->offset->v.i <= 16 && node->esize==4) { + /* validate(ap1); -> useless since ap2 is am_immed :) */ + g_code(op_swap, 0, ap1, NIL_AMODE); + if ((ap2->offset->v.i -= 16)) { + ap2 = mk_immed(-ap2->offset->v.i); + op = (op==op_lsl?op_ror:op_rol); /* since op might be op_asr too */ + g_code(op, (int) node->esize, ap2, ap1); + } + #error The following bugs... ((long)x)<<16 => ext/swap/ext #roll# + /* to be improved since it normally results from 'long' shifts and surrounding + g_cast does not recurse down to the shift node... + The current optimization is nevertheless useful with respect to speed. */ + if (node->esize==4) g_code(op_ext, (int) node->esize, ap1, NIL_AMODE); + goto ok_shift; + } else +#endif + ap2 = mk_legal(ap2, F_DREG, 1l); + } + g_code(op, (int) node->esize, ap2, ap1); +#ifdef USE_SWAP_FOR_SHIFT16 + ok_shift: +#endif + freeop(ap2); + } + return mk_legal(ap1, flags, node->esize); +} + +struct amode *g_div(struct enode *node, int flags) { +/* + * generate code to evaluate a divide operator + */ + struct amode *ap1, *ap2; + long i; + switch (node->etype) { + case bt_short: + case bt_ushort: + ap1 = g_expr(node->v.p[0], F_DREG | F_VOL); + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + validate(ap1); + if (node->etype == bt_short) { + g_code(op_ext, 4, ap1, NIL_AMODE); + g_code(op_divs, 0, ap2, ap1); + } else { + g_code(op_and, 4, mk_immed(65535l), ap1); + g_code(op_divu, 0, ap2, ap1); + } + freeop(ap2); + return mk_legal(ap1, flags, 2l); + case bt_long: + case bt_ulong: + case bt_double: + temp_inv(); + i = push_param(node->v.p[1]); + i += push_param(node->v.p[0]); + switch (node->etype) { + case bt_long: + call_library("__divsi3"); + break; + case bt_ulong: + case bt_pointer: + call_library("__udivsi3"); + break; +#ifndef NOFLOAT + case bt_double: + call_library(str(ffpdiv)); + break; +#endif + } + return func_result(flags, i); + } + ierr(G_DIV,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_mod(struct enode *node, int flags) { +/* + * generate code to evaluate a mod operator + */ + struct amode *ap1, *ap2; + long i; + switch (node->etype) { + case bt_short: + case bt_ushort: + ap1 = g_expr(node->v.p[0], F_DREG | F_VOL); + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + validate(ap1); + if (node->etype == bt_short) { + g_code(op_ext, 4, ap1, NIL_AMODE); + g_code(op_divs, 0, ap2, ap1); + } else { + g_code(op_and, 4, mk_immed(65535l), ap1); + g_code(op_divu, 0, ap2, ap1); + } + g_code(op_swap, 0, ap1, NIL_AMODE); + freeop(ap2); + return mk_legal(ap1, flags, 2l); + case bt_long: + case bt_ulong: + temp_inv(); + i = push_param(node->v.p[1]); + i += push_param(node->v.p[0]); + if (node->etype == bt_long) + call_library("__modsi3"); + else + call_library("__umodsi3"); + return func_result(flags, i); + } + ierr(G_MOD,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +void swap_nodes(struct enode *node) { +/* + * exchange the two operands in a node. + */ + struct enode *temp; + temp = node->v.p[0]; + node->v.p[0] = node->v.p[1]; + node->v.p[1] = temp; +} + +struct amode *g_mul(struct enode *node, int flags) { + struct amode *ap1, *ap2; +#ifdef OLD_GCCLIKE_MULSI3 + long i; +#endif +/* switch (node->etype) { + case bt_long: + case bt_ulong: + if (node->v.p[0]->nodetype == en_icon) + swap_nodes(node); + ap1 = g_expr(node->v.p[0], F_DREG | F_VOL); + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + validate(ap1); + if (node->etype == bt_long) + g_code(op_muls, 0, ap2, ap1); + else + g_code(op_mulu, 0, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, 2l); + case bt_pointer: + case bt_double: + temp_inv(); + i = push_param(node->v.p[1]); + i += push_param(node->v.p[0]); + if (node->etype == bt_ulong) + call_library(".ulmul"); // obsolete + else if (node->etype == bt_double) + call_library(".fpmult"); // obsolete + else + call_library(".lmul"); // obsolete + return func_result(flags, i); + }*/ + switch (node->etype) { + case bt_short: + case bt_ushort: + if (node->v.p[0]->nodetype == en_icon) + swap_nodes(node); + ap1 = g_expr(node->v.p[0], F_DREG | F_VOL); + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + validate(ap1); + if (node->v.p[0]->etype == bt_short) + g_code(op_muls, 0, ap2, ap1); + else + g_code(op_mulu, 0, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, 2l); + case bt_ulong: + case bt_long: + case bt_pointer: + case bt_double: + temp_inv(); +#ifdef OLD_GCCLIKE_MULSI3 + i = push_param(node->v.p[1]); + i += push_param(node->v.p[0]); +#ifndef NOFLOAT + if (node->etype == bt_double) + call_library(str(ffpmul)); + else +#endif + call_library("__mulsi3"); /* it's the same function for ulong & long :) */ + return func_result(flags, i); +#else + { char *libfunc="__mulsi3_rp"; + if (tst_ushort(node->v.p[0])) + swap_nodes(node); + if (tst_ushort(node->v.p[1])) { /* favour ushort rather than short! */ + node->v.p[1]->etype=bt_ushort; + node->v.p[1]->esize=2; + libfunc="__mulsi3ui2_rp"; + } else { + if (tst_short(node->v.p[0])) + swap_nodes(node); + if (tst_short(node->v.p[1])) { + node->v.p[1]->etype=bt_short; + node->v.p[1]->esize=2; + libfunc="__mulsi3si2_rp"; + } + } + ap1 = g_expr(node->v.p[0], F_DREG | F_VOL); /* put it in D0 */ + ap2 = g_expr(node->v.p[1], F_DREG | F_VOL); /* put it in D1 */ + validate(ap1); + call_library(libfunc); + freeop(ap2); + return mk_legal(ap1, flags, 4l); + } +#endif + } + ierr(G_MUL,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +/* + * Returns a complexity measure (in terms of time) of the given node, if it's constant. + * If it's not, returns -128. + */ +int complexity(struct enode *ep) { + int comp=1; + if (!ep) return 0; +restart: + switch (ep->nodetype) { + case en_icon: + if (ep->v.i) comp++; + case en_tempref: + comp--; + case en_fcon: + case en_nacon: + case en_labcon: + case en_autocon: + return comp; + case en_fcall: + case en_assign: + case en_asadd: case en_assub: + case en_asmul: case en_asmod: case en_asdiv: + case en_aslsh: case en_asrsh: + case en_asand: case en_asor: case en_asxor: + case en_ainc: case en_adec: + case en_alloca: + return -128; + case en_cond: +// msg("DEBUG: complexity\n"); + return -128; + case en_compound: +// msg("DEBUG: complexity\n"); + return -128; + case en_mod: case en_div: + comp+=2; + case en_mul: + comp+=2; + case en_void: + case en_add: case en_sub: + case en_lsh: case en_rsh: + case en_and: case en_or: case en_xor: + case en_eq: case en_ne: + case en_lt: case en_le: case en_gt: case en_ge: + case en_land: case en_lor: + comp+=complexity(ep->v.p[0]); + if (comp<0) return -128; + { + int comp2=complexity(ep->v.p[1]); + if (comp2<0) return -128; + return comp+comp2; + } + case en_ref: + case en_fieldref: + case en_deref: + case en_uminus: case en_not: + case en_compl: + case en_cast: + comp++; + ep=ep->v.p[0]; + goto restart; + default: + fatal("COMPLEXITY"); + return 0; // make the compiler happy + } +} + +struct amode *g_hook(struct enode *node, int flags) { +/* + * generate code to evaluate a condition operator node (?:) + */ + struct amode *ap1, *ap2; + unsigned int false_label, end_label; + int flagx; + int result_is_void; + long size=node->esize; + struct enode *vnode=node->v.p[1]; +#ifdef VCG + int alternatives = complexity(node->v.p[0]); + int best_flagx; + unsigned int cost1=-1,cost2=-1; +#endif + end_label = nxtlabel(); + + result_is_void = (node->etype == bt_void); + if (bt_aggregate(node->etype)) { + size = 4; + } + + if (!result_is_void) { + flagx = (flags & (F_DREG | F_AREG)) == F_AREG ? + F_AREG | F_VOL : F_DREG | F_VOL; +#ifdef VCG + best_flagx = vcg_lvl?-1:flagx; +#endif + } else { +#ifdef VCG + best_flagx = +#endif + flagx = F_ALL | F_SRCOP | F_NOVALUE; + } + +// temp_inv(); /* I do not think I can avoid that */ + +#ifdef VCG + best_flagx=flagx; + while (1) { + if (best_flagx<0) + vcg_init(); // always succeeds, otherwise best_flagx would be flagx +#endif + if (vnode->v.p[0]) { + /* all scratch registers are void */ +#ifdef OPTIMIZED_HOOK + struct ocode *old_peep_tail=peep_tail; + int old_max_reg=max_reg; + max_reg=0; +#endif +#ifdef VCG + if (vcg_lvl && alternatives IS_VALID) { + int alt1,alt2,norm; + if (complexity(vnode->v.p[1])>=0) { + vcg_init(); + ap1 = g_expr(vnode->v.p[1], flagx); + falsejp(node->v.p[0], end_label); + if (ap_hasbeenpushed(ap1)) { + validate(ap1); + freeop(ap1); + vcg_done(); + best_flagx=0; + goto classic_fashion; + } + freeop(ap1); + alt1=vcg_cost()>>3; + ap2 = g_expr(vnode->v.p[0], flagx); + alt1+=vcg_done(); + } else alt1=32767; + swap_nodes(vnode); + if (complexity(vnode->v.p[1])>=0) { + vcg_init(); + ap1 = g_expr(vnode->v.p[1], flagx); + truejp(node->v.p[0], end_label); + if (ap_hasbeenpushed(ap1)) + ierr(G_HOOK,3); + freeop(ap1); + alt2=vcg_cost()>>3; + ap2 = g_expr(vnode->v.p[0], flagx); + alt2+=vcg_done(); + } else alt2=32767; + swap_nodes(vnode); + vcg_init(); + false_label = nxtlabel(); + falsejp(node->v.p[0], false_label); + norm=vcg_cost()>>3; + ap1 = g_expr(vnode->v.p[0], flagx); + freeop(ap1); + g_code(op_bra, 0, mk_label(end_label), NIL_AMODE); + g_label(false_label); + ap2 = g_expr(vnode->v.p[1], flagx); + norm+=vcg_done(); + + if (norm>alt1 && norm>alt2) { + if (alt2v.p[1], flagx); + (alt2>=alt1?falsejp:truejp) + (node->v.p[0], end_label); + freeop(ap1); + ap2 = g_expr(vnode->v.p[0], flagx); + if (alt2v.p[0]),c2=complexity(vnode->v.p[1]); + if (c1>=0 || c2>=0) { + if ((unsigned)c1<(unsigned)c2) + swap_nodes(vnode); + ap1 = g_expr(vnode->v.p[1], flagx); + ((unsigned)c1<(unsigned)c2?truejp:falsejp) + (node->v.p[0], end_label); + freeop(ap1); + ap2 = g_expr(vnode->v.p[0], flagx); + if ((unsigned)c1<(unsigned)c2) + swap_nodes(vnode); + } else { +#endif + classic_fashion: + false_label = nxtlabel(); + falsejp(node->v.p[0], false_label); + + /* all scratch registers are void */ + ap1 = g_expr(vnode->v.p[0], flagx); + freeop(ap1); + + /* all scratch registers are void */ + g_code(op_bra, 0, mk_label(end_label), NIL_AMODE); + + g_label(false_label); + + ap2 = g_expr(vnode->v.p[1], flagx); +#if defined(ALTERNATE_HOOK) || defined(OPTIMIZED_HOOK) + } +#endif + done: + if (!result_is_void && !equal_address(ap1,ap2)) + ierr(G_HOOK,1); + + } else { + ap1 = g_expr(node->v.p[0], flagx); + /* all scratch registers are void */ + g_code(op_tst, (int)node->v.p[0]->esize, ap1, NIL_AMODE); + freeop(ap1); + g_code(op_bne, 0, mk_label(end_label), NIL_AMODE); + ap2 = g_expr(vnode->v.p[1], flagx); + if (!result_is_void && !equal_address(ap1,ap2)) + ierr(G_HOOK,2); + } + g_label(end_label); + +#ifdef VCG + if (best_flagx>=0) +#endif + return mk_legal(ap2, flags, size); +#ifdef VCG + if (best_flagx<0) { + cost1=cost2; + cost2=vcg_done(); + if (!(flags&F_AREG) || size==1 || flagx==(F_AREG|F_VOL)) + best_flagx = cost1etype) { + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_pointer: + if (flags & F_NOVALUE) + f = F_ALL; + else + f = F_ALL | F_USES; + ap1 = g_expr(node->v.p[0], f); + if (ap1->mode==am_dreg || ap1->mode==am_areg) + f = F_ALL | F_SRCOP; + else f = F_DREG | F_IMMED; + ap2 = g_expr(node->v.p[1], f); + validate(ap1); + g_code(op, (int) node->esize, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, node->esize); +#ifndef NOFLOAT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + if (op == op_add) + return as_fcall(node, flags, str(ffpadd)); + else + return as_fcall(node, flags, str(ffpsub)); +#endif + } + ierr(G_ASADD,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +readonly xstatic int bits_for_size[4]={7,15,0,31}; +void g_bitmancode(enum(e_op) op,int size,struct amode *ap1,struct amode *ap2) { + struct amode *ap3=0; + if (ap2->mode!=am_dreg && size && size!=1) { + int bits_to_skip; + if (ap1->mode!=am_immed || ap1->offset->nodetype!=en_icon) + uerrc("illegal address mode"); + bits_to_skip=bits_for_size[size-1]-ap1->offset->v.i; + while (bits_to_skip>=8) { + if (!ap3) ap3=copy_addr(ap2),ap3->offset=copynode(ap3->offset); + if (ap3->mode==am_ind) + ap3->mode=am_indx,ap3->offset=mk_icon(0); + if (ap3->offset->nodetype==en_icon) + ap3->offset->v.i++; + else ap3->offset=mk_node(en_add,ap3->offset,mk_icon(1)),opt4(&ap3->offset); + bits_to_skip-=8; + } + ap1=mk_immed(7-bits_to_skip); + } + if (!ap3) ap3=ap2; + g_code(op,ap2->mode==am_dreg?4:1,ap1,ap3); +} +#ifdef BITWISE_REDUCE +/* the latter relies on the big-endianness of the 68k */ +int bitwise_reduction(unsigned long x,int *size) { + if (!x) return; // anyway the constant folder will already have taken care :) + int offs=0,end_offs=0; + unsigned long v=0xFF<<((*size-1)*8); + while (!(x&v)) offs++,x<<=8; + if (!(x&(v>>8))) { + if (!(x&(v>>16)) && !(x&(v>>24))) + *size=4; + else *size=2; + } else *size=1; + if (*size==1) { + if (offs==1 && v!=0xFF) /* avoid such a case... (unless *size _was_ already 1) */ + offs=0,*size=2; + } else if (offs&1) /* too bad... we can do nothing */ + offs=0,*size=4; + return offs; +} +readonly int deflt_types[5]={0,bt_uchar,bt_ushort,0,bt_ulong}; +void bitwise_optimize(struct enode *ep,long mode) { + long *ref=0; + /* we may not call swap_nodes here! VCG needs to preserve the order */ + if (ep->v.p[0]->nodetype==en_icon && ep->v.p[1]->nodetype==en_ref) + ref=&ep->v.p[0]->v.i; + else if (ep->v.p[1]->nodetype==en_icon && ep->v.p[0]->nodetype==en_ref) + ref=&ep->v.p[1]->v.i; + if (ref) { + int offs=bitwise_reduction((*ref)^mode,&ep->esize); + ep->etype=deflt_types[ep->esize]; + ep->v.p[0]->etype= +#endif + +struct amode *g_asxor(struct enode *node, int flags) { +/* + * generate an ^= node + */ + int f; + struct amode *ap1, *ap2; + switch (node->etype) { + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_pointer: + if (flags & F_NOVALUE) + f = F_ALL; + else + f = F_ALL | F_USES; + ap1 = g_expr(node->v.p[0], f); + if (ap1->mode==am_dreg || ap1->mode==am_areg) + f = F_ALL | F_SRCOP; + else f = F_DREG | F_IMMED; + ap2 = g_expr(node->v.p[1], f); + validate(ap1); + if (ap2->mode==am_immed && ap1->mode!=am_dreg && ap1->mode!=am_areg) { + int i,n=0,j=0; long z=ap2->offset->v.i; + for (i=0;i<8*node->esize;i++) + if (z&(1<esize, mk_immed(j), ap1); + } else g_code(op_eor, (int) node->esize, ap2, ap1); + } else g_code(op_eor, (int) node->esize, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, node->esize); + } + ierr(G_ASXOR,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_aslogic(struct enode *node, int flags, enum(e_op) op) { + /* + * generate a&= or a|= + */ + int f; + struct amode *ap1, *ap2, *ap3; + if (flags & F_NOVALUE) + f = F_ALL; + else + f = F_ALL | F_USES; + ap1 = g_expr(node->v.p[0], f); + if (ap1->mode==am_dreg || ap1->mode==am_areg) + f = (F_ALL & ~F_AREG) | F_SRCOP; + else f = F_DREG | F_IMMED; + ap2 = g_expr(node->v.p[1], f); + validate(ap1); + if (ap1->mode != am_areg) { + if (/*(op==op_and || op==op_or || op==op_eor) && */ap2->mode==am_immed + && ap1->mode!=am_dreg && ap1->mode!=am_areg + && (node->esize==1/* || (ap1->mode!=am_ainc && ap1->mode!=am_adec)*/)) { + int i,n=-1,j=0,and=(op==op_and); long z=ap2->offset->v.i; + for (i=0;i<8*node->esize;i++) + if ((!!(z&(1<esize!=1) { + ap3 = copy_addr(ap1); + switch (ap1->mode) { + case am_ind: + ap3->mode=am_indx; + ap3->offset=mk_immed( + }*/ + g_bitmancode(and?op_bclr:(op==op_or?op_bset:op_bchg), + 0/* ALWAYS .B !!! */, mk_immed(j), ap3); + goto asdone; + } + } + g_code(op, (int) node->esize, ap2, ap1); + } else { + ap3 = temp_data(); + g_code(op_move, 4, ap1, ap3); + g_code(op, (int) node->esize, ap2, ap3); + g_code(op_move, (int) node->esize, ap3, ap1); + freeop(ap3); + } +asdone: + freeop(ap2); + return mk_legal(ap1, flags, node->esize); +} + +struct amode *g_asshift(struct enode *node, int flags, enum(e_op) op) { + /* + * generate shift equals operators. + */ + int f; + struct amode *ap1, *ap2, *ap3; + switch (node->etype) { + case bt_uchar: + case bt_char: + case bt_ushort: + case bt_short: + case bt_ulong: + case bt_long: + case bt_pointer: + if (flags & F_NOVALUE) + f = F_ALL; + else + f = F_ALL | F_USES; + ap1 = g_expr(node->v.p[0], f); + if (ap1->mode != am_dreg) { + ap3 = temp_data(); + g_code(op_move, (int) node->esize, ap1, ap3); + } else + ap3 = ap1; + ap2 = g_expr(node->v.p[1], F_DREG | F_IMMED); + + /* add if const=1 and op is << */ + if (op==op_lsl && ap2->mode == am_immed && ap2->offset->nodetype == en_icon + && ap2->offset->v.i == 1) { + op=op_add; ap2=ap3; + } + /* quick constant if 2<=const<=8 */ + if (ap2->mode == am_immed && ap2->offset->nodetype == en_icon + && (ap2->offset->v.i > 8 || ap2->offset->v.i < 1)) { + /*if (ap2->offset->v.i <= 0) + uwarn("negative shift constant");*/ + ap2 = mk_legal(ap2, F_DREG, 1l); + } + validate(ap3); + g_code(op, (int) node->esize, ap2, ap3); + if (ap2 != ap3) + freeop(ap2); + if (ap3 != ap1) { + g_code(op_move, (int) node->esize, ap3, ap1); + freeop(ap3); + } + return mk_legal(ap1, flags, node->esize); + } + ierr(G_ASSHIFT,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_asmul(struct enode *node, int flags) { + /* + * generate a *= node. + */ + struct amode *ap1, *ap2, *ap3; + enum(e_op) op = op_mulu; + switch (node->etype) { + case bt_char: + ap1 = g_expr(node->v.p[0], F_ALL | F_USES); + if (ap1->mode != am_dreg) { + ap2 = temp_data(); + g_code(op_move, 1, ap1, ap2); + } else + ap2 = ap1; + g_code(op_ext, 2, ap2, NIL_AMODE); + ap3 = g_expr(node->v.p[1], F_DREG | F_IMMED); + if (ap3->mode == am_dreg) + g_code(op_ext, 2, ap3, NIL_AMODE); + validate(ap2); + g_code(op_muls, 0, ap3, ap2); + freeop(ap3); + if (ap2 != ap1) { + validate(ap1); + g_code(op_move, 1, ap2, ap1); + freeop(ap2); + } + return mk_legal(ap1, flags, node->esize); + case bt_uchar: + ap1 = g_expr(node->v.p[0], F_ALL | F_USES); + if (ap1->mode != am_dreg) { + ap2 = temp_data(); + g_code(op_move, 1, ap1, ap2); + } else + ap2 = ap1; + g_code(op_and, 2, mk_immed(255l), ap2); + ap3 = g_expr(node->v.p[1], F_DREG | F_IMMED); + if (ap3->mode == am_dreg) + g_code(op_and, 2, mk_immed(255l), ap3); + validate(ap2); + g_code(op_mulu, 0, ap3, ap2); + freeop(ap3); + if (ap2 != ap1) { + validate(ap1); + g_code(op_move, 1, ap2, ap1); + freeop(ap2); + } + return mk_legal(ap1, flags, node->esize); + case bt_short: + op = op_muls; + case bt_ushort: + ap1 = g_expr(node->v.p[0], F_ALL | F_USES); + ap2 = g_expr(node->v.p[1], F_ALL); + validate(ap1); + if (ap1->mode != am_dreg) { + ap3 = temp_data(); + g_code(op_move, 2, ap1, ap3); + g_code(op, 0, ap2, ap3); + freeop(ap2); + freeop(ap3); + g_code(op_move, 2, ap3, ap1); + } else { + g_code(op_muls, 0, ap2, ap1); + freeop(ap2); + } + return mk_legal(ap1, flags, node->esize); + case bt_long: + case bt_ulong: + case bt_pointer: + return as_fcall(node, flags, "__mulsi3"); +#ifndef NOFLOAT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return as_fcall(node, flags, str(ffpmul)); +#endif + } + ierr(G_ASMUL,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_asdiv(struct enode *node, int flags) { +/* + * generate /= and %= nodes. + */ + struct amode *ap1, *ap2, *ap3; + switch (node->etype) { + case bt_char: + ap1 = g_expr(node->v.p[0], F_ALL | F_USES); + if (ap1->mode != am_dreg) { + ap2 = temp_data(); + g_code(op_move, 1, ap1, ap2); + } else + ap2 = ap1; + g_code(op_ext, 2, ap2, NIL_AMODE); + g_code(op_ext, 4, ap2, NIL_AMODE); + ap3 = g_expr(node->v.p[1], F_DREG | F_IMMED); + if (ap3->mode == am_dreg) + g_code(op_ext, 2, ap3, NIL_AMODE); + validate(ap2); + g_code(op_divs, 0, ap3, ap2); + freeop(ap3); + if (ap2 != ap1) { + validate(ap1); + g_code(op_move, 1, ap2, ap1); + freeop(ap2); + } + return mk_legal(ap1, flags, node->esize); + case bt_uchar: + ap1 = g_expr(node->v.p[0], F_ALL | F_USES); + if (ap1->mode != am_dreg) { + ap2 = temp_data(); + g_code(op_move, 1, ap1, ap2); + } else + ap2 = ap1; + g_code(op_and, 4, mk_immed(255l), ap2); + ap3 = g_expr(node->v.p[1], F_DREG | F_IMMED); + if (ap3->mode == am_dreg) + g_code(op_and, 2, mk_immed(255l), ap3); + validate(ap2); + g_code(op_divu, 0, ap3, ap2); + freeop(ap3); + if (ap2 != ap1) { + validate(ap1); + g_code(op_move, 1, ap2, ap1); + freeop(ap2); + } + return mk_legal(ap1, flags, node->esize); + case bt_short: + case bt_ushort: + ap1 = temp_data(); + ap2 = g_expr(node->v.p[0], F_ALL | F_USES); + validate(ap1); + g_code(op_move, 2, ap2, ap1); + ap3 = g_expr(node->v.p[1], F_ALL & ~F_AREG); + validate(ap2); + validate(ap1); + if (node->etype == bt_short) { + g_code(op_ext, 4, ap1, NIL_AMODE); + g_code(op_divs, 0, ap3, ap1); + } else { + g_code(op_and, 4, mk_immed(65535l), ap1); + g_code(op_divu, 0, ap3, ap1); + } + freeop(ap3); + g_code(op_move, 2, ap1, ap2); + freeop(ap2); + return mk_legal(ap1, flags, 2l); + case bt_long: + return as_fcall(node, flags, "__divsi3"); + case bt_ulong: + case bt_pointer: + return as_fcall(node, flags, "__udivsi3"); +#ifndef NOFLOAT +#ifdef DOUBLE + case bt_double: +#endif + case bt_float: + return as_fcall(node, flags, str(ffpdiv)); +#endif + } + ierr(G_ASDIV,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +struct amode *g_asmod(struct enode *node, int flags) { +/* + * generate /= and %= nodes. + */ + struct amode *ap1, *ap2, *ap3; + switch (node->etype) { + case bt_short: + case bt_ushort: + ap1 = temp_data(); + ap2 = g_expr(node->v.p[0], F_ALL | F_USES); + validate(ap1); + g_code(op_move, 2, ap2, ap1); + ap3 = g_expr(node->v.p[1], F_ALL & ~F_AREG); + validate(ap2); + validate(ap1); + if (node->etype == bt_short) { + g_code(op_ext, 4, ap1, NIL_AMODE); + g_code(op_divs, 0, ap3, ap1); + } else { + g_code(op_and, 4, mk_immed(65535l), ap1); + g_code(op_divu, 0, ap3, ap1); + } + g_code(op_swap, 0, ap1, NIL_AMODE); + freeop(ap3); + g_code(op_move, 2, ap1, ap2); + freeop(ap2); + return mk_legal(ap1, flags, 2l); + case bt_long: + return as_fcall(node, flags, ".lrem"); + case bt_ulong: + case bt_pointer: + return as_fcall(node, flags, ".ulrem"); + } + ierr(G_ASMOD,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +void structassign(struct amode *ap1, struct amode *ap2, long size, int mode) { +/* + * assign structure from ap1 to ap2 + * ap1, ap2 are scratch address registers + */ +#ifdef BIGMEM + long loop_c; +#else + int loop_c; +#endif + int rest; + struct amode *ap3; + unsigned int label; + + ap1 = copy_addr(ap1); + ap2 = copy_addr(ap2); + ap1->mode = mode; + ap2->mode = mode; + loop_c = size >> 2; + rest = (int) (size & 3); + if (loop_c <= 5) /* loop-unrolling */ + while (loop_c--) + g_code(op_move, 4, ap1, ap2); + else { + loop_c--; /* for dbra */ + ap3 = temp_data(); + freeop(ap3); + label = nxtlabel(); +#ifdef BIGMEM + if (loop_c <= 65535) { // single loop +#endif + g_code(op_move, 2, mk_immed(loop_c), ap3); + g_label(label); + g_code(op_move, 4, ap1, ap2); + g_code(op_dbra, 0, ap3, mk_label(label)); +#ifdef BIGMEM + } else { // extended loop + g_code(op_move, 4, mk_immed(loop), ap3); + g_label(label); + g_code(op_move, 4, ap1, ap2); + g_code(op_dbra, 0, ap3, mk_label(label)); + g_code(op_sub, 4, mk_immed(65536l), ap3); + g_code(op_bhs, 0, mk_label(label), NIL_AMODE); + } +#endif + } +#if AL_DEFAULT!=2 + if (rest >= 2) { + rest -= 2; + g_code(op_move, 2, ap1, ap2); + } + + /* This cannot happen if the size of structures is always even */ + if (rest) + g_code(op_move, 1, ap1, ap2); +#ifdef SHORT_STRUCT_PASSING +#error "Much of the short struct stuff assumes that structs whose size is under 4 \ + really are short structs (while they aren't, since to do an assignment of a \ + 3-byte struct, you have to do 2 moves, if not 3...)" +#error "So let AL_DEFAULT be 2." +#endif +#else + if (rest) + g_code(op_move, 2, ap1, ap2); +#endif +} + +struct amode *g_assign(struct enode *node, int flags) { +/* + * generate code for an assignment node. + */ + int f; + struct amode *ap1, *ap2, *ap3; + struct enode *ep; + long size = node->esize; + if (flags & F_NOVALUE) + f = F_ALL; + else + f = F_ALL | F_USES; + if (bt_aggregate(node->etype)) { +#ifdef SHORT_STRUCT_PASSING + if (node->esize<=4) { + ap1 = g_expr(node->v.p[1], F_AREG); + ap2 = g_expr(node->v.p[0], F_AREG); + validate(ap1); + structassign(ap1, ap2, (long)node->esize, am_ind); + freeop(ap2); + return mk_legal(ap1, flags, 4l); + } +#endif + /* + * Other parts of this module return a pointer to a struct in a register, + * not the struct itself + */ + ap1 = g_expr(node->v.p[1], F_AREG | F_VOL); + ap2 = g_expr(node->v.p[0], F_AREG | F_VOL); + validate(ap1); + + /* hacky: save ap1 if needed later, structassign destroys it */ + if (!(flags & F_NOVALUE)) { + ap3 = temp_addr(); + /* BTW, this code gets eliminated with MAX_ADDR = 1 */ + g_code(op_move, 4, ap1, ap3); + structassign(ap3, ap2, (long)size, am_ainc); + freeop(ap3); + freeop(ap2); + validate(ap1); + return mk_legal(ap1, flags, 4l); + } else { /* no need to save any registers */ + structassign(ap1, ap2, (long)node->esize, am_ainc); + freeop(ap2); + /* mk_legal is a no-op here */ + return mk_legal(ap1, flags, 4l); + } + } + if (node->v.p[0]->nodetype == en_fieldref) { + long mask; + int i; + /* + * Field assignment + */ + +#ifdef OLD_FIELD_ASSIGN + /* get the value */ + ap1 = g_expr(node->v.p[1], F_DREG | F_VOL); + i = node->v.p[0]->bit_width; + mask = 0; + while (i--) + mask = mask + mask + 1; + g_code(op_and, (int) size, mk_immed(mask), ap1); + i = (node->v.p[0]->esize<<3)-node->v.p[0]->bit_offset-node->v.p[0]->bit_width; + mask <<= i; + if (!(flags & F_NOVALUE)) { + /* + * result value needed + */ + ap3 = temp_data(); + g_code(op_move, 4, ap1, ap3); + } else + ap3 = ap1; + if (i > 0) { + if (i == 1) { + /* add dn,dn */ + g_code(op_add, (int) node->esize, ap3, ap3); + } else if (i <= 8) { + g_code(op_lsl, (int) size, + mk_immed(i), ap3); + } else { + ap2 = temp_data(); + g_code(op_moveq, 0, + mk_immed(i), ap2); + g_code(op_lsl, (int) size, ap2, ap3); + freeop(ap2); + } + } + ep = mk_node(en_ref, node->v.p[0]->v.p[0], NIL_ENODE); + ep->esize = 1; + ap2 = g_expr(ep, F_MEM); + validate(ap3); + g_code(op_and, (int) size, mk_immed(~mask), ap2); + g_code(op_or, (int) size, ap3, ap2); + freeop(ap2); + if (!(flags & F_NOVALUE)) { + freeop(ap3); + validate(ap1); + } +#else + { + ep = mk_node(en_ref, node->v.p[0]->v.p[0], NIL_ENODE); + ep->esize = node->v.p[1]->esize; + ep->etype = node->v.p[1]->etype; + ap2 = g_expr(ep, F_MEM); + + ep=node->v.p[1]; + /* get the value */ + i = node->v.p[0]->bit_width; + mask = 0; + while (i--) + mask = mask + mask + 1; + ep = mk_node(en_and, ep, mk_icon(mask)); + ep->esize=ep->v.p[0]->esize; + ep->etype=ep->v.p[0]->etype; + ep->v.p[1]->esize=ep->esize; + ep->v.p[1]->etype=ep->etype; + i = (node->v.p[0]->esize<<3)-node->v.p[0]->bit_offset-node->v.p[0]->bit_width; + mask <<= i; + ep = mk_node(en_lsh, ep, mk_icon(i)); + ep->esize=ep->v.p[0]->esize; + ep->etype=ep->v.p[0]->etype; + ep->v.p[1]->esize=1; + ep->v.p[1]->etype=bt_char; + opt0(&ep); + ap1 = g_expr(ep, F_DREG | F_IMMED); + validate(ap2); + if (ap1->mode==am_immed && node->v.p[0]->bit_width==1) { + // note that thus, we need not free/validate anything... + if (!((~ap1->offset->v.i)&mask)) { + ap1->offset->v.i = i; + g_bitmancode(op_bset, (int)size, ap1, ap2); + freeop(ap2); + if (!(flags & F_NOVALUE)) + return mk_legal(mk_immed(1L),flags,node->esize); + return NIL_AMODE; + } else if (!(ap1->offset->v.i&mask)) { + ap1->offset->v.i = i; + g_bitmancode(op_bclr, (int)size, ap1, ap2); + freeop(ap2); + if (!(flags & F_NOVALUE)) + return mk_legal(mk_immed(0L),flags,node->esize); + return NIL_AMODE; + } + } else { + g_code(op_and, (int) size, mk_immed(~mask), ap2); + g_code(op_or, (int) size, ap1, ap2); + freeop(ap1); + if (!(flags & F_NOVALUE)) + return g_fderef(node->v.p[0], ap2, flags); + freeop(ap2); + return NIL_AMODE; + } + } +#endif + return mk_legal(ap1, flags, size); + } + /* + * (uns.) char, (uns.) short, (uns.) long, float + * + * we want to pass the right hand side as the expression value. This can't + * be done if the left side is a register variable on which the right + * hand side addressing mode depends. But if the left side IS a register + * variable, it is desirable to pass the left side, so no problem. + */ + if (node->v.p[0]->nodetype == en_tempref) { + /* pass the left side as expr. value */ + ap1 = g_expr(node->v.p[0], f); + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + validate(ap1); + g_code(op_move, (int) size, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, size); + } else { + /* pass the right side as expr. value */ + /* normally, this is more efficient */ + ap1 = g_expr(node->v.p[1], f | F_SRCOP); + ap2 = g_expr(node->v.p[0], F_ALL); + validate(ap1); + g_code(op_move, (int) size, ap1, ap2); + freeop(ap2); + return mk_legal(ap1, flags, size); + } +} + +struct amode *g_aincdec(struct enode *node, int flags, enum(e_op) op) { +/* + * generate an auto increment or decrement node. op should be either op_add + * (for increment) or op_sub (for decrement). + */ + struct amode *ap1, *ap2; + switch (node->etype) { + case bt_uchar: + case bt_char: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: + case bt_pointer: + if (flags & F_NOVALUE) {/* dont need result */ + ap1 = g_expr(node->v.p[0], F_ALL); + g_code(op, (int) node->esize, mk_immed((long) node->v.p[1]->v.i), + ap1); + return mk_legal(ap1, flags, node->esize); + } + if (flags & F_DREG) + ap1 = temp_data(); + else + ap1 = temp_addr(); + ap2 = g_expr(node->v.p[0], F_ALL | F_USES); + validate(ap1); + g_code(op_move, (int) node->esize, ap2, ap1); + g_code(op, (int) node->esize, mk_immed((long) node->v.p[1]->v.i), ap2); + freeop(ap2); + return mk_legal(ap1, flags, node->esize); + } + ierr(G_AINCDEC,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +long push_param(struct enode *ep) { +/* + * push the operand expression onto the stack. return the number of bytes + * pushed + */ + struct amode *ap; +#ifdef OLD_STRUCT_PUSH + struct amode *ap1; +#endif + long size = ep->esize; + int old_pushed; + + /* pushing of aggregates: (short) structures and unions, as well as BCD floats */ + if (bt_aggregate(ep->etype)) { + if (ep->nodetype==en_ref) + ep = ep->v.p[0]; + /* all other cases return a pointer to the struct anyway */ +#ifdef OLD_STRUCT_PUSH + /* allocate stack space */ + g_code(op_sub, 4, mk_immed(size), mk_reg(STACKPTR)); + /* + * F_VOL was missing in the following line -- + * it took a hard-core debugging session to find this error + */ + ap = g_expr(ep, F_AREG | F_VOL); + ap1 = temp_addr(); + validate(ap); + g_code(op_move, 4, mk_reg(STACKPTR), ap1); + /* now, copy it on stack - the same as structassign */ + structassign(ap, ap1, size, am_ainc); + freeop(ap1); + freeop(ap); +#else + if ((size&1)) size++; /* otherwise there will be a bunch of problems */ + + { + struct enode *ep2=mk_icon(size); + ep2->etype=bt_long; ep2->esize=4; + ep = mk_node(en_add,ep,ep2); + ep->etype=bt_pointer; ep->esize=4; + opt0(&ep); + ap = g_expr(ep, F_AREG | F_VOL); + /* now, copy it on stack - the same as structassign */ + structassign(ap, mk_reg(STACKPTR), size, am_adec); + freeop(ap); + } +#endif + return size; + } + old_pushed = pushed; + pushed = 0; + ap = g_expr(ep, F_ALL | F_DEREF); + + /* + * This is a hook for the peephole optimizer, which will convert lea + * ,An + pea (An) ==> pea + */ + +#ifdef POP_OPT + if (old_pushed && pushed) + g_code(_op_adj, 0, NIL_AMODE, NIL_AMODE); +#endif + pushed = 1; + if ((ap->mode == am_areg || ap->mode == am_immed) + && size == 4 && ap->preg <= MAX_ADDR) { + ap = copy_addr(ap); + am_doderef(ap->mode); + g_code(op_pea, 0, ap, NIL_AMODE); + } else + g_code(op_move, (int) size, ap, push_am); + freeop(ap); + return size+(size&1); +} + +int req_all_aregs(struct enode *plist,int rp_dn,int rp_an) { + /* requires all regs if and only if (num_params>=regs_num || num_pointers>=aregs_num) */ + rp_dn+=rp_an; + while (plist) { + if (!--rp_dn) return 1; + if (plist->v.p[0]->etype==bt_pointer && !--rp_an) return 1; + plist=plist->v.p[1]; + } + return 0; +} + +long g_parms(struct enode *plist +#ifdef REGPARM + , int rp_dn, int rp_an, struct amode **a1ap +#endif + ) { +/* + * push a list of parameters onto the stack and return the number of + * parameters pushed. + */ +#ifdef BIGSTACK + long i=0; +#else + int i=0; +#endif + pushed = 0; +#ifdef REGPARM +#ifdef PC + if (rp_dn IS_INVALID || rp_an IS_INVALID) + ierr(G_PARMS,1); +#endif + if (rp_dn || rp_an) { + int nr=rp_dn+rp_an,np=0,n; + struct enode *ep=plist,**p,**dp,**ap,*allocbase[16],*list[16]; + struct amode deep[CONVENTION_MAX_DATA+1+CONVENTION_MAX_ADDR+1],*deepp; + while (ep) np++, ep=ep->v.p[1]; + /* first, push stack params while all the temp registers are free */ + while (np>nr) { + i += push_param(plist->v.p[0]); + plist = plist->v.p[1]; + np--; + } + /* store the last params so we can examinate them in the correct order */ + n=np; while (n--) list[n]=plist->v.p[0], plist=plist->v.p[1]; + /* now, fill in 'allocbase' */ + p=list; dp=&allocbase[0]; ap=&allocbase[8]; + n=np; while (n--) { + ep=*p++; + if ((ep->etype==bt_pointer && rp_an) || !rp_dn) + *ap++=ep, rp_an--; + else *dp++=ep, rp_dn--; + } + *ap=NULL; *dp=NULL; + /* finally, load all the parameters into the correct registers */ + dp=&allocbase[0]; ap=&allocbase[8]; + deepp=deep; + n=8; while (n--) { /* push d0/a0/d1/a1/... */ + if (*dp) { +//#ifdef PC + struct amode *amp= +//#endif + g_expr(*dp++,F_DREG|F_VOL); +#ifdef INFINITE_REGISTERS + struct amode *ap2 = (struct amode *) xalloc((int) sizeof(struct amode), 0); + ap2->mode = am_dreg; + ap2->preg = TDREGBASE+dp-allocbase-1; + g_code(op_move, dp[-1]->esize, amp, ap2); + freeop(amp); + amp=ap2; +#endif +#ifdef PC + if (amp->mode!=am_dreg || amp->preg!=TDREGBASE+dp-allocbase-1) + ierr(REGPARM,1); +#endif + *deepp++=*amp; + } + if (*ap) { +//#ifdef PC + struct amode *amp= +//#endif + *a1ap = g_expr(*ap++,F_AREG|F_VOL); +#ifdef INFINITE_REGISTERS + struct amode *ap2 = (struct amode *) xalloc((int) sizeof(struct amode), 0); + ap2->mode = am_areg; + ap2->preg = TDREGBASE+ap-allocbase-1-8; + g_code(op_move, ap[-1]->esize, amp, ap2); + freeop(amp); + amp=ap2; +#endif +#ifdef PC + if (amp->mode!=am_areg || amp->preg!=TDREGBASE+ap-allocbase-1-8) + ierr(REGPARM,2); +#endif + *deepp++=*amp; + } + } + while (deepp>deep) + validate(--deepp); + } else { +#endif + while (plist != 0) { + i += push_param(plist->v.p[0]); + plist = plist->v.p[1]; + } +#ifdef REGPARM + } +#endif + return i; +} + +struct amode *func_result(int flags, long bytes) { + /* + * saves a function call result in D0 it is assumed that flags contain + * either F_DREG or F_AREG return value is the addressing mode of the + * result bytes is the number of bytes to pop off the stack + * + * This routine does not use mk_legal and takes care of the stuff itself. + */ + struct amode *ap; + if (bytes != 0) + /* adjust stack pointer */ + g_code(op_add, 4, mk_immed(bytes), mk_reg(STACKPTR)); + if (flags & F_NOVALUE) + return 0; + if (flags & F_DREG) { + ap = temp_data(); + g_code(op_move, 4, mk_reg(RESULT), ap); + } else if (flags & F_AREG) { + ap = temp_addr(); + g_code(op_move, 4, mk_reg(RESULT), ap); +#ifdef PC + } else { + ierr(FUNC_RESULT,1); + return 0; // make the compiler happy +#endif + } + return ap; +} + +struct amode *func_result2(int flags, long bytes, int reg) { + /* + * Saves a function call result in REG. It is assumed that flags contain + * either F_DREG or F_AREG. Return value is the addressing mode of the + * result; bytes is the number of bytes to pop off the stack + * + * This routine does not use mk_legal and takes care of the stuff itself. + */ + struct amode *ap; + if (bytes != 0) /* adjust stack pointer */ + g_code(op_add, 4, mk_immed(bytes), mk_reg(STACKPTR)); + if (flags & F_NOVALUE) + return 0; + if ((flags & F_DREG) && reg==RESULT) { // permet d'viter move.l a0,d0 / + ap = temp_data(); // move.l d0,rn #roll# + g_code(op_move, 4, mk_reg(reg), ap); + } else if (flags & F_AREG) { + ap = temp_addr(); + g_code(op_move, 4, mk_reg(reg), ap); + } else { +#ifdef PC + if (flags & F_DREG) { +#endif + ap = temp_data(); + g_code(op_move, 4, mk_reg(reg), ap); +#ifdef PC + } else { + ierr(FUNC_RESULT,2); + return 0; // make the compiler happy + } +#endif + } + return ap; +} + +struct amode *as_fcall(struct enode *node, int flags, char *libname) { +/* assignment operations with library calls */ + long i; + struct amode *ap1; + long size; + size = node->esize; + temp_inv(); + i = push_param(node->v.p[1]); + if (node->v.p[0]->nodetype == en_tempref) { + /* ap1 cannot be destroyed, no problem */ + ap1 = g_expr(node->v.p[0], F_DREG | F_AREG); + g_code(op_move, (int) size, ap1, push_am); + i += size; + call_library(libname); + /* ap1 is always valid and not equal to RESULT */ + g_code(op_move, (int) size, mk_reg(RESULT), ap1); + } else { + uwarn("possible flaw in lib call"); + ap1 = g_expr(node->v.p[0], F_DREG | F_AREG); + g_code(op_move, (int) size, ap1, push_am); + i += size; + call_library(libname); + /* ap1 is always valid and not equal to RESULT */ + g_code(op_move, (int) size, mk_reg(RESULT), ap1); + } + g_code(op_add, 4, mk_immed((long) i), mk_reg(STACKPTR)); + if (!(flags & F_NOVALUE)) { + if (flags & F_AREG) + ap1 = temp_addr(); + else + ap1 = temp_data(); + g_code(op_move, 4, mk_reg(RESULT), ap1); + return mk_legal(ap1, flags, size); + } else + return 0; +} + +#ifndef __HAVE_REGS_IMAGE +#define __HAVE_REGS_IMAGE +typedef struct _regsimg { +#ifndef INFINITE_REGISTERS + int reg_alloc_ptr,reg_stack_ptr; + int next_data,next_addr; +#endif +} REGS_IMAGE; +#endif + +readonly struct amode am_a1={am_areg,0,1,0,0,0}; +readonly struct amode am_a2={am_areg,0,2,0,0,0}; +readonly struct amode am_a2ind={am_ind,0,2,0,0,0}; + +extern int hexatoi(char *s); + +struct amode *g_fcall(struct enode *node, int flags) { +/* + * generate a function call node and return the address mode of the result. + */ + struct amode *ap; enum(e_node) nt; + long i; +#ifdef SHORT_STRUCT_PASSING + int short_struct_return=0; +#endif +#ifdef PC + // avoid a compiler warning... + struct amode *struct_ap = 0; +#else + struct amode *struct_ap = struct_ap; +#endif + #ifdef REGPARM +// struct amode *regap[(MAX_DATA+1+MAX_ADDR+1)+1],**rapp; + struct amode *a1ap; struct enode *dep; + REGS_IMAGE regs_img; + int allaregs_patch=0; + #endif + /* push any used addr&data temps */ + dep = node->v.p[0]; + while (dep->nodetype==en_cast && dep->esize==4) dep=dep->v.p[0]; + nt = dep->nodetype; +// nt = node->v.p[0]->nodetype; +/* if (nt==en_nacon && !strcmp(node->v.p[0]->v.ensp,"rand")) + printf("jdfio");*/ + temp_inv(); + #ifdef REGPARM + useregs(®s_img); +#ifndef INFINITE_REGISTERS + if (node->rp_an>MAX_ADDR && !(nt==en_nacon || nt==en_labcon + || (nt==en_tempref && node->v.p[0]->v.i>=AREGBASE)) + && req_all_aregs(node->v.p[1],node->rp_dn,node->rp_an)) + allaregs_patch=1; +#endif + i = g_parms(node->v.p[1],node->rp_dn, + node->rp_an/*-allaregs_patch*/,&a1ap); /* generate parameters */ + if (allaregs_patch) freeop(a1ap); + #else + i = g_parms(node->v.p[1]); /* generate parameters */ + #endif + /* + * for functions returning a structure or a union, push a pointer to the + * return value as additional argument The scratch space will be + * allocated in the stack frame of the calling function. + */ + if (bt_aggregate(node->etype)) { + struct_ap = mk_scratch(node->esize); +#ifdef SHORT_STRUCT_PASSING + if (node->esize>4) +#endif + g_code(op_pea, 0, struct_ap, NIL_AMODE), i += 4l; +#ifdef SHORT_STRUCT_PASSING + else short_struct_return=1; +#endif + // freeop(ap); it is useless, as scratch amode's need not be freed + } + /* call the function */ + if (nt == en_nacon || nt == en_labcon) { + /*if (!strcmp(node->v.p[0]->v.ensp,"rand")) + printf("jdfio");*/ +#ifdef FLINE_RC + if (fline_rc && nt==en_nacon && dep->v.ensp && !strncmp(dep->v.ensp,"_ROM_CALL_",10)) + g_code(op_dc, 2, mk_offset(mk_icon(0xF800+hexatoi(dep->v.ensp+10))), NIL_AMODE); + else +#endif + g_code(op_jsr, 0, mk_offset(dep), NIL_AMODE); +// g_code(op_jsr, 0, mk_offset(node->v.p[0]), NIL_AMODE); + } else { +#ifdef REGPARM + if (allaregs_patch) { + g_code(op_move, 4, (struct amode *)&am_a2, push_am); + g_code(op_move, 4, (struct amode *)&am_a1, (struct amode *)&am_a2); + } +#endif + ap = g_expr(node->v.p[0], F_AREG); + ap = copy_addr(ap); + ap->mode = am_ind; + freeop(ap); +#ifdef REGPARM + if (allaregs_patch) { +#ifdef PC + if (ap->preg!=1) + ierr(REGPARM,3); +#endif +/* struct amode *ap2 = + (struct amode *) xalloc((int) sizeof(struct amode), AMODE);*/ + g_code(op_exg, 4, (struct amode *)&am_a1, (struct amode *)&am_a2); + ap=(struct amode *)&am_a2ind; +/* ap2->mode = am_areg; + ap2->preg = node->rp_an-1; + g_code(op_move, 4, pop_am, ap2); // always long since it's 'bt_pointer' + i-=4;*/ + } +#endif + g_code(op_jsr, 0, ap, NIL_AMODE); +#ifdef REGPARM + if (allaregs_patch) + g_code(op_move, 4, pop_am, (struct amode *)&am_a2); +#endif + } + #ifdef REGPARM + /* free register params */ +/* rapp=regap; + while (*rapp) + freeop(*rapp++);*/ + freeregs(®s_img); + #endif +#ifdef SHORT_STRUCT_PASSING + if (short_struct_return) { + if (flags & F_NOVALUE) + return func_result2(F_NOVALUE,i,0); + g_code(op_lea,0,struct_ap,mk_reg(PRESULT)); /* note : this *is* commutative with + * popping args off as we use a virtual + * a6-like register for struct_ap... + * But we had better postpone this lea + * as late as possible to take advantage + * of peephole optimizations. + */ + ap = mk_reg(PRESULT); ap->mode=am_ind; + g_code(op_move,node->esize,mk_reg(RESULT),ap); + } +#endif + return func_result2(flags, i, + (node->etype>=bt_pointer&&node->etype<=bt_union)?PRESULT:RESULT); +} + +struct amode *g_alloca(struct enode *node) { + struct enode *ep=mk_node(en_add,node->v.p[0],mk_icon(1)); + struct amode *ap1, *ap2; + ep->etype=node->v.p[0]->etype; + ep->esize=node->v.p[0]->esize; + ep->v.p[1]->etype=ep->etype; + ep->v.p[1]->esize=ep->esize; + ep=mk_node(en_and,mk_icon(-2),ep); + ep->etype=ep->v.p[1]->etype; + ep->esize=ep->v.p[1]->esize; + ep->v.p[0]->etype=ep->etype; + ep->v.p[0]->esize=ep->esize; + ap1 = mk_reg(STACKPTR); + opt0(&ep); + ap2 = g_expr(ep, F_DREG | F_IMMED); + g_code(op_sub, 2, ap2, ap1); + freeop(ap2); + return ap1; +} + +#define F_GCAST 0 +//#define F_GCAST F_USES => seems completely useless... + +#ifdef G_CAST2 +struct amode *g_cast2(struct enode *ep, enum(e_bt) typ2, int flags) { +/* + * generates code for a en_cast node + * + */ + struct amode *ap; + enum(e_bt) typ1=ep->etype; + if (typ1==bt_long && typ2==bt_short) { /* useful when using short mul's */ + if (ep->nodetype==en_cast && ep->v.p[0]->etype==bt_short) + return g_expr(ep->v.p[0], flags); + } + ap=g_expr(ep, F_ALL | F_SRCOP | F_GCAST); + return g_cast(ap, typ1, typ2, flags); +} +#endif + +struct amode *g_cast(struct amode *ap, enum(e_bt) typ1, enum(e_bt) typ2, int flags) { +/* + * generates code for an en_cast node + * + */ + struct amode *ap1; + int f; + + if (flags & F_NOVALUE) { + freeop(ap); + return 0; + } + + /* the following code from now on is meaningless : + * 'useless' casts are sometimes generated to keep track of + * the previous TYP structure */ +#if 0 + if (typ1 == typ2) + /* + * this can happen in with the g_xmul stuff, where a cast from + * (u)short to long now casts from (u)short to (u)short for an 68000 + * mulu or muls instruction. + * It is safe to cut things short then. + * It should not happen with types other than (u)short, but + * it does not harm either. + */ + if (typ1 == bt_short || typ1 == bt_ushort) + return mk_legal(ap, flags, 2l); + //else + // msg("DEBUG: g_cast: typ1 == typ2\n"); +#endif + + switch (typ2) { + /* switch: type to cast to */ + case bt_char: + case bt_uchar: + switch (typ1) { + case bt_uchar: + case bt_char: + return mk_legal(ap, flags, 1l); + case bt_ushort: + case bt_short: + if ((ap1 = g_offset(ap, 1)) == 0) + ap1 = mk_legal(ap, F_DREG, 2l); + return mk_legal(ap1, flags, 1l); + case bt_ulong: + case bt_long: + case bt_pointer: + if ((ap1 = g_offset(ap, 3)) == 0) + ap1 = mk_legal(ap, F_DREG, 4l); + return mk_legal(ap1, flags, 1l); + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return g_cast(g_cast(ap, bt_double, bt_long, F_DREG), + bt_long, typ2, F_DREG); + } + break; + case bt_ushort: + case bt_short: + switch (typ1) { + case bt_uchar: + ap = mk_legal(ap, F_DREG | F_VOL, 1l); + g_code(op_and, 2, mk_immed(255l), ap); + return mk_legal(ap, flags, 2l); + case bt_char: + ap = mk_legal(ap, F_DREG | F_VOL, 1l); // F_VOL is important here! + g_code(op_ext, 2, ap, NIL_AMODE); // (otherwise (short)(char)my_short fails...) + return mk_legal(ap, flags, 2l); + case bt_short: + case bt_ushort: + return mk_legal(ap, flags, 2l); + case bt_long: + case bt_ulong: + case bt_pointer: + if ((ap1 = g_offset(ap, 2)) == 0) + ap1 = mk_legal(ap, F_DREG, 4l); + return mk_legal(ap1, flags, 2l); + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return g_cast(g_cast(ap, bt_double, bt_long, F_DREG), + bt_long, typ2, F_DREG); + } + break; + case bt_long: + case bt_ulong: + case bt_pointer: + switch (typ1) { + case bt_uchar: + ap = mk_legal(ap, F_DREG | F_VOL, 1l); + g_code(op_and, 4, mk_immed(255l), ap); + return mk_legal(ap, flags, 4l); + case bt_char: + ap = mk_legal(ap, F_DREG | F_VOL, 1l); // F_VOL is important here! + g_code(op_ext, 2, ap, NIL_AMODE); // (otherwise (short)(char)my_short fails...) + g_code(op_ext, 4, ap, NIL_AMODE); + return mk_legal(ap, flags, 4l); + case bt_ushort: + ap = mk_legal(ap, F_DREG | F_VOL, 2l); + g_code(op_and, 4, mk_immed(65535l), ap); + return mk_legal(ap, flags, 4l); + case bt_short: + f = flags & (F_DREG | F_AREG); + if (f == 0) f = F_DREG | F_AREG; + ap = mk_legal(ap, f | F_VOL, 2l); // F_VOL is important here! + if (ap->mode == am_dreg) // (otherwise (short)(char)my_short fails...) + g_code(op_ext, 4, ap, NIL_AMODE); + return mk_legal(ap, flags, 4l); + case bt_long: + case bt_ulong: + case bt_pointer: + return mk_legal(ap, flags, 4l); +#ifndef NOFLOAT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + /* library call */ +#ifndef BCDFLT + freeop(ap); + temp_inv(); + g_code(op_move, 4, ap, push_am); + if (typ2 == bt_long) + call_library(str(ffpftol)); + else + call_library(str(ffpftou)); + return func_result(flags, 4l); +#else + fatal( + "__floatsibf"); // !!!STUDY ME!!! +#endif +#endif + } + break; +#ifndef NOFLOAT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + switch (typ1) { + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + ap = g_cast(ap, typ1, bt_long, F_ALL); + case bt_long: + case bt_ulong: + case bt_pointer: + /* library call */ +#ifndef BCDFLT + freeop(ap); + temp_inv(); + g_code(op_move, 4, ap, push_am); + if (typ1 == bt_ulong || typ1 == bt_pointer) + call_library(str(ffputof)); + else + call_library(str(ffpltof)); + return func_result(flags, 4l); +#else + fatal( + "__fixbfsi"); // !!!STUDY ME!!! +#endif + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif + return mk_legal(ap, flags, (long)float_size); + } +#endif + break; + } + ierr(G_CAST,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + + +struct amode *g_offset(struct amode *ap, int off) { +/* + * return true, if ap can be switched to address a location with a short + * offset. typical application: cast long -> short: 8(a6) --> 10(a6) offset + * is a small number (1,2 or 3) + */ + switch (ap->mode) { + case am_ind: + ap = copy_addr(ap); + ap->mode = am_indx; + ap->offset = mk_icon((long) off); + return ap; + case am_indx: + if (ap->offset->nodetype == en_icon && + off + ap->offset->v.i <= 32767) { + ap = copy_addr(ap); + ap->offset->v.i += off; + return ap; + } + break; + case am_indx2: + case am_indx3: + if (ap->offset->nodetype == en_icon && + off + ap->offset->v.i <= 127) { + ap = copy_addr(ap); + ap->offset->v.i += off; + return ap; + } + break; + case am_direct: + ap = copy_addr(ap); + ap->offset = mk_node(en_add, ap->offset, + mk_icon((long) off)); + return ap; + } + /* special value indicating that it must be done by hand */ + return 0; +} + +struct amode *g_xmul(struct enode *node, int flags, enum(e_op) op) { +/* + * performs a mixed-mode multiplication + */ + struct amode *ap1, *ap2; + +/* if (lineid==139) + bkpt();*/ + ap1 = g_expr(node->v.p[1], F_DREG | F_VOL); + ap2 = g_expr(node->v.p[0], F_ALL & ~F_AREG); + validate(ap1); + + g_code(op, 0, ap2, ap1); + freeop(ap2); + return mk_legal(ap1, flags, node->esize); +} + +#ifndef __HAVE_STACK_IMAGE +#define __HAVE_STACK_IMAGE +typedef struct _stackimg { + int next_data,next_addr; +#ifndef INFINITE_REGISTERS + int reg_alloc_ptr,reg_stack_ptr; + char dreg_in_use[MAX_DATA+1]; + char areg_in_use[MAX_ADDR+1]; + struct reg_struct reg_stack[MAX_REG_STACK+1],reg_alloc[MAX_REG_STACK+1]; + int act_scratch; +#endif +} STACK_IMAGE; +#endif + +struct amode *g_compound(struct snode *st, int flags) { + STACK_IMAGE img; + struct amode *ap1,*ap2; + int old=need_res; + need_res=(~flags)&F_NOVALUE; + temp_inv(); /* we are forced to do so :'( */ + usestack(&img); + genstmt(st); + need_res=old; + if (!(ap1=lastexpr_am)) { + if (!(flags&F_NOVALUE)) + err_force_line=st->line, uerrc("no value returned in compound expression"); + } + if (flags&F_NOVALUE) { + freeop(lastexpr_am); + return NIL_AMODE; + } + freestack(&img); + /* always one of F_DREG or F_AREG is set */ + if ((flags&(F_AREG|F_DEREF))==(F_AREG|F_DEREF) || !(flags&F_DREG)) + ap2=temp_addr(); + else ap2=temp_data(); + g_code(op_move, 4, ap1, ap2); + return ap2; /* we needn't call mk_legal :) */ +} + +struct amode *g_expr(struct enode *node, int flags) { +/* + * general expression evaluation. returns the addressing mode of the result. + * + * notice how most of the code actually lies in other functions: this is to + * reduce the stack footprint, which is necessary because calls to g_expr may + * be deeply nested + */ + struct amode *ap1, *ap2; + unsigned int lab0 +#ifndef ALTERNATE_HOOK + , lab1 +#endif + ; + long size; + enum(e_bt) type; + if (node == 0) + ierr(G_EXPR,1); +/* if (node==0x7e1b50) + bkpt();*/ + if (tst_const(node)) { +#ifndef NOBCDFLT + if (node->nodetype==en_fcon) { + extern int glblabel; + int lab = nxtglabel(); + int i; + dseg(); + put_align(2); + put_label(lab); + genfloat(node->v.f); + //char s[2+BCDLEN]; + //int i; + //s[0] = (node->v.f.exponent>>8)&255; + //s[1] = (node->v.f.exponent>>0)&255; + //for (i=0;iv.f.mantissa[i]; + //lab = stringlit(s,sizeof(s)-1); + + node = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + node->v.enlab = lab; + node->etype = bt_pointer; + node->esize = 4; + } +#endif + ap1 = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+G_EXPR); + ap1->mode = am_immed; + ap1->offset = node; + return mk_legal(ap1, flags, node->esize); + } + type = node->etype; + size = node->esize; + switch (node->nodetype) { + case en_autocon: + ap1 = temp_addr(); +#ifdef BIGSTACK + if (node->v.i >= -32768 && node->v.i <= 32767) { +#endif + ap2 = (struct amode *) xalloc((int) sizeof(struct amode), + AMODE+G_EXPR); + ap2->mode = am_indx; + ap2->preg = FRAMEPTR - AREGBASE; /* frame pointer */ + ap2->offset = node; /* use as constant node */ + g_code(op_lea, 0, ap2, ap1); +#ifdef BIGSTACK + } else { + g_code(op_move, 4, mk_immed((long) node->v.p[0]->v.i), ap1); + g_code(op_add, 4, mk_reg(FRAMEPTR), ap1); + ap1 = copy_addr(ap1); + ap1->mode = am_ind; + } +#endif + return mk_legal(ap1, flags, size); + case en_ref: + /* + * g_deref uses flags and size only to test F_USES + */ + ap1 = g_deref(node->v.p[0], type, flags, node->esize); + if (bt_aggregate(type)) + return mk_legal(ap1, flags, 4l); + else + return mk_legal(ap1, flags, size); + case en_fieldref: + return g_fderef(node, NULL, flags); + case en_tempref: + ap1 = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+G_EXPR); + if (node->v.i < AREGBASE) { + ap1->mode = am_dreg; + ap1->preg = (reg_t)node->v.i; + } else { + ap1->mode = am_areg; + ap1->preg = (reg_t)(node->v.i - AREGBASE); + } + return mk_legal(ap1, flags, size); + case en_uminus: + return g_unary(node, flags, op_neg); + case en_compl: + return g_unary(node, flags, op_not); + case en_add: +#ifdef VCG + return g_commute(g_addsub, node, flags, op_add, symmetric); +#else + return g_addsub(node, flags, op_add); +#endif + case en_sub: + //#ifdef VCG + // return g_commute(g_addsub, node, flags, op_sub, antisymmetric); + //#else + return g_addsub(node, flags, op_sub); + //#endif + case en_and: +#ifdef BITWISE_REDUCE + bitwise_optimize(node, -1L); +#endif +#ifdef VCG + return g_commute(g_ybin, node, flags, op_and, symmetric); +#else + return g_ybin(node, flags, op_and); +#endif + case en_or: +#ifdef BITWISE_REDUCE + bitwise_optimize(node, 0L); +#endif +#ifdef VCG + return g_commute(g_ybin, node, flags, op_or, symmetric); +#else + return g_ybin(node, flags, op_or); +#endif + case en_xor: +#ifdef BITWISE_REDUCE + bitwise_optimize(node, 0L); +#endif +#ifdef VCG + return g_commute(g_xbin, node, flags, op_eor, symmetric); +#else + return g_xbin(node, flags, op_eor); +#endif + case en_mul: + /* + * special optimization possible if there are patterns matching the + * 68000 mulu, muls instructions. ugly, but it gives a big + * performance increase + */ + + if (type == bt_long || type == bt_ulong || type == bt_pointer) { + /* TODO : (char/uchar) * (icon both short & ushort) would be more + * efficient with muls instead of mulu (ext.w instead of and.w + * #255) + */ + if (tst_ushort(node->v.p[0]) && tst_ushort(node->v.p[1])) { + /*if (node->v.p[0]->esize>2) {*/ + node->v.p[0]->etype = bt_ushort; + node->v.p[0]->esize = 2; + /*} + if (node->v.p[1]->esize>2) {*/ + node->v.p[1]->etype = bt_ushort; + node->v.p[1]->esize = 2; + /*}*/ + return g_xmul(node, flags, op_mulu); + } else if (tst_short(node->v.p[0]) && tst_short(node->v.p[1])) { + /*if (node->v.p[0]->esize>2) {*/ + node->v.p[0]->etype = bt_short; + node->v.p[0]->esize = 2; + /*} + if (node->v.p[1]->esize>2) {*/ + node->v.p[1]->etype = bt_short; + node->v.p[1]->esize = 2; + /*}*/ + return g_xmul(node, flags, op_muls); + } + } + return g_mul(node, flags); + case en_div: + return g_div(node, flags); + case en_mod: + return g_mod(node, flags); + case en_lsh: + return g_shift(node, flags, op_lsl); + case en_rsh: + if (type==bt_ulong || type==bt_ushort || type==bt_uchar) + return g_shift(node, flags, op_lsr); + else + return g_shift(node, flags, op_asr); + case en_asadd: + return g_asadd(node, flags, op_add); + case en_assub: + return g_asadd(node, flags, op_sub); + case en_asand: + return g_aslogic(node, flags, op_and); + case en_asor: + return g_aslogic(node, flags, op_or); + case en_aslsh: + return g_asshift(node, flags, op_lsl); + case en_asrsh: + if (type==bt_ulong || type==bt_ushort || type==bt_uchar) + return g_asshift(node, flags, op_lsr); + else + return g_asshift(node, flags, op_asr); + case en_asmul: + return g_asmul(node, flags); + case en_asdiv: + return g_asdiv(node, flags); + case en_asmod: + return g_asmod(node, flags); + case en_asxor: + return g_asxor(node, flags); + case en_assign: + return g_assign(node, flags); + case en_ainc: + return g_aincdec(node, flags, op_add); + case en_adec: + return g_aincdec(node, flags, op_sub); + case en_land: + case en_lor: + case en_eq: + case en_ne: + case en_lt: + case en_le: + case en_gt: + case en_ge: + case en_not: +#ifndef ALTERNATE_HOOK + lab0 = nxtlabel(); + lab1 = nxtlabel(); + falsejp(node, lab0); + ap1 = temp_data(); + g_code(op_moveq, 0, mk_immed(1l), ap1); + g_code(op_bra, 0, mk_label(lab1), NIL_AMODE); + g_label(lab0); + g_code(op_moveq, 0, mk_immed(0l), ap1); + g_label(lab1); +#else + lab0 = nxtlabel(); + ap1 = temp_data(); + g_code(op_moveq, 0, mk_immed(0l), ap1); + falsejp(node, lab0); + g_code(op_moveq, 0, mk_immed(1l), ap1); + g_label(lab0); +#endif + return mk_legal(ap1, flags, size); + case en_cond: + return g_hook(node, flags); + case en_void: + freeop(g_expr(node->v.p[0], F_ALL | F_SRCOP | F_NOVALUE)); + return g_expr(node->v.p[1], flags); + case en_fcall: + return g_fcall(node, flags); + case en_alloca: + return mk_legal(g_alloca(node), flags, 4); + case en_cast: + /* + * On the 68000, suppress all casts between any of + * long, unsigned long, pointer + */ + if (type == bt_pointer || type == bt_long || type == bt_ulong) { + type = node->v.p[0]->etype; + if (type == bt_pointer || type == bt_long || type == bt_ulong) + return g_expr(node->v.p[0], flags); + } + /* + * The cast really results in some work + */ +#ifdef G_CAST2 + return g_cast2(node->v.p[0], node->etype, flags); +#else + return g_cast(g_expr(node->v.p[0], F_ALL | F_SRCOP | F_GCAST), + node->v.p[0]->etype, + node->etype, flags); +#endif + case en_deref: + /* + * The cases where this node occurs are handled automatically: + * g_assign and g_fcall return a pointer to a structure rather than a + * structure. + */ + return g_expr(node->v.p[0], flags); + case en_compound: + return g_compound(node->v.st, flags); + default: + uerr(ERR_OTH,"debug: node=$%lx, nodetype=%d, etype=%d, esize=%d",node,node->nodetype,node->etype,node->esize); + ierr(G_EXPR,2); + /* NOTREACHED */ + return 0; // make the compiler happy + } +} + +extern struct enode *regexp[REGEXP_SIZE]; +int tst_ushort(struct enode *node) { +/* + * tests if node is a integer constant falling in the range of uns. short or + * if node is cast from uns. short, uns. char or char. + */ + enum(e_bt) type; + + if (node->nodetype == en_icon && 0 <= node->v.i && node->v.i <= 65535) + return 1; + + if (node->nodetype == en_tempref) /* because it could be something + like a constant in a register */ + return tst_ushort(regexp[reg_t_to_regexp(node->v.i)]); + if (node->nodetype == en_cast) { + type = node->v.p[0]->etype; + if (type == bt_ushort || type == bt_uchar || type == bt_char) + return 1; + } + return 0; +} + +int tst_short(struct enode *node) { +/* + * tests if node is a integer constant falling in the range of short or if + * node is cast from signed or unsigned short. + */ + enum(e_bt) type; + + if (node->nodetype == en_icon && -32768 <= node->v.i && node->v.i <= 32767) + return 1; + + if (node->nodetype == en_tempref) /* because it could be something + like a constant in a register */ + return tst_short(regexp[reg_t_to_regexp(node->v.i)]); + if (node->nodetype == en_cast) { + type = node->v.p[0]->etype; + if (type == bt_short || type == bt_ushort + || type == bt_char || type == bt_uchar) + return 1; + } + return 0; +} + +int tst_const(struct enode *node) { +/* + * tests if it is a constant node, that means either en_icon, en_nacon or + * en_labcon, or sums or differences of such nodes + */ + enum(e_node) typ1 = node->nodetype; + enum(e_node) typ2; + if (typ1 == en_icon || typ1 == en_nacon || typ1 == en_labcon + || typ1 == en_fcon) + return 1; + + if (typ1 == en_add || typ1 == en_sub) { + typ1 = node->v.p[0]->nodetype; + typ2 = node->v.p[1]->nodetype; + if (((typ1 == en_nacon || typ1 == en_labcon) && typ2 == en_icon) || + ((typ2 == en_nacon || typ2 == en_labcon) && typ1 == en_icon)) + return 1; + } + return 0; +} + + +static int g_compare(struct enode *node) { +/* + * generate code to do a comparison of the two operands of node. returns 1 if + * it was an unsigned comparison + */ + struct amode *ap1, *ap2, *ap3; +#ifndef NOFLOAT + long i; +#endif + switch (node->v.p[0]->etype) { + case bt_uchar: + case bt_char: + case bt_ushort: + case bt_short: + case bt_pointer: + case bt_long: + case bt_ulong: + ap2 = g_expr(node->v.p[1], F_ALL | F_SRCOP); + /* We want to handle the special case 'tst.w pcrel_variable' smoothly, + * which is why we set F_SRCOP in the latter + * We will unset it later on. */ + if (ap2->mode == am_immed) + ap1 = g_expr(node->v.p[0], (F_ALL & ~F_IMMED) | F_SRCOP); + else + ap1 = g_expr(node->v.p[0], F_AREG | F_DREG); + validate(ap2); + /*if (ap1->mode == am_direct + && (ap->offset->nodetype == en_nacon + || ap->offset->nodetype == en_labcon) +#ifdef AS +&& !external(ap->offset->v.enlab) +#else +#ifdef PC +&& ((long)ap->offset->v.ensp>0x1000 ? internal(ap->offset->v.ensp) : 1) +#endif +#endif +) +t*/ + /* + * sorry, no tst.l An on the 68000, but we can move to a data + * register if one is free + * As there is no tst.l myval(pc), we can do it this way for am_direct's too. + */ + if ((ap1->mode == am_areg || ap1->mode==am_direct) + && node->v.p[1]->nodetype == en_icon + && node->v.p[1]->v.i == 0 && free_data()) { + ap3 = temp_data(); + g_code(op_move, node->v.p[0]->esize, ap1, ap3); + /* tst.l ap3 not needed */ + freeop(ap3); + } else { + /* the only case where the following != nop is when ap2->mode==am_immed and ap1->mode==am_direct */ + ap1=mk_legal(ap1, F_ALL, node->v.p[0]->esize); + g_code(op_cmp, (int) node->v.p[0]->esize, ap2, ap1); + } + freeop(ap1); + freeop(ap2); + if (node->v.p[0]->etype == bt_char || + node->v.p[0]->etype == bt_short || + node->v.p[0]->etype == bt_long) + return 0; + return 1; + case bt_struct: + ap1 = g_expr(node->v.p[1], F_AREG | F_VOL); + ap2 = g_expr(node->v.p[0], F_AREG | F_VOL); + validate(ap1); { + int lab=nxtlabel(); + ap1 = copy_addr(ap1); + ap2 = copy_addr(ap2); + ap2->mode=ap1->mode=am_ainc; + ap3 = temp_data(); + freeop(ap3); + g_code(op_move,2,mk_immed((node->esize-1)>>1),ap3); + g_label(lab); + g_code(op_cmp,2,ap1,ap2); + g_code(op_dbne,0,ap3,mk_label(lab)); + } + freeop(ap2); + freeop(ap1); + return 1; +#ifndef NOFLOAT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif +#ifndef BCDFLT + if (node->v.p[1]->nodetype == en_fcon && node->v.p[1]->v.f==0) { + node->etype = bt_long; /* no conversion func call (raw cast) */ + node=mk_node(en_cast,node,NIL_ENODE); + node->etype = bt_char; + node->esize = 1; + ap1 = g_expr(node, F_DALT); + g_code(op_tst, (int) node->esize, ap1, NIL_AMODE); + freeop(ap1); + } else { +#endif + temp_inv(); + i = push_param(node->v.p[1]); + i += push_param(node->v.p[0]); +#ifndef BCDFLT + call_library(str(ffpcmp)); +#else + call_library("__cmpbf2"); +#endif + g_code(op_add, 4, mk_immed((long) i), mk_reg(STACKPTR)); + return 0; +#ifndef BCDFLT + } +#endif +#endif + } + ierr(G_COMPARE,1); + /* NOTREACHED */ + return 0; // make the compiler happy +} + +#ifndef NOBCDFLT +readonly struct enode __bcd_zero__value={ + en_labcon, +#ifdef DOUBLE + bt_double, +#else + bt_float, +#endif + 10 +}; +#ifdef AS +#define bcd_zero (pchsearch("__bcd_zero",PCHS_ADD), \ + __bcd_zero__value.v.enlab=label("__bcd_zero"), \ + &__bcd_zero__value) +#else +#define bcd_zero (__bcd_zero__value.v.ensp="__bcd_zero", &__bcd_zero__value) +#endif +#endif +void truejp(struct enode *node, unsigned int lab) { +/* + * generate a jump to lab if the node passed evaluates to a true condition. + */ + struct amode *ap; + unsigned int lab0; + if (node == 0) + ierr(TRUEJP,1); + if (node->nodetype == en_icon) { + if (node->v.i) + g_code(op_bra, 0, mk_label(lab), NIL_AMODE); + return; + } + opt_compare(node); + switch (node->nodetype) { + case en_eq: + (void) g_compare(node); + g_code(op_beq, 0, mk_label(lab), NIL_AMODE); + break; + case en_ne: + (void) g_compare(node); + g_code(op_bne, 0, mk_label(lab), NIL_AMODE); + break; + case en_lt: + case en_le: + case en_gt: + case en_ge: + { + int n=(en_ge-node->nodetype)*2+op_bhs; + g_code(g_compare(node)?n:++n, 0, mk_label(lab), NIL_AMODE); + break; + } + case en_fieldref: + { + struct enode *ep,*ep2; + ep=mk_node(en_ref, node->v.p[0], (struct enode *) NIL_AMODE); + ep->esize=node->esize; + ep->etype=node->etype; + ep2=mk_icon(((1<bit_width)-1) << + ((node->esize<<3)-node->bit_offset-node->bit_width)); + ep2->esize=node->esize; + ep2->etype=node->etype; + ep=mk_node(en_and,ep,ep2); + ep->esize=node->esize; + ep->etype=node->etype; + truejp(ep, lab); + break; + } + + /* case en_lt: + g_compare(node) ? + g_code(op_blo, 0, mk_label(lab), NIL_AMODE) : + g_code(op_blt, 0, mk_label(lab), NIL_AMODE); + break; + case en_le: + g_compare(node) ? + g_code(op_bls, 0, mk_label(lab), NIL_AMODE) : + g_code(op_ble, 0, mk_label(lab), NIL_AMODE); + break; + case en_gt: + g_compare(node) ? + g_code(op_bhi, 0, mk_label(lab), NIL_AMODE) : + g_code(op_bgt, 0, mk_label(lab), NIL_AMODE); + break; + case en_ge: + g_compare(node) ? + g_code(op_bhs, 0, mk_label(lab), NIL_AMODE) : + g_code(op_bge, 0, mk_label(lab), NIL_AMODE); + break;*/ + case en_land: + lab0 = nxtlabel(); + falsejp(node->v.p[0], lab0); + truejp(node->v.p[1], lab); + g_label(lab0); + break; + case en_lor: + truejp(node->v.p[0], lab); + truejp(node->v.p[1], lab); + break; + case en_not: + falsejp(node->v.p[0], lab); + break; +#ifdef OPTIMIZED_AINCDEC_TEST + case en_adec: + // struct amode *lblap = mk_label(lab); + ap = g_expr(node->v.p[0], F_ALL); + /* if (ap->mode==am_dreg) + freeop(ap), + g_code(op_dbra, 0, ap, lblap); + else {*/ + g_code(op_sub, (int) node->esize, mk_immed(1), ap); + freeop(ap); + g_code(op_bhs, 0, /*lblap*/mk_label(lab), NIL_AMODE); + /* }*/ + break; +#endif + case en_and: + /*#ifdef PC*/ +#define is_powerof2(x) (((x)<<1)==((x)^((x)-1))+1) + /*#else +#define is_powerof2(x) ({int __x=x;((__x)<<1)==((__x)^((__x)-1))+1;}) +#endif*/ + if (node->v.p[1]->nodetype==en_icon) { + unsigned long v=node->v.p[1]->v.i; + if (v>=128/*otherwise moveq is cool enough and faster for dregs*/ + && is_powerof2(v)) { + ap=g_expr(node->v.p[0],F_DREG|F_MEM); + g_bitmancode(op_btst,node->v.p[0]->esize,mk_immed(pwrof2(v)),ap); + freeop(ap); + g_code(op_bne, 0, mk_label(lab), NIL_AMODE); + break; + } + } + /* FALL THROUGH */ + default: +#ifndef NOFLOAT + if (node->etype == bt_float || node->etype == bt_double) { +#ifdef DOUBLE + long i; + temp_inv(); + i = push_param(node); + call_library(".fptst"); // obsolete + /* The pop-off does not change the condition codes */ + g_code(op_add, 4, mk_immed((long) i), mk_reg(STACKPTR)); + } else { +#else +#ifndef BCDFLT + node->etype = bt_long; /* no conversion func call (raw cast) */ + node=mk_node(en_cast,node,NIL_ENODE); + node->etype = bt_char; + node->esize = 1; + } + { +#else + g_compare(mk_node(en_void,node,bcd_zero)); + } else { +#endif +#endif +#else + { +#endif + ap = g_expr(node, F_DALT|F_SRCOP); + if (ap->mode==am_direct && free_data()) { + struct amode *ap2 = temp_data(); + g_code(op_move, (int) node->esize, ap, ap2); + g_code(op_tst, (int) node->esize, ap2, NIL_AMODE); + freeop(ap2); + } else + g_code(op_tst, (int) node->esize, ap, NIL_AMODE); + freeop(ap); + } + g_code(op_bne, 0, mk_label(lab), NIL_AMODE); + break; + } +} + +void falsejp(struct enode *node, unsigned int lab) { +/* + * generate code to execute a jump to lab if the expression passed is + * false. + */ + struct amode *ap; + unsigned int lab0; + if (node == 0) + ierr(FALSEJP,1); + if (node->nodetype == en_icon) { + if (!node->v.i) + g_code(op_bra, 0, mk_label(lab), NIL_AMODE); + return; + } + opt_compare(node); + switch (node->nodetype) { + case en_eq: + (void) g_compare(node); + g_code(op_bne, 0, mk_label(lab), NIL_AMODE); + break; + case en_ne: + (void) g_compare(node); + g_code(op_beq, 0, mk_label(lab), NIL_AMODE); + break; + case en_lt: + case en_le: + case en_gt: + case en_ge: + { + int n=(node->nodetype-en_lt)*2+op_bhs; + g_code(g_compare(node)?n:++n, 0, mk_label(lab), NIL_AMODE); + break; + } + case en_fieldref: + { + struct enode *ep,*ep2; + ep=mk_node(en_ref, node->v.p[0], (struct enode *) NIL_AMODE); + ep->esize=node->esize; + ep->etype=node->etype; + ep2=mk_icon(((1<bit_width)-1) << + ((node->esize<<3)-node->bit_offset-node->bit_width)); + ep2->esize=node->esize; + ep2->etype=node->etype; + ep=mk_node(en_and,ep,ep2); + ep->esize=node->esize; + ep->etype=node->etype; + falsejp(ep, lab); + break; + } + /* case en_lt: + g_compare(node) ? + g_code(op_bhs, 0, mk_label(lab), NIL_AMODE) : + g_code(op_bge, 0, mk_label(lab), NIL_AMODE); + break; + case en_le: + g_compare(node) ? + g_code(op_bhi, 0, mk_label(lab), NIL_AMODE) : + g_code(op_bgt, 0, mk_label(lab), NIL_AMODE); + break; + case en_gt: + g_compare(node) ? + g_code(op_bls, 0, mk_label(lab), NIL_AMODE) : + g_code(op_ble, 0, mk_label(lab), NIL_AMODE); + break; + case en_ge: + g_compare(node) ? + g_code(op_blo, 0, mk_label(lab), NIL_AMODE) : + g_code(op_blt, 0, mk_label(lab), NIL_AMODE); + break;*/ + case en_land: + falsejp(node->v.p[0], lab); + falsejp(node->v.p[1], lab); + break; + case en_lor: + lab0 = nxtlabel(); + truejp(node->v.p[0], lab0); + falsejp(node->v.p[1], lab); + g_label(lab0); + break; + case en_not: + truejp(node->v.p[0], lab); + break; +#ifdef OPTIMIZED_AINCDEC_TEST + case en_adec: + ap = g_expr(node->v.p[0], F_ALL); + g_code(op_sub, (int) node->esize, mk_immed(1), ap); + freeop(ap); + g_code(op_blo, 0, mk_label(lab), NIL_AMODE); + break; +#endif + case en_and: + if (node->v.p[1]->nodetype==en_icon) { + unsigned long v=node->v.p[1]->v.i; + if (v>=128/*otherwise moveq is cool enough and faster for dregs*/ + && is_powerof2(v)) { + ap=g_expr(node->v.p[0],F_DREG|F_MEM); + g_bitmancode(op_btst,node->v.p[0]->esize,mk_immed(pwrof2(v)),ap); + freeop(ap); + g_code(op_beq, 0, mk_label(lab), NIL_AMODE); + break; + } + } + /* FALL THROUGH */ + default: +#ifndef NOFLOAT + if (node->etype == bt_float || node->etype == bt_double) { +#ifdef DOUBLE + long i; + temp_inv(); + i = push_param(node); + call_library(".fptst"); // obsolete + /* The pop-off does not change the condition codes */ + g_code(op_add, 4, mk_immed((long) i), mk_reg(STACKPTR)); + } else { +#else +#ifndef BCDFLT + node->etype = bt_long; /* no conversion func call (raw cast) */ + node=mk_node(en_cast,node,NIL_ENODE); + node->etype = bt_char; + node->esize = 1; + } + { +#else + g_compare(mk_node(en_void,node,bcd_zero)); + } else { +#endif +#endif +#else + { +#endif + ap = g_expr(node, F_DALT|F_SRCOP); + if (ap->mode==am_direct && free_data()) { + struct amode *ap2 = temp_data(); + g_code(op_move, (int) node->esize, ap, ap2); + g_code(op_tst, (int) node->esize, ap2, NIL_AMODE); + freeop(ap2); + } else + g_code(op_tst, (int) node->esize, ap, NIL_AMODE); + freeop(ap); + } + g_code(op_beq, 0, mk_label(lab), NIL_AMODE); + break; + } +} + +void opt_compare(struct enode *node) { + /* temprefs should be the second operand to a cmp instruction */ + enum(e_node) t = node->nodetype; + if ((t == en_eq || t == en_ne || t == en_le || t == en_ge + || t == en_lt || t == en_gt) + && (node->v.p[1]->nodetype == en_tempref || + node->v.p[0]->nodetype == en_icon)) { + + swap_nodes(node); + /* if you change the operands, change the comparison operator */ + switch (t) { + case en_le: + node->nodetype = en_ge; + break; + case en_ge: + node->nodetype = en_le; + break; + case en_lt: + node->nodetype = en_gt; + break; + case en_gt: + node->nodetype = en_lt; + break; + } + } +} +#endif /* MC680X0 */ +// vim:ts=4:sw=4 diff --git a/gtc/src/genffp.c b/gtc/src/genffp.c new file mode 100644 index 0000000..4a1ad62 --- /dev/null +++ b/gtc/src/genffp.c @@ -0,0 +1,174 @@ +/* + * GTools C compiler + * ================= + * source file : + * Fast Floating-Point generator + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +/* + * The following floating-point operations are needed in this module: + * + * - comparision with 0.0, 0.5 and 1.0 - division by 2.0 - multiplication with + * 2.0 (performed as addition here) - subtraction of 1.0 + */ + +#ifndef NOFLOAT +#ifdef PC +#include "define.h" +_FILE(__FILE__) +#ifndef BCDFLT +unsigned long double2ffp(double d) { + unsigned long mantissa; + int sign = 0, exponent = 64, i; + + if (d < 0.0) { + sign = 128; + d = -d; + } + while (d < 0.5) { + d += d; + --exponent; + if (exponent == 0) + return sign; /* zero fp number */ + } + + while (d >= 1.0) { + d /= 2.0; + ++exponent; + if (exponent >= 127) + return 127 + sign; /* +/- infinity */ + } + + /* 0.5 <=d <1.0 now: construct the mantissa */ + + mantissa = 0; + for (i = 0; i < 24; i++) { + /* 24 mantissa bits */ + d += d; + mantissa = mantissa + mantissa; + if (d >= 1.0) { + ++mantissa; + d -= 1.0; + } + } + + /* round up, if the next bit would be 1 */ + if (d >= 0.5) + ++mantissa; + /* check on mantissa overflow */ + if (mantissa > 0xFFFFFF) { + ++exponent; + /* exponent overflow? */ + if (exponent >= 127) + return (127 + sign); + mantissa >>= 1; + } + /* put the parts together and return the value */ + + return (mantissa << 8) + sign + exponent; +} +#else +void double2bcd(double d,struct bcd *bcd) { + unsigned char *mantptr=bcd->mantissa; + int bias = 16384, exponent = 0, i; + + if (d < 0.0) { + bias += 32768; + d = -d; + } + if (d != 0.0) { + while (d < 1.0) { + d *= 10.0; + --exponent; + if (exponent < -999) { + d = 0.0; + break; + } + } + } + + while (d >= 10.0) { + d /= 10.0; + ++exponent; + } + + if (d==0.0) { + bcd->exponent=16384; + memset(bcd->mantissa,0,BCDLEN); + return; + } + + /* 1.0 <= d < 10.0 now: construct the mantissa */ + + d += 5e-16; /* round up now */ + for (i = 0; i < BCDLEN; i++) { + unsigned char digit,buffer; + /* 8 mantissa groups of 2 digits */ + if (d>=5.0) { + if (d>=7.0) { + if (d>=8.0) { + if (d>=9.0) + digit=9; + else digit=8; + } else digit=7; + } else if (d>=6.0) + digit=6; + else digit=5; + } else { + if (d>=2.0) { + if (d>=3.0) { + if (d>=4.0) + digit=4; + else digit=3; + } else digit=2; + } else if (d>=1.0) + digit=1; + else digit=0; + } + d -= digit; + d *= 10.0; + buffer = digit<<4; + if (d>=5.0) { + if (d>=7.0) { + if (d>=8.0) { + if (d>=9.0) + digit=9; + else digit=8; + } else digit=7; + } else if (d>=6.0) + digit=6; + else digit=5; + } else { + if (d>=2.0) { + if (d>=3.0) { + if (d>=4.0) + digit=4; + else digit=3; + } else digit=2; + } else if (d>=1.0) + digit=1; + else digit=0; + } + d -= digit; + d *= 10.0; + *mantptr++ = buffer | digit; + } + + /* put the parts together and return the value */ + bcd->exponent = exponent+bias; + + return; +} + +#endif /* !defined(BCDFLT) */ +#endif /* defined(PC) */ +#endif /* !defined(NOFLOAT) */ +// vim:ts=4:sw=4 diff --git a/gtc/src/genstmt.c b/gtc/src/genstmt.c new file mode 100644 index 0000000..e3a38fa --- /dev/null +++ b/gtc/src/genstmt.c @@ -0,0 +1,1248 @@ +/* + * GTools C compiler + * ================= + * source file : + * statement generator + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +#ifndef PC +#define checkstack() while (0) +#endif + +int nextlabel CGLOB; +/*int uses_structassign CGLOB;*/ +TYP *ret_type CGLOB; +XLST_TYPE lc_auto CGLOB; +XLST_TYPE max_scratch CGLOB; +#ifdef MC680X0 +unsigned int save_mask CGLOB; +#endif +xstatic unsigned int breaklab CGLOB; +xstatic unsigned int contlab CGLOB; +xstatic unsigned int retlab CGLOB; + +void genstmt(struct snode *stmt); + +struct amode *mk_reg(int r) { +/* + * make an address reference to a register. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+MK_REG); +#ifdef MC680X0 + if (r < AREGBASE) { + ap->mode = am_dreg; + ap->preg = r; + } else { + ap->mode = am_areg; + ap->preg = r - AREGBASE; + } +#endif +#ifdef INTEL_386 + ap->mode = am_reg; + ap->preg = r; +#endif + return ap; +} + + +#ifdef MC680X0 +struct amode *mk_rmask(unsigned int mask) { +/* + * generate the mask address structure. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+MK_MASK); + ap->mode = am_mask1; + ap->offset = mk_icon((long) mask); + return ap; +} + +struct amode *mk_smask(unsigned int mask) { +/* + * generate the mask address structure. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+MK_MASK); + ap->mode = am_mask2; + ap->offset = mk_icon((long) mask); + return ap; +} +#endif + +struct amode *mk_strlab(char *s) { +/* + * generate a direct reference to a string label. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+MK_STRLAB); + ap->mode = am_direct; + ap->offset = mk_node(en_nacon, NIL_ENODE, NIL_ENODE); + ap->offset->v.ensp = s; +#ifdef AS + ap->offset->v.enlab = label(s); +#endif + return ap; +} + +static void genwhile(struct snode *stmt) { +/* + * generate code to evaluate a while statement. + */ + unsigned int lab1, lab2; + initstack(); /* initialize temp registers */ + lab1 = contlab; /* save old continue label */ + lab2 = breaklab; /* save old break label */ + contlab = nxtlabel(); /* new continue label */ +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", contlab); +#endif + g_label(contlab); + if (stmt->s1 != 0) { /* has block */ + breaklab = nxtlabel(); + initstack(); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "*falsejp L%u\n", breaklab); + g_icode(stmt->exp); + } +#endif + falsejp(stmt->exp, breaklab); + checkstack(); + genstmt(stmt->s1); + g_code(op_bra, 0, mk_label(contlab), NIL_AMODE); + g_label(breaklab); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "\tbranch_unconditional\tL%u\n", contlab); + fprintf(icode, "\tL%u:\n", breaklab); + } +#endif + breaklab = lab2; /* restore old break label */ + } else { /* no loop code */ + initstack(); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "*truejp L%u\n", contlab); + g_icode(stmt->exp); + } +#endif + truejp(stmt->exp, contlab); + checkstack(); + } + contlab = lab1; /* restore old continue label */ +} + +struct amode *g_deref(); +static void genloop(struct snode *stmt) { +/* + * generate code to evaluate a loop statement. + */ + unsigned int lab1, lab2; + struct amode *counter,*ap2; + struct enode *node; + initstack(); /* initialize temp registers */ + lab1 = contlab; /* save old continue label */ + lab2 = breaklab; /* save old break label */ + node=stmt->exp->v.p[0]; + counter = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+GENLOOP); + switch (node->nodetype) { + case en_autocon: + counter->mode = am_indx; + counter->preg = FRAMEPTR - AREGBASE; /* frame pointer */ + counter->offset = node; /* use as constant node */ + break; + case en_tempref: + if (node->v.i < AREGBASE) { + counter->mode = am_dreg; + counter->preg = (reg_t)node->v.i; + } else { + fatal("LOOP can't use aregs"); +/* counter->mode = am_areg; + counter->preg = (reg_t)(node->v.i - AREGBASE);*/ + } + break; + case en_nacon: + case en_labcon: + counter->mode = am_direct; + counter->offset = node; + break; + case en_ref: + counter=g_deref(node->v.p[0],node->etype,F_MEM|F_USES,node->esize); + break; + default: + ierr(GENLOOP,1); + } +// ap2 = g_expr(stmt->exp, F_ALL); + ap2 = g_expr(stmt->exp->v.p[1], F_ALL | F_SRCOP); + g_code(op_move, 2, ap2, counter); + freeop(ap2); + if (counter->mode==am_dreg && counter->preg<=MAX_DATA) + ierr(GENLOOP,2); + contlab = nxtlabel(); /* new continue label */ +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", contlab); +#endif + g_label(contlab); + breaklab = nxtlabel(); + if (stmt->s1 != 0) /* has block */ + genstmt(stmt->s1); + if (stmt->v2.e != 0) { /* has 'until' condition */ +#ifdef ICODE + if (icode_option) { + fprintf(icode, "*truejp L%u\n", breaklab); + g_icode(stmt->v1.e); + } +#endif + truejp(stmt->v2.e, breaklab); + } + if (counter->mode==am_dreg) g_code(op_dbra, 0, counter, mk_label(contlab)); + else { + struct amode *ap1; + ap1 = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+GENLOOP); + ap1->mode = am_immed; + ap1->offset = mk_icon(1L); + g_code(op_subq, 2, ap1, counter); + g_code(op_bhs, 0, mk_label(contlab), NIL_AMODE); + } + g_label(breaklab); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "\tbranch_unconditional\tL%u\n", contlab); + fprintf(icode, "\tL%u:\n", breaklab); + } +#endif + breaklab = lab2; /* restore old break label */ + contlab = lab1; /* restore old continue label */ +} + +#ifndef ASM +static void genasm(struct snode *stmt) { + g_code(_op_asm, 0, (struct amode *)stmt->v1.i, NIL_AMODE); +} +#else +#ifdef VCG +extern int vcg_lvl; +extern int vcg_aborted[]; +#endif +static void genasm(struct snode *stmt) { + struct ocode *ip=(struct ocode *)stmt->v1.i; +#ifdef VCG + if (vcg_lvl!=VCG_MAX) + vcg_aborted[vcg_lvl]++; + else +#endif + while (ip) { + add_peep(ip); + ip=ip->fwd; + } +} +#endif + +static void g_for(struct snode *stmt) { +/* + * generate code to evaluate a for loop + */ + unsigned int old_break, old_cont, exit_label, loop_label; + old_break = breaklab; + old_cont = contlab; + loop_label = nxtlabel(); + exit_label = nxtlabel(); + if (stmt->v2.e != 0) + contlab = nxtlabel(); + else + contlab = loop_label; +#ifdef ICODE + if (icode_option) { + if (stmt->exp != 0) + g_icode(stmt->exp); + fprintf(icode, "\tL%u:\n", loop_label); + } +#endif + initstack(); + if (stmt->exp != 0) { + (void) g_expr(stmt->exp, F_ALL | F_SRCOP | F_NOVALUE); + checkstack(); + } + g_label(loop_label); + initstack(); + if (stmt->v1.e != 0) { +#ifdef ICODE + if (icode_option) { + fprintf(icode, "*falsejp L%u\n", exit_label); + g_icode(stmt->v1.e); + } +#endif + falsejp(stmt->v1.e, exit_label); + checkstack(); + } + if (stmt->s1 != 0) { + breaklab = exit_label; + genstmt(stmt->s1); + } +#ifdef ICODE + if (icode_option) { + if (stmt->v2.e != 0) { + fprintf(icode, "\tL%u:\n", contlab); + g_icode(stmt->v2.e); + } + fprintf(icode, "\tbranch_unconditional\tL%u\n", loop_label); + } +#endif + initstack(); + if (stmt->v2.e != 0) { + g_label(contlab); + (void) g_expr(stmt->v2.e, F_ALL | F_SRCOP | F_NOVALUE); + checkstack(); + } + g_code(op_bra, 0, mk_label(loop_label), NIL_AMODE); + breaklab = old_break; + contlab = old_cont; + g_label(exit_label); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", exit_label); +#endif +} + +static void genif(struct snode *stmt) { +/* + * generate code to evaluate an if statement. + */ + unsigned int lab1, lab2, oldbreak; + lab1 = nxtlabel(); /* else label */ + lab2 = nxtlabel(); /* exit label */ + oldbreak = breaklab; /* save break label */ +#ifdef ICODE + if (icode_option) { + fprintf(icode, "*falsejp L%u\n", lab1); + g_icode(stmt->exp); + } +#endif + initstack(); /* clear temps */ + falsejp(stmt->exp, lab1); + checkstack(); + if (stmt->s1 != 0 && stmt->s1->next != 0) { + if (stmt->v1.s != 0) + breaklab = lab2; + else + breaklab = lab1; + } + genstmt(stmt->s1); + if (stmt->v1.s != 0) { /* else part exists */ + g_code(op_bra, 0, mk_label(lab2), NIL_AMODE); + g_label(lab1); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "\tbranch_unconditional\tL%u\n", lab2); + fprintf(icode, "\tL%u:\n", lab1); + } +#endif + if (stmt->v1.s == 0 || stmt->v1.s->next == 0) + breaklab = oldbreak; + else + breaklab = lab2; + genstmt(stmt->v1.s); + g_label(lab2); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", lab2); +#endif + } else { /* no else code */ + g_label(lab1); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", lab1); +#endif + } + breaklab = oldbreak; +} + +static void gendo(struct snode *stmt) { +/* + * generate code for a do - while loop. + */ + unsigned int oldcont, oldbreak, dolab; + oldcont = contlab; + oldbreak = breaklab; + dolab = nxtlabel(); + contlab = nxtlabel(); + breaklab = nxtlabel(); + g_label(dolab); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", dolab); +#endif + genstmt(stmt->s1); /* generate body */ + g_label(contlab); +#ifdef ICODE + if (icode_option) { + fprintf(icode, "\tL%u:\n", contlab); + fprintf(icode, "*truejp L%u\n", dolab); + g_icode(stmt->exp); + fprintf(icode, "\tL%u:\n", breaklab); + } +#endif + initstack(); + truejp(stmt->exp, dolab); + checkstack(); + g_label(breaklab); + breaklab = oldbreak; + contlab = oldcont; +} + +void call_library(char *lib_name) { +/* + * generate a call to a library routine. + * it is assumed that lib_name won't be clobbered + */ + struct sym *sp; + sp = gsearch(lib_name, -1); + if (sp == 0) { + pchsearch(lib_name,PCHS_ADD); + sp = gsearch(lib_name, -1); + if (sp == 0) { + ++global_flag; + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM); + #ifdef NO_CALLOC + sp->tp = 0; + #endif + sp->name = strsave(lib_name); + sp->storage_class = sc_external; + append(&sp, &gsyms); + --global_flag; + } + } + sp->used = 1; +#ifdef MC680X0 + g_code(op_jsr, 0, mk_strlab(sp->name), NIL_AMODE); +#endif +#ifdef INTEL_386 + g_code(op_call, 0, mk_strlab(sp->name), NIL_AMODE); +#endif +} + +static void genswitch(struct snode *stmt) { +/* + * generate a linear search switch statement. + */ + unsigned int curlab; + unsigned int deflab; + unsigned int tablab; + long i; + struct snode *defcase, *s; + struct amode *ap, *ap1; +#ifndef USE_WORDS_IN_SWITCH + struct amode *ap2; +#endif + struct enode *ep; + long size; + enum(e_bt) type; + long min_caselabel, max_caselabel, nxt_caselabel; + int number_of_cases; + defcase = 0; +#ifdef ICODE + if (icode_option) { + fprintf(icode, "$switchexp\n"); + g_icode(stmt->exp); + } +#endif + initstack(); +#ifdef MC680X0 + ap = g_expr(stmt->exp, F_DREG | F_VOL); +#endif +#ifdef INTEL_386 + ap = g_expr(stmt->exp, F_REG); +#endif + size = stmt->exp->esize; + type = stmt->exp->etype; + stmt = stmt->s1; + /* + * analyze the switch statement + */ + s = stmt; + if (s != 0 && s->stype == st_default) { + defcase = s; + s = s->s1; + } + /* s points to the first case label */ + number_of_cases = 1; + if (s != 0) { + max_caselabel = min_caselabel = s->v2.i; + s = s->s1; + while (s != 0) { + if (s->stype == st_default) { + defcase = s; + } else { + if (s->v2.i > max_caselabel) + max_caselabel = s->v2.i; + else if (s->v2.i < min_caselabel) + min_caselabel = s->v2.i; + number_of_cases++; + } + s = s->s1; + } + } + if (number_of_cases > 7 && + (max_caselabel - min_caselabel) / number_of_cases <= 5) { + /* + * we need the case label as a 32-bit item. + */ +#ifdef MC680X0 + switch (type) { + case bt_char: + g_code(op_ext, 2, ap, NIL_AMODE); +#ifndef USE_WORDS_IN_SWITCH + /*FALLTHROUGH*/ + case bt_short: + g_code(op_ext, 4, ap, NIL_AMODE); + break; + case bt_uchar: + g_code(op_and, 4, mk_immed(255l), ap); + break; + case bt_ushort: + g_code(op_and, 4, mk_immed(65535l), ap); +#else + break; + case bt_uchar: + g_code(op_and, 2, mk_immed(255l), ap); + break; +#endif + } +#endif +#ifdef INTEL_386 + switch (type) { + case bt_char: + g_code(op_movsbl, 0, ap, ap); + break; + case bt_short: + g_code(op_movswl, 0, ap, ap); + break; + case bt_uchar: + g_code(op_movzbl, 0, ap, ap); + break; + case bt_ushort: + g_code(op_movzwl, 0, ap, ap); + } +#endif + /* + * move the interval + */ +#ifdef MC680X0 +#ifndef USE_WORDS_IN_SWITCH +#define switch_size 4 +#else +#define switch_size 2 +#endif + if (min_caselabel != 0) { + g_code(op_sub, switch_size, mk_immed(min_caselabel), ap); + g_code(op_cmp, switch_size, mk_immed(max_caselabel - min_caselabel), ap); + } else + g_code(op_cmp, (int) size, + mk_immed(max_caselabel-min_caselabel), ap); +#endif +#ifdef INTEL_386 + if (min_caselabel != 0) { + g_code (op_sub, 4, mk_immed(min_caselabel), ap); + g_code(op_cmp, 4, mk_immed(max_caselabel-min_caselabel), ap); + } else + g_code(op_cmp, (int) size, + mk_immed(max_caselabel-min_caselabel), ap); +#endif + if (defcase == 0) + deflab = breaklab; + else { + deflab = nxtlabel(); + defcase->v2.i = deflab; + } +#ifdef MC680X0 + g_code(op_bhi, 0, mk_label(deflab), NIL_AMODE); +#endif +#ifdef INTEL_386 + g_code(op_ja, 0, mk_label(deflab), NIL_AMODE); +#endif + tablab = nxtlabel(); +#ifdef MC680X0 +#ifndef USE_WORDS_IN_SWITCH + g_code(op_add, 4, ap, ap); + g_code(op_add, 4, ap, ap); +#else + g_code(op_add, 2, ap, ap); +#endif + ap1 = temp_addr(); + g_code(op_lea, 0, mk_label(tablab), ap1); +#ifndef USE_WORDS_IN_SWITCH + g_code(op_add, 4, ap, ap1); +#endif + freeop(ap1); + ap1 = copy_addr(ap1); +#ifndef USE_WORDS_IN_SWITCH + ap1->mode = am_ind; + ap2 = temp_addr(); + g_code(op_move, 4, ap1, ap2); + ap2 = copy_addr(ap2); + ap2->mode = am_ind; + g_code(op_jmp, 0, ap2, NIL_AMODE); + freeop(ap2); +#else + ap1->mode=am_indx2; + ap1->sreg=ap->preg; + ap1->slen=2; + ap1->offset=mk_icon(0l); + g_code(op_move, 2, ap1, ap); + g_code(op_jmp, 0, ap1, NIL_AMODE); +#endif + freeop(ap); +#endif +#ifdef INTEL_386 + g_code(op_shl, 4, mk_immed(2l), ap); + ep = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + ep->v.enlab = tablab; + ap1 = copy_addr(ap); + ap1->mode = am_indx; + ap1->offset = ep; + g_code(op_mov, 4, ap1, ap); + ap1=copy_addr(ap); + ap1->mode = am_star; +/* + * DO NOT USE OP_BRA here.... + * op_bra is reserved for jumps to internal labels. + * This keeps things easy in the peephole optimizer + * While producing assembler output, op_bra and op_jmp yield + * the same + */ + g_code(op_jmp, 0, ap1, NIL_AMODE); + freeop(ap); +#endif +/* + * now, ship out the switch table + * we have just generated the following code (MC68000 expample) + * + * sub.l #min_caselabel,d0 + * cmp.l #max_caselabel-min_caselabel,d0 + * bhi deflab + * add.l d0,d0 + * add.l d0,d0 + * lea table,a0 + * add.l d0,a0 + * move.l (a0),a0 + * jmp (a0) + */ +/* + * search the cases: look for min_caselabel. nxt_caselabel is set to + * the label looked for in the next pass + */ +#ifdef ICODE + if (icode_option) + fprintf(icode, "default ==> L%u\n", + (unsigned int) deflab); +#endif +//#ifdef AS + g_label(tablab); +//#else +// cseg(); +// nl(); +// put_align(AL_POINTER); +// put_label(tablab); +//#endif + ep = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + ep->v.enlab=deflab; + { +#ifdef USE_WORDS_IN_SWITCH + struct enode *ep0 = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + struct amode *ap0; + ep0->v.enlab=tablab; + ap0=mk_offset(mk_node(en_sub,ep,ep0)); +#endif + while (min_caselabel <= max_caselabel) { + nxt_caselabel = max_caselabel + 1; + s = stmt; + while (s != 0) { + if (s->stype != st_default) { + if (s->v2.i == min_caselabel) { + ep = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + s->v2.i = ep->v.enlab = nxtlabel(); + /* remove statment from the list */ + s->stype = st_default; +#ifndef USE_WORDS_IN_SWITCH +//#ifdef AS + g_code(op_dc, 4, mk_offset(ep), NIL_AMODE); + // this is because AS can't handle local references in 'genptr' +//#else +// genptr(ep); +//#endif +#else + ep=mk_node(en_sub,ep,ep0); + g_code(op_dc, 2, mk_offset(ep), NIL_AMODE); +#endif +#ifdef ICODE + if (icode_option) + fprintf(icode, "case-value %8ld ==> L%u\n", + min_caselabel, (unsigned int) (s->v2.i)); +#endif + } else if (nxt_caselabel > s->v2.i) + nxt_caselabel = s->v2.i; + } + s = s->s1; + } + /* fill the holes */ + for (i = min_caselabel + 1; i < nxt_caselabel; i++) { + +#ifndef USE_WORDS_IN_SWITCH + ep = mk_node(en_labcon, NIL_ENODE, NIL_ENODE); + ep->v.enlab = deflab; +//#ifdef AS + g_code(op_dc, 4, mk_offset(ep), NIL_AMODE); + // this is because AS can't handle local references in 'genptr' +//#else +// genptr(ep); +//#endif +#else + g_code(op_dc, 2, ap0, NIL_AMODE); +#endif +#ifdef ICODE + if (icode_option) + fprintf(icode, "case-value %8ld ==> L%u\n", + i, (unsigned int) deflab); +#endif + } + min_caselabel = nxt_caselabel; + } + } + nl(); + } else { + /* + * generate sequential compare instructions this is not very + * intelligent, but quicker than a lookup in a (value,label) table + * and has no startup time, this makes it fast if there are few + * labels. + */ + while (stmt != 0) { + curlab = nxtlabel(); + if (stmt->stype == st_default) { /* default case ? */ + defcase = stmt; + } else { +#ifdef MC680X0 + g_code(op_cmp, (int) size, mk_immed((long) stmt->v2.i), ap); + g_code(op_beq, 0, mk_label(curlab), NIL_AMODE); +#endif +#ifdef INTEL_386 + g_code(op_cmp, (int) size, mk_immed((long) stmt->v2.i), ap); + g_code(op_je, 0, mk_label(curlab), NIL_AMODE); +#endif +#ifdef ICODE + if (icode_option) + fprintf(icode, "*ifeq\t%ld,L%u\n", stmt->v2.i, curlab); +#endif + } + stmt->v2.i = curlab; + stmt = stmt->s1; + } + if (defcase == 0) { + g_code(op_bra, 0, mk_label(breaklab), NIL_AMODE); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tbranch_unconditional\tL%u\n", breaklab); +#endif + } else { + g_code(op_bra, 0, mk_label((unsigned int) defcase->v2.i), + NIL_AMODE); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tbranch_unconditional\tL%u\n", + (unsigned int) defcase->v2.i); +#endif + } + freeop(ap); + } + checkstack(); +} + +static void gencase(struct snode *stmt) { +/* + * generate the label for the case statement. + */ + g_label((unsigned int) stmt->v2.i); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", (unsigned int) stmt->v2.i); +#endif +} + +static void genxswitch(struct snode *stmt) { +/* + * analyze and generate best switch statement. + */ + int oldbreak; + oldbreak = breaklab; + breaklab = nxtlabel(); + genswitch(stmt); + genstmt(stmt->v1.s); + g_label(breaklab); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", breaklab); +#endif + breaklab = oldbreak; +} + +static void genreturn(struct snode *stmt) { +/* + * generate a return statement. + */ + struct amode *ap; + struct enode *ep,*ep1; +// long stack_offset; + if (stmt != 0 && stmt->exp != 0) { +#ifdef ICODE + if (icode_option) { + fprintf(icode, "$return_value\n"); + g_icode(stmt->exp); + } +#endif + initstack(); + switch (ret_type->type) { + case bt_struct: + case bt_union: + aggregate: +/* uses_structassign = 1;*/ +#ifdef SHORT_STRUCT_PASSING + if (ret_type->size<=4) { + if (stmt->exp->nodetype!=en_ref) + ierr(GENRETURN,1); + ap = g_expr(stmt->exp->v.p[0], F_AREG); + ap = copy_addr(ap); + ap->mode = am_ind; + g_code(op_move,ret_type->size,ap,mk_reg(RESULT)); + freeop(ap); + break; + } +#endif + /* assign structure */ + ep = mk_node(en_autocon, NIL_ENODE, NIL_ENODE); + ep->v.i = 8; + ep->esize = 4; + ep->etype = bt_pointer; + ep = mk_node(en_ref, ep, NIL_ENODE); + ep->etype = bt_pointer; + ep->esize = 4; + ep1 = mk_node(en_ref, ep, NIL_ENODE); + ep1->etype = ret_type->type; + ep1->esize = ret_type->size; + ep1 = mk_node(en_assign, ep1, stmt->exp); + ep1->etype = ret_type->type; + ep1->esize = ret_type->size; + (void) g_expr(ep1, F_ALL | F_SRCOP | F_NOVALUE); +#ifdef MC680X0 + /* move pointer to A0 */ + ap = g_expr(ep, F_ALL | F_SRCOP); + g_code(op_move, 4, ap, mk_reg(PRESULT)); + freeop(ap); +#endif +#ifdef INTEL_386 + /* move pointer to eax */ + ap = g_expr(ep, F_ALL | F_SRCOP); + g_code(op_mov, 4, ap, mk_reg(RESULT)); + freeop(ap); +#endif + break; + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif +#ifdef INTEL_386 + /* return floating point value on top of fpu stack */ + (void) g_expr(stmt->exp, F_FPSTACK); +#ifdef FUNCS_USE_387 + if (!fpu_option) +/* + * .fpgetstack may pop off the top of the software stack into + * the hardware stack. Thus this function can be linked with + * code that expexts the result value in the hardware stack. + */ + call_library(".fpgetstack"); // obsolete +#endif + /* DO NOT call freeop since this might pop the value off */ + break; +#endif +#ifdef MC68000 +#ifndef BCDFLT + /* fallthrough, return value in RESULT register */ +#else + goto aggregate; +#endif +#endif + case bt_char: + case bt_uchar: + case bt_short: + case bt_ushort: + case bt_long: + case bt_ulong: +#ifdef MC680X0 + /* evaluate a parameter in D0 */ + ap = g_expr(stmt->exp, (F_ALL | F_SRCOP)&~F_AREG); + g_code(op_move, (int) stmt->exp->esize, ap, mk_reg(RESULT)); + freeop(ap); +#endif +#ifdef INTEL_386 + case bt_pointer: + /* evaluate a parameter in eax */ + ap = g_expr(stmt->exp, F_ALL); + g_code(op_mov, (int) stmt->exp->esize, ap, mk_reg(RESULT)); + freeop(ap); +#endif + break; +#ifdef MC680X0 + case bt_pointer: + /* evaluate a parameter in A0 */ + ap = g_expr(stmt->exp, (F_ALL | F_SRCOP)&~F_DREG); + g_code(op_move, (int) stmt->exp->esize, ap, mk_reg(PRESULT)); + freeop(ap); + break; +#endif + case bt_void: + uwarn("return in function returning void"); + break; + default: + ierr(GENRETURN,1); + } + checkstack(); + } + +/* + * The epilogue is now postponed till the end of the function body since + * we have to know the final value of max_scratch + * If stmt is zero, this is the implicit return statement at the end of + * the function + */ + if (stmt != 0) { + if (retlab == 0) + retlab = nxtlabel(); + g_code(op_bra, 0, mk_label(retlab), NIL_AMODE); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tbranch_unconditional\tL%u\n", retlab); +#endif + } else { + if (retlab != 0) { + g_label(retlab); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", retlab); +#endif + } +/* + * Note that if the function has called other functions (imagine alloca!), + * the only safe reference to the saved registers is via the framepointer, + * not the stackpointer. + */ +#ifdef MC680X0 + if (regs_used > 0) { +#ifndef USE_LINK + if (!uses_link) +#endif + g_code(op_movem, 4, pop_am, mk_smask(save_mask)); +#ifndef USE_LINK + else { + int stack_offset = lc_auto + max_scratch + 4*regs_used; +#ifdef BIGSTACK + if (stack_offset <= 32768l) { +#endif + ap=mk_reg(TRUE_FRAMEPTR); + ap->mode = am_indx; + ap->offset = mk_icon(-stack_offset); + g_code(op_movem, 4, ap, mk_smask(save_mask)); +#ifdef BIGSTACK + } else { + ap = mk_reg(STACKPTR); + g_code(op_move, 4, mk_reg(TRUE_FRAMEPTR), ap); + g_code(op_sub, 4, mk_immed(stack_offset), ap); + g_code(op_movem, 4, pop_am, mk_smask(save_mask)); + } +#endif + } +#endif + } +#ifdef USE_LINK + g_code(op_unlk, 0, mk_reg(FRAMEPTR), NIL_AMODE); +#else + if (uses_link) + g_code(op_unlk, 0, mk_reg(TRUE_FRAMEPTR), NIL_AMODE); + else if (lc_auto || max_scratch) + g_code(op_add, 4, mk_immed(lc_auto + max_scratch), mk_reg(STACKPTR)); +#endif + g_code(op_rts, 0, NIL_AMODE, NIL_AMODE); +#endif +#ifdef INTEL_386 + /* + * Adjust stack pointer to initial value + */ + if (regs_used > 0 && !is_leaf_function) { + stack_offset = lc_auto + max_scratch + 4*regs_used; + ap = mk_reg(EBP); + ap->mode = am_indx; + ap->offset = mk_icon(-stack_offset); + g_code(op_lea, 4, ap, mk_reg(ESP)); + } +/* + * pop clobbered register variables + */ + if (esi_used) + g_code(op_pop, 4, mk_reg(ESI), NIL_AMODE); + if (edi_used) + g_code(op_pop, 4, mk_reg(EDI), NIL_AMODE); + if (ebx_used) + g_code(op_pop, 4, mk_reg(EBX), NIL_AMODE); + g_code(op_leave, 0, NIL_AMODE, NIL_AMODE); + g_code(op_ret, 0, NIL_AMODE, NIL_AMODE); +#endif +#ifdef ICODE + if (icode_option) + fprintf(icode, "\t$leave\n"); +#endif + } +} + +struct amode *lastexpr_am; +int need_res; + +void genstmt(struct snode *stmt) { +/* + * genstmt will generate a statement and follow the next pointer until the + * block is generated. + */ + while (stmt != 0) { +#ifdef DB_POSSIBLE + lineid=stmt->line; +#endif + switch (stmt->stype) { + case st_label: + g_label((unsigned int) stmt->v2.i); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tL%u:\n", (unsigned int) stmt->v2.i); +#endif + genstmt(stmt->s1); + break; + case st_goto: + g_code(op_bra, 0, mk_label((unsigned int) stmt->v2.i), NIL_AMODE); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tbranch_unconditional\tL%u\n", + (unsigned int) stmt->v2.i); +#endif + break; + case st_expr: { + int flgs; +#ifdef ICODE + if (icode_option) + g_icode(stmt->exp); +#endif + initstack(); +/* if ((long)stmt->exp==0x7b82cc) + bkpt();*/ + lastexpr_am=g_expr(stmt->exp, flgs = + (!(stmt->next) && need_res ? F_ALL | F_SRCOP : F_ALL | F_SRCOP | F_NOVALUE)); + if (flgs & F_NOVALUE) checkstack(); + break; + } + case st_return: + genreturn(stmt); + break; + case st_if: + genif(stmt); + break; + case st_asm: + genasm(stmt); + break; + case st_loop: + genloop(stmt); + break; + case st_while: + genwhile(stmt); + break; + case st_do: + gendo(stmt); + break; + case st_for: + g_for(stmt); + break; + case st_continue: + g_code(op_bra, 0, mk_label(contlab), NIL_AMODE); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tbranch_unconditional\tL%u\n", contlab); +#endif + break; + case st_break: + g_code(op_bra, 0, mk_label(breaklab), NIL_AMODE); +#ifdef ICODE + if (icode_option) + fprintf(icode, "\tbranch_unconditional\tL%u\n", breaklab); +#endif + break; + case st_switch: + genxswitch(stmt); + break; + case st_compound: + genstmt(stmt->s1); + break; + case st_case: + case st_default: + gencase(stmt); + genstmt(stmt->v1.s); + break; + default: + ierr(GENSTMT,1); + break; + } + stmt = stmt->next; + } +} + +extern SYM *func_sp; +extern SYM *parmsp[CONVENTION_MAX_DATA+1+CONVENTION_MAX_ADDR+1+1]; +void genfuncbegin(void) { +#ifdef REGPARM + int dregs=func_sp->tp->rp_dn, aregs=func_sp->tp->rp_an; + int dreg=RESULT, areg=PRESULT; +#endif + +#ifdef BIGSTACK + if (lc_auto < 32768l) { +#ifdef REGPARM +#error This codes needs a little fix if REGPARM is defined... +#endif +#endif +#ifdef USE_LINK + g_coder(op_link, 0, mk_reg(FRAMEPTR), mk_immed(-lc_auto)); +#else +#ifndef REGPARM + if (uses_link) + g_coder(op_link, 0, mk_reg(TRUE_FRAMEPTR), mk_immed(-lc_auto)); + else if (lc_auto) g_coder(op_sub, 4, mk_immed(lc_auto), mk_reg(STACKPTR)); +#else + if (!uses_link && lc_auto!=reg_size) + g_coder(op_sub, 4, mk_immed(lc_auto-reg_size), mk_reg(STACKPTR)); +#endif +#endif +#ifdef BIGSTACK + } else { + g_coder(op_sub, 4, mk_immed(lc_auto), mk_reg(STACKPTR)); +#ifdef USE_LINK + if (uses_link) + g_coder(op_link, 0, mk_reg(FRAMEPTR), mk_immed(0l)); +#endif + } +#endif + /* now generate pushing code for reg params */ +#ifdef REGPARM + { struct amode *apl[CONVENTION_MAX_DATA+1+CONVENTION_MAX_ADDR+1]; + int aps[CONVENTION_MAX_DATA+1+CONVENTION_MAX_ADDR+1],i=0; + SYM **spp=parmsp; + while (*spp) { + SYM *sp1 = *spp++; + if (dregs || aregs) { + apl[i]=mk_reg(((sp1->tp->type==bt_pointer && aregs) || !dregs) + ?(aregs--, areg++):(dregs--, dreg++)); + aps[i]=sp1->tp->size; + aps[i]+=aps[i]&1; + if (uses_link) { + struct amode *ap = (struct amode *) xalloc((int) sizeof(struct amode), + AMODE+G_DEREF); + ap->mode = am_indx; + ap->preg = FRAMEPTR-AREGBASE; + ap->offset = mk_icon(sp1->value.i); + g_coder(op_move, aps[i], apl[i], ap); + } + i++; + } else break; + } + if (!uses_link) { +// i=nparms; if (i>dregs+aregs) i=dregs+aregs; + while (i--) g_coder(op_move, aps[i], apl[i], push_am); + } else g_coder(op_link, 0, mk_reg(TRUE_FRAMEPTR), mk_immed(-lc_auto)); + } +#endif +} + +void genfunc(struct snode *stmt) { +/* + * generate a function body. + */ +#ifdef VERBOSE + time_t ltime; +#endif /* VERBOSE */ + int line0 = lineid; + + retlab = contlab = breaklab = 0; + max_scratch = 0; + if (lc_auto % AL_DEFAULT != 0) + lc_auto += AL_DEFAULT - (lc_auto % AL_DEFAULT); +#ifdef VERBOSE + times(&tms_buf); + ltime = tms_buf.tms_utime; +#endif /* VERBOSE */ +#ifdef SHOWSTEP + printf("\ncse"); +#endif + opt1(stmt); +#ifdef SHOWSTEP + printf(" ok "); +#endif +#ifdef VERBOSE + times(&tms_buf); + opt_time += tms_buf.tms_utime - ltime; +#endif /* VERBOSE */ + need_res=0; +#ifdef SHOWSTEP + printf("\ngen"); +#endif + genstmt(stmt); + genreturn(NIL_SNODE); +#ifdef SHOWSTEP + printf(" ok "); +#endif +/* + * It is desirable to postpone the generation of the + * stack fram until here since it it now possible for + * the code generation routines to allocate stack space + * as they want. A little hack (defining g_coder) + * allows us to put the following code to the BEGINNING + * of a function body. Note that this means that we have + * to generate all code in REVERSE order + */ + lineid = line0; + lc_auto += max_scratch; +#ifdef MC680X0 + genfuncbegin(); +#endif +#ifdef INTEL_386 + if (lc_auto != 0) + g_coder(op_sub, 4, mk_immed(lc_auto), mk_reg(STACKPTR)); + g_coder(op_mov, 4, mk_reg(STACKPTR), mk_reg(FRAMEPTR)); + g_coder(op_push, 4, mk_reg(FRAMEPTR), NIL_AMODE); +#endif +#ifdef ICODE + if (icode_option) + fprintf(icode, "\t$framesize was %ld\n", lc_auto); +#endif +} +// vim:ts=4:sw=4 diff --git a/gtc/src/getasm.c b/gtc/src/getasm.c new file mode 100644 index 0000000..a2b9b31 --- /dev/null +++ b/gtc/src/getasm.c @@ -0,0 +1,718 @@ +/* + * GTools C compiler + * ================= + * source file : + * inline assembly extraction routines + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifdef ASM +#define DECLARE +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifdef PC +#ifdef SHORT_INT +#undef int +#endif +#include +#ifdef SHORT_INT +#define int short +#endif +#endif + +#define newline semicolon + +#ifndef AS +#define label(__l) 12345 +#endif + +xstatic char * readonly asmreservedlist[] = { + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "b", + "ccr", + "d0", + "d1", + "d2", + "d3", + "d4", + "d5", + "d6", + "d7", + "l", + "s", + "sp", + "sr", + "usp", + "w", +}; + +xstatic readonly struct oplst_elem { + char *s; + enum(e_op) ov; + short val; +} oplist[] = + +{{ + "add", op_add +}, { + "adda", op_add +}, { + "addi", op_addi +}, { + "addq", op_addq +}, { + "addx", op_addx +}, { + "and", op_and +}, { + "andi", op_andi +}, { + "asl", op_asl +}, { + "asr", op_asr +}, { + "bcc", op_bhs +}, { + "bchg", op_bchg +}, { + "bclr", op_bclr +}, { + "bcs", op_blo +}, { + "beq", op_beq +}, { + "bge", op_bge +}, { + "bgt", op_bgt +}, { + "bhi", op_bhi +}, { + "bhs", op_bhs +}, { + "ble", op_ble +}, { + "blo", op_blo +}, { + "bls", op_bls +}, { + "blt", op_blt +}, { + "bmi", op_bmi +}, { + "bne", op_bne +}, { + "bpl", op_bpl +}, { + "bra", op_bra +}, { + "bset", op_bset +}, { + "bsr", op_bsr +}, { + "btst", op_btst +}, { + "bvs", op_bvs +}, { + "bvc", op_bvc +}, { + "chk", op_chk +}, { + "clr", op_clr +}, { + "cmp", op_cmp +}, { + "cmpi", op_cmpi +}, { +#ifndef LIGHT_DBXX_AND_SXX + "dbcc", op_dbhs +}, { + "dbcs", op_dblo +}, { +#endif + "dbeq", op_dbeq +}, { + "dbf", op_dbra +}, { +#ifndef LIGHT_DBXX_AND_SXX + "dbge", op_dbge +}, { + "dbgt", op_dbgt +}, { + "dbhi", op_dbhi +}, { + "dbhs", op_dbhs +}, { + "dble", op_dble +}, { + "dblo", op_dblo +}, { + "dbls", op_dbls +}, { + "dblt", op_dblt +}, { + "dbmi", op_dbmi +}, { +#endif + "dbne", op_dbne +}, { +#ifndef LIGHT_DBXX_AND_SXX + "dbpl", op_dbpl +}, { +#endif + "dbra", op_dbra +}, { +#ifndef LIGHT_DBXX_AND_SXX + "dbvs", op_dbvs +}, { + "dbvc", op_dbvc +}, { +#endif + "dc", op_dc +}, { + "dcb", op_dcb +}, { + "divs", op_divs +}, { + "divu", op_divu +}, { + "ds", op_ds +}, { + "eor", op_eor +}, { + "eori", op_eori +}, { + "even", op_even +}, { + "exg", op_exg +}, { + "ext", op_ext +}, { + "jmp", op_jmp +}, { + "jsr", op_jsr +}, { + "lea", op_lea +}, { + "link", op_link +}, { + "lsl", op_lsl +}, { + "lsr", op_lsr +}, { + "move", op_move +}, { + "movea", op_move +}, { + "movem", op_movem +}, { + "moveq", op_moveq +}, { + "muls", op_muls +}, { + "mulu", op_mulu +}, { + "neg", op_neg +}, { + "negx", op_negx +}, { + "nop", op_dc, 0x4e71 +}, { + "not", op_not +}, { + "or", op_or +}, { + "ori", op_ori +}, { + "pea", op_pea +}, { + "rol", op_rol +}, { + "ror", op_ror +}, { + "roxl", op_roxl +}, { + "roxr", op_roxr +}, { + "rte", op_dc, 0x4e73 +}, { + "rtr", op_dc, 0x4e77 +}, { + "rts", op_rts +}, { +#ifndef LIGHT_DBXX_AND_SXX + "scc", op_shs +}, { + "scs", op_slo +}, { + "seq", op_seq +}, { + "sf", op_sf +}, { + "sge", op_sge +}, { + "sgt", op_sgt +}, { + "shi", op_shi +}, { + "shs", op_shs +}, { + "sle", op_sle +}, { + "slo", op_slo +}, { + "sls", op_sls +}, { + "slt", op_slt +}, { + "smi", op_smi +}, { + "sne", op_sne +}, { + "spl", op_spl +}, { + "st", op_st +}, { +#endif + "sub", op_sub +}, { + "suba", op_sub +}, { + "subi", op_subi +}, { + "subq", op_subq +}, { + "subx", op_subx +}, { +#ifndef LIGHT_DBXX_AND_SXX + "svs", op_svs +}, { + "svc", op_svc +}, { +#endif + "swap", op_swap +}, { + "tas", op_tas +}, { + "trap", op_trap +}, { + "trapv", op_dc, 0x4e76 +}, { + "tst", op_tst +}, { + "unlk", op_unlk +}}; +#ifndef LIGHT_DBXX_AND_SXX +#define asm_N 118 +#else +#define asm_N 85 +#endif + +int lastreg CGLOB; + +void asm_getsym() { + int l=lineid; + getsym(); + if (lineid!=l) + cached_sym=lastst, cached_lineid = lineid, lastst=newline; +} + +struct ocode *asm_head CGLOB; +xstatic struct ocode *asm_tail CGLOB; +struct ocode *new_code(int s) { + struct ocode *new_ocode; + new_ocode = (struct ocode *) xalloc(s, OCODE); +#ifdef NO_CALLOC + new_ocode->fwd = 0; +#endif + if (!asm_head) { + asm_head = new_ocode; +#ifdef NO_CALLOC + new_ocode->back = 0; +#endif + } else { + new_ocode->back = asm_tail; + asm_tail->fwd = new_ocode; + } + return asm_tail = new_ocode; +} + +void add_code(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2, int line) { +/* + * generate a code sequence into the asm list. + */ + struct ocode *new_ocode = new_code(sizeof(struct ocode)); + new_ocode->opcode = op; + new_ocode->length = len; + if ((unsigned int)len>4 || len==3) + ierr(ADD_CODE,1); + new_ocode->oper1 = ap1; + new_ocode->oper2 = ap2; +#ifdef DB_POSSIBLE + new_ocode->line=line; +#endif +#ifdef AS + new_ocode->opt = 1; +#endif +} + +void add_label(int lab) { + struct lbls *new_ocode = (struct lbls *)new_code(sizeof(struct lbls)); + new_ocode->opcode = op_label; + new_ocode->lab = lab; +} + +int has_autocon(struct enode *ep) { + switch (ep->nodetype) { + case en_icon: +#ifndef NOFLOAT + case en_fcon: +#endif + case en_labcon: + case en_nacon: + return 0; + case en_autocon: + return 1; + case en_add: + return has_autocon(ep->v.p[0]) + has_autocon(ep->v.p[1]); + case en_sub: + return has_autocon(ep->v.p[0]) - has_autocon(ep->v.p[1]); + case en_uminus: + return - has_autocon(ep->v.p[0]); + default: + uerrc("invalid expression"); + return 0; // avoid compiler warning + } +} +void get_offset(struct amode *ap) { + asm_xflag++; + asm_zflag++; +/* if (!strcmp(lastid,"__Int5_body__")) + printf("fgio");*/ + if (!exprnc(&ap->offset)) + error(ERR_INTEXPR); + else { + opt4(&ap->offset); + if (ap->offset->nodetype==en_deref) + ap->offset=ap->offset->v.p[0]; +#ifdef OLD_AMODE_INPUT + if (lastst==kw_offs_end) { +#else + if (lastst==openpa) { +#endif + asm_getsym(); + if (lastst==kw_areg) { + ap->preg=lastreg; + asm_getsym(); + if (lastst==comma) { + asm_getsym(); + ap->sreg=lastreg; + if (lastst==kw_dreg) + ap->mode=am_indx2; + else if (lastst==kw_areg) + ap->mode=am_indx3; + else error(ERR_SYNTAX); + asm_getsym(); + if (lastst==dot) { +#ifdef EXT_AS_ID + asm_getsym(); +#else + char c=lastch; +#endif + ap->slen=0; +#ifdef EXT_AS_ID + if (lastst==id && lastid[1]==0) { + char c=lastid[0]; +#endif + if (c=='b' || c=='s') ap->slen=1; + else if (c=='w') ap->slen=2; + else if (c=='l') ap->slen=4; +#ifdef EXT_AS_ID + asm_getsym(); + } +#else + getch(); + asm_getsym(); +#endif + if (!ap->slen) + error(ERR_SYNTAX); + } else ap->slen=2; + } else ap->mode=am_indx; + needpunc(closepa); + } else if (lastst==id && !strcmp("pc",lastid)) + ap->mode=am_pcrel, asm_getsym()/* 'pc' */, asm_getsym()/* ')' */; + } else + ap->mode=am_direct; + if (has_autocon(ap->offset)) { + if (ap->mode!=am_direct && (ap->mode!=am_indx || ap->pregmode=am_indx, ap->preg=FRAMEPTR-AREGBASE; + } + } + asm_zflag--; + asm_xflag--; +} + +xstatic enum(e_op) lastop CGLOB; +xstatic int lastval CGLOB,second_parm CGLOB; +struct amode *get_asmparam() { + struct amode *ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE); + ap->preg=lastreg; +/* if ((long)&ap->offset==0x7D53CC) + printf("gio");*/ + if (lastop==op_movem && (lastst==kw_dreg || lastst==kw_areg)) { + unsigned int mask=0; int n,d,x; + if (second_parm) ap->mode=am_mask2,x=0; + else ap->mode=am_mask1,x=15; + /* Format : d0=0x8000 in mask1, 0x0001 in mask2 */ + while (lastst==kw_dreg || lastst==kw_areg) { + d=n=lastreg+((lastst-kw_dreg)<<3); + asm_getsym(); + if (lastst==minus) { + asm_getsym(); + if (lastst==kw_dreg || lastst==kw_areg) + d=lastreg+((lastst-kw_dreg)<<3); + else error(ERR_SYNTAX); + asm_getsym(); + } + if (n>d) + error(ERR_SYNTAX); + while (n<=d) { + mask |= 1<<(n^x); + n++; + } + if (lastst==divide) + asm_getsym(); + } + ap->offset=mk_icon(mask); + } else if (lastst==kw_dreg) + ap->mode=am_dreg, asm_getsym(); + else if (lastst==kw_areg) + ap->mode=am_areg, asm_getsym(); + else if (lastst==openpa) { + asm_getsym(); + if (lastst==kw_areg) { + ap->preg=lastreg; + asm_getsym(); + needpunc(closepa); + if (lastst==plus) + asm_getsym(), ap->mode=am_ainc; + else ap->mode=am_ind; + } else { + cached_sym=lastst; + cached_lineid=lineid; + lastst=openpa; + get_offset(ap); + } + } else if (lastst==minus) { + if (lastch=='(') { // a bit dirty, but doesn't matter since you never type '- (an)' + asm_getsym(); // remove '-' + asm_getsym(); // remove '(' + if (lastst==kw_areg) { + ap->preg=lastreg; + asm_getsym(); + needpunc(closepa); + ap->mode=am_adec; + } else { + get_offset(ap); + needpunc(closepa); + ap->offset=mk_node(en_uminus,ap->offset,NIL_ENODE); + opt4(&ap->offset); + } + } else get_offset(ap); + } else if (lastst==sharp) { + asm_getsym(); + get_offset(ap); + if (ap->mode!=am_direct) + error(ERR_SYNTAX); + else ap->mode=am_immed; + } else if (lastst==id && ((!lastid[2] && lastid[1]=='r' && lastid[0]=='s') || + (!lastid[3] && ((lastid[2]=='r' && lastid[1]=='c' && lastid[0]=='c') || + (lastid[2]=='p' && lastid[0]=='u' && lastid[1]=='s'))))) { + ap->mode=lastid[2]?(lastid[0]=='u'?am_usp:am_ccr):am_sr; + getsym(); + } else get_offset(ap); + return ap; +} + +/* dichotomic keyword search */ +void asm_searchkw() { + char *s1,*s2,c; + const struct oplst_elem *op_ptr; + int a=0,b=asm_N-1,m; +#ifdef PC + if (sizeof(oplist)/sizeof(struct oplst_elem)!=asm_N) + fatal("BUILD ERROR, WRONG ASM KEYWORDS #"); +#endif +/* if (!strcmp("addq",lastid)) + printf("");*/ + while (a<=b) { + m=(a+b)>>1; + op_ptr=&oplist[m]; + s1=lastid; + s2=op_ptr->s; + do { + if (!(c=*s2++)) { + if (!*s1) { + lastst=kw_instr; + lastop=op_ptr->ov; + lastval=op_ptr->val; + return; + } + /* otherwise continue ( < 'addi' doesn't match 'add' but yet exists) */ + } + } while (*s1++==c); + if (s1[-1]>1; + s1=lastid; + s2=asmreservedlist[m]; + do { + if (!(c=*s2++)) { + if (!*s1) + return 1; + /* otherwise continue ( < 'addi' doesn't match 'add' but yet exists) */ + } + } while (*s1++==c); + if (s1[-1]stype = st_asm; + snp->count = 1; + asm_flag++; + asm_head = 0; + getsym(); + if (lastst == kw_volatile) + getsym(); + if (lastst != begin) + error(ERR_EXPREXPECT); + asm_getsym(); + while (getasm_main()); + snp->v1.i=(long)asm_head; + asm_flag--; + needpunc(end); + needpunc(semicolon); +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + return snp; +} +#undef newline +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/getsym.c b/gtc/src/getsym.c new file mode 100644 index 0000000..7216aa6 --- /dev/null +++ b/gtc/src/getsym.c @@ -0,0 +1,2293 @@ +/* + * GTools C compiler + * ================= + * source file : + * symbol extraction routines + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define DECLARE +#include "define.h" +_FILE(__FILE__) +#include "version.h" +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifdef PCH +#include "pch.h" +#endif +#ifndef NOFLOAT +#include "ffplib.h" +#define FFP_TEN 0xA0000044 +#define FFP_TENINV 0xCCCCCD3D +#endif +#ifdef PC +#ifdef SHORT_INT +#undef int +#endif +#include +#include +#ifdef SHORT_INT +#define int short +#endif +#endif + +#ifdef PC +unsigned long _w2ul(TI_LONG *x) { + return ((unsigned long)x->x0<<24)+((unsigned long)x->x1<<16)+ + ((unsigned long)x->x2<< 8)+((unsigned long)x->x3<< 0); +} +unsigned short _w2us(TI_SHORT *x) { + return ((unsigned short)x->hi<<8)+x->lo; +} +#endif + +FILE *input CGLOB; +int total_errors CGLOB; +int err_force_line CGLOB,err_cur_line CGLOB,err_assembly CGLOB; +int lastch CGLOB; +enum(e_sym) lastst CGLOB; +int lastst_flag CGLOB; +char lastid[MAX_ID_LEN+1]; +int got_sym CGLOB; +#ifdef PCH +char curpch[MAX_ID_LEN+1]; +#endif +int lastcrc CGLOB; +struct sym *lastsp CGLOB; +char laststr[MAX_STRLEN + 1]; +int lstrlen CGLOB; +unsigned long ival CGLOB; +#ifndef NOFLOAT +double rval CGLOB; +#endif + +//#define MAX_NUM_ERRS 80 +#define MAX_NUM_ERRS 2 +int err_num[MAX_NUM_ERRS]; +int numerrs; +char linein[LINE_LENGTH]; +//#define linemax &linein[LINE_LENGTH] +//xstatic int act_line; +//xstatic char act_file[100] = ""; +//xstatic int lineno; + +#ifdef OLD_MACRO +#define CHAR_POPMAC 1 +#define MAX_MAC_NUM 100 +TABLE *mac_stk[MAX_MAC_NUM]; +TABLE **mac_sp; +#else +#define MAX_MAC_ARGS 20 +#endif + +char *curname CGLOB; +char *lptr CGLOB; /* shared with preproc */ +char *inclname[10]; /* shared with preproc */ +FILE *inclfile[10]; /* shared with preproc */ +int inclline[10]; /* shared with preproc */ +int inclifreldepth[10]; /* shared with preproc */ +#ifdef GTDEV +int inclread[10]; /* shared with preproc */ +int inclcoeff[10]; /* shared with preproc */ +#endif +int incldepth; /* shared with preproc */ +char *linstack[20]; /* stack for substitutions */ +char chstack[20]; /* place to save lastch */ +int lstackptr CGLOB;/* substitution stack pointer */ +int preproc_stmt CGLOB; +#ifdef PC +enum(e_sym) cached_sym CGLOB; /* cached symbol (for preproc-emulation prefetching) */ +#else +enum(e_sym) _cached_sym CGLOB; +#endif +int cached_flag CGLOB; +int cached_lineid CGLOB; +enum(e_sym) forbid CGLOB; +int pch_init CGLOB; + +extern int getch_comment,getch_pp,getch_in_string,getch_noppdir; + +xstatic char *linemin CGLOB,*linemax CGLOB; + +int getline(int f); +int getcache(enum(e_sym) f); + +#ifndef isalnum +#define isalnum _isalnum +static int isalnum(char c) { +/* + * This function makes assumptions about the character codes. + */ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9'); +} +#endif + +//#ifndef isidch +#ifdef PC +static int isidch(char c) { + return (c>='0'&&c<='9') || (c>='A'&&c<='Z') || (c>='a'&&c<='z') + || c == '_' || c == '$'; +} +static int isbegidch(char c) { + return (c>='A'&&c<='Z') || (c>='a'&&c<='z') || c == '_' || c == '$'; +} +#else +#define isidch(___c) ({register short __c=(___c); \ +(__c>='0'&&__c<='9') || (__c>='A'&&__c<='Z') || (__c>='a'&&__c<='z') || __c=='_' || __c=='$';}) +#define isbegidch(___c) ({register short __c=(___c); \ +(__c>='A'&&__c<='Z') || (__c>='a'&&__c<='z') || __c=='_' || __c=='$';}) +#endif +//#endif + +#undef isspace +#ifdef PC +#define isspace _isspace +int isspace(int c) { + return (c == ' ' || c == '\t' || c == '\n'); +} +#else +#define isspace(___c) ({register short __c=(___c); \ +__c==' ' || __c=='\t' || __c=='\n';}) +#endif + +#ifndef isdigit +#define isdigit _isdigit +static int isdigit(char c) { +/* + * This function makes assumptions about the character codes. + */ + return (c >= '0' && c <= '9'); +} +#endif + +#ifdef GTDEV +void progr_initforcurfile(); +int progr CGLOB,progr_readtonow CGLOB,progr_coeff CGLOB; +#endif +#define stringify_noexpand(s) #s +#define stringify(s) stringify_noexpand(s) +char * readonly stddefines="__GTC__\000"stringify(GTC_MAJOR)"\0" "__GTC_MINOR__\000"stringify(GTC_MINOR)"\0" "__VERSION__\000\""GTC_VERSION"\"\0" + "mc68000\000\0" "__embedded__\000\0" + "__DATE__\000\""__DATE__"\"\0" "__TIME__\000\""__TIME__"\"\0" + ; +void insert_macros(char *p) { + SYM *sp; + while (*p) { + sp=(SYM *)xalloc((int)sizeof(SYM), _SYM); + sp->name=p; + while (*p++); + sp->value.s=p; + while (*p++); + insert(sp,&defsyms); + } +} +#ifdef PC +/* warning: duplicated in cmain.c! */ +enum OptionModes { optn_parse=0, optn_global_init, optn_global_init_post, optn_preproc_init }; +void option_parse_all(enum(OptionModes) ex_mode); +#endif +extern TI_SHORT func_attr; +#ifdef PCH +void initpch() { + pchnum = 0; +} +#endif +void initsym() { +#if defined(PC) || (defined(PCH) && defined(MULTIFILE)) + int i; +#endif +#ifdef OLD_MACRO + lptr = &linein[MAX_MAC_LEN+1]; +#else + lptr = linein+1; +#endif + *lptr = 0; + numerrs = 0; + total_errors = 0; + err_force_line = -1; + err_assembly = 0; + lineno = lineid = 0; + ifsd = ifskip = ifdepth = ifreldepth = 0; + ifcount[0] = 0; + ifval[0] = 0; +#ifdef PCH +#ifdef MULTIFILE + for (i=pchnum;i--;) + memset(pchtab[i],0,(short)w2us(pchhead[i]->nID)); +#endif + pch_init = 0; +#endif +#ifdef MID_DECL + middle_decl = 0; +#endif +#ifdef NEW_ATTR +#ifdef PC + func_attr.lo = -1; + func_attr.hi = -1; +#else + func_attr = -1; +#endif +#endif +#ifdef OLD_MACRO + mac_sp = &mac_stk[MAX_MAC_NUM]; +#endif +#ifdef FLINE_RC + fline_rc=0; +#endif +#ifdef GTDEV + progr_initforcurfile(); +#endif + getch_comment=0; + getch_pp=0; + getch_in_string=0; + getch_noppdir=0; + preproc_stmt=0; + /*cached_sym2=*/cached_sym=-1; + forbid=-1; +#ifdef MIN_TEMP_MEM + min_temp_mem=0; +#endif + linemin=linein+1; + linemax=linein+LINE_LENGTH; + global_strings = 0; + hashinit(&defsyms); // this is because the file could *begin* with #define's and/or #if's + global_flag = 1; // (idem) + temp_local = 0; + /* pre-defined preprocessor macros */ + insert_macros(stddefines); +#ifdef PC + option_parse_all(optn_preproc_init); +#endif +} + +#if defined(PC) || defined(FLASH_VERSION) +xstatic readonly char * readonly __err[] = { + "syntax error", + "illegal character", + "illegal floating-point constant", + "illegal type", + "undefined identifier '%s'", + "no field allowed here", + "'%c' expected", + "identifier expected", + "initialization invalid here", + "incomplete struct/union/enum declaration", + "illegal initialization", + "too many initializers", + "illegal storage class", + "function body expected", + "pointer type expected", + "function type expected", + "'%s' is not a member of structure", + "l-value required", + "error dereferencing a pointer", + "mismatch between types '%s' and '%s'", + "expression expected", + "'while' expected in do-loop", + "enum value out of range", + "duplicate case label", + "undefined label", + NULL/*"preprocessing error"*/, + "declared argument missing", + "illegal field width", + "illegal constant integer expression", + "cannot cast from '%s' to '%s'", + "integer-valued type expected", + "error casting a constant", + "illegal redeclaration of '%s'", + NULL/*"error while scanning parameter list"*/, + "bad field type, must be unsigned or int", + "invalid #include statement", + "cannot open file \"%s\"", + "wrong #define", + "#error: %s", + "duplicate symbol '%s'", + "constant expression expected", + "value out of range", + "too many parameters to function", + "too few parameters to function", + "invalid case range", + "unexpected end of file", + "%s", + "internal limit exceeded: %s", + "invalid relocation in expression", +}; +#endif + +int _getline(int listflag,char *base) { + //int rv; //char *p; +#ifdef LISTING + int i; +#endif + char *lptr=base; +#ifdef LISTING + if (lineno > 0 && list_option && !ifskip) { + fprintf(list, "%s:%6d", lptr, lineno); + for (i = 0; i < numerrs; i++) + fprintf(list, " error: %s\n", __err[err_num[i]]); + numerrs = 0; + } +#endif +#ifdef GTDEV + { + int new_progr=((long)/*progr_readtonow*/(((void *)input->fpos-input->base)-7)*progr_coeff)>>16; + if (new_progr!=progr) + progr=new_progr,progr_process(func_sp?func_sp->name:0,curname,new_progr); + } +#endif + do { + ++lineno; + // ++act_line; + if ((int)(&linein[LINE_LENGTH-1]-lptr)<100) + uerrsys("line is too long"); + if (!fgets(lptr,(int)(&linein[LINE_LENGTH-1]-lptr),input)) { + if (incldepth > 0) { + if (ifreldepth) uerrc("unterminated '#if' statement"); + fclose(input); + input = inclfile[--incldepth]; + curname = inclname[incldepth]; +#ifdef GTDEV + progr_readtonow = inclread[incldepth]; + progr_coeff = inclcoeff[incldepth]; +#endif + lineno = inclline[incldepth]; + ifreldepth = inclifreldepth[incldepth]; + #ifdef OLD_MACRO + lptr=&linein[MAX_MAC_LEN+1]; + #else + lptr=linein+1; + #endif + *lptr='\n'; lptr[1]=0; + return 0; + // return getline(0); + } else + return 1; + } +#ifdef PC + if (strlen(lptr)>=2 && lptr[strlen(lptr)-2]=='\r') // workaround so that Unix version accepts DOS files + strcpy(&lptr[strlen(lptr)-2],"\n"); +#endif + } while (*(lptr+=strlen(lptr)-2)=='\\' && !ifskip); +#ifdef GTDEV + progr_readtonow+=strlen(lptr); // this isn't byte-precise, but OK for a percentage :) +#endif + /* the following instruction is used so that when reading the character after '#endif' + * at the end of a header file (in order to tell 'endif' from 'endif_foo'), the + * preprocessor still operates in the current header file, preventing it from + * generating an error since a '#if' statement isn't complete */ + /*if (lineno==0x1DC) + bkpt();*/ + if (lptr[1]!='\n') /* lptr[2] is '\0' at this point */ + lptr++,lptr[1]='\n',lptr[2]=0; + preproc_stmt=0; + return 0; +} + +int getline(int listflag) { + return _getline(listflag, + #ifdef OLD_MACRO + lptr=&linein[MAX_MAC_LEN+1] + #else + lptr=linein+1 + #endif + ); +/* p=lptr; + while (*p && isspace(*p)) p++; + if (*p == '#') { + lptr=p;*/ + /* ++lptr; + lastch = ' '; + getsym(); + if (lastst == id && !strcmp(lastid, "line")) + getsym(); + if (lastst != iconst) + error(ERR_PREPROC); + act_line = ival-1; + // scan file name + i = 0; + while (isspace(*lptr)) + lptr++; + if (*lptr == '"') + lptr++; + // assume that a filename does not end with double-quotes + while (*lptr != '\0' && *lptr != '"' && !isspace(*lptr)) + act_file[i++] = *lptr++; + // DECUS cpp suppresses the name if it has not changed + // in this case, i is simply zero, and then we keep the + // old name + if (i > 0) + act_file[i] = '\0'; + return getline();*/ +/* preproc_stmt=1; + return preprocess(); + }*/ +/* while ((c=*lptr++)) + if (c=='#' && *lptr=='#') { + char *p=lptr-1; + char id[MAX_ID_LEN+1],c=*lptr++; + int i = 0; SYM *sp; + while (isidch(c=*lptr++)) { + if (i < MAX_ID_LEN) + id[i++] = c; + } + id[i] = '\0'; + if (mac_sp!=&mac_stk[MAX_MAC_NUM] && (sp = search(lastid, lastcrc, *mac_sp))) { + char *q=sp->value.s,*e=p+strlen(q); + //memmove(p,lptr,&linein[MAX_MAC_LEN+1000]-lptr); + //memmove(e,p,&linein[MAX_MAC_LEN+1000]-e); + memmove(e,lptr,&linein[MAX_MAC_LEN+1000]-(lptr>e?lptr:e)); + memcpy(p,q,e-p); + lptr=e; + } + } + lptr=&linein[MAX_MAC_LEN+1];*/ +// return 0; +} + +/* + * getch - basic get character routine. + */ +xstatic int getch_comment CGLOB,getch_pp CGLOB,getch_in_string CGLOB; +int getch_noppdir CGLOB; +xstatic char *getch_p CGLOB; +int getch() { + if (getch_pp) goto ppdo; + do { +#ifdef MACRO_PPDIR + if (lptr!=linein+1 && lptr[-1]=='\n' && *lptr) { + lastch=*lptr; + goto pptest_continue; /* we needn't bother about comments since all are removed + * because dodefine() calls getch() to read the macro */ + } +#endif + while ((lastch = *(unsigned char *)lptr++) == '\0') { + if( lstackptr > 0 ) { + lptr = linstack[--lstackptr]; + lastch = chstack[lstackptr]; + return lastch; + } + if (getline(incldepth == 0)) + return lastch = -1; + pptest_continue: + if (!getch_comment) { + getch_p=lptr; + while (*getch_p && isspace(*getch_p)) getch_p++; + if (*getch_p == '#' && !getch_noppdir) { + getch_pp=1; + lastch = ' '; + return 0; + ppdo: + getch_pp=0; + lptr=getch_p; + preproc_stmt=1; + if (preprocess()) return lastch = -1; + preproc_stmt=0; + goto pptest_continue; + } + } + } + if (lastch=='/' && !getch_in_string) { + if (*(unsigned char *)lptr=='/' && !getch_comment) { + while (*(unsigned char *)lptr++) + if (*(char *)lptr=='\n' && lptr[1]) + uwarn("multi-line comment"); + lptr--; + return getch(); + } else if (*(unsigned char *)lptr=='*') { + char last; + if (getch_comment) { + uwarn("/" "* in comment block"); + return 0; + } + getch_comment=1; + do { + last=(char)lastch; + if (getch()<0) uerrc("unended comment block"); + } while (last!='*' || lastch!='/'); + getch_comment=0; + return getch(); + } + } +/*#ifdef ASM + else if (asm_flag && lastch==';' && !comment) { + while (*(unsigned char *)lptr++); + lptr--; return getch(); + } +#endif*/ +#ifdef OLD_MACRO + if (lastch==CHAR_POPMAC) { + mac_sp++; return getch(); + } +#endif + } while (ifskip && !getch_comment/* since otherwise we would 'eat' the callers' chars */ + && !preproc_stmt); + //if (lastch=='\r') lastch='\n'; +#ifdef OLD_MACRO + if (isspace(lastch) || lastch=='#') { + char c,*z=lptr-1; + while (isspace(c=*z++)); // skip spaces + if (c=='#' && *z=='#') { // ## ? + char *p=z-1; + char id[MAX_ID_LEN+1],c=*z++; + int i = 0; SYM *sp; + while (isidch(c=*z++)) { + if (i < MAX_ID_LEN) + id[i++] = c; + } + id[i] = '\0'; + if (mac_sp!=&mac_stk[MAX_MAC_NUM] && (sp = search(id, -1, (HTABLE *)*mac_sp))) { + char *q=sp->value.s,*e=p+strlen(q); + //memmove(p,z,&linein[MAX_MAC_LEN+999]-z); + //memmove(e,p,&linein[MAX_MAC_LEN+999]-e); + memmove(e,z,&linein[MAX_MAC_LEN+999]-(z>e?z:e)); + memcpy(p,q,e-p); + lptr=p; + } else lptr=p+2; // ignore ## + return getch(); + } + } +#endif + /*if (lastch=='@') + bkpt();*/ + return 0; +} + +#ifndef GTDEV +void locate(void) { + if (err_force_line IS_INVALID) { +#ifdef PC + msg3("%s:%d: ", curname, lineno); +#else + char lcl[6+1],*p=lcl,*l=lptr-1; int n=6; + while (n-- && *l!='\n') *p++=*l++; + *p=0; + msg4("%s:%d (%s): ", curname, lineno, lcl); +#endif + } else + msg3("%s:%d: ", curname, err_force_line); +} +#endif + +#if 0 +/* + * error - print error information + */ +void error(int n) { + debug('e'); + if (numerrs < MAX_NUM_ERRS) + err_num[numerrs++] = n; + ++total_errors; + locate(); +#ifdef PC + msg3("error %d: %s\n", n, __err[n]); +#else + msg2("error %d\n", n); +#endif +/* + * Do not proceed if more than MAX_ERROR_COUNT errors were detected. + * MAX_ERROR_COUNT should be high since each error might be reported + * more than once + */ + if (total_errors > MAX_ERROR_COUNT) { + msg("Too many errors\n"); + _exit(1); + } +} +#endif + +#if 0 +void do_warning(char *s, ...) { +#ifndef __GTC__ + va_list args; + va_start(args,s); + locate(); + msg("warning: "); + vmsg(s,args); + va_end(args); +/* if (total_errors > MAX_ERROR_COUNT) { + msg("Too many errors\n"); + _exit(1); + }*/ +#else + +#endif +} +#endif + +#include "error.c" + +/* + * getidstr - get an identifier string, that is either a macro name or an include file. + * + * Note that there are no escape characters + */ +void getidstr() { + register int i; + i = 0; + while (isidch(lastch) || lastch=='\\' || lastch=='/' +#ifdef PC + || lastch=='.' + || lastch==':' + || lastch=='-' +#endif + ) { + if (lastch=='/') lastch='\\'; +// if (lastch=='\\') getch(); + if (i < MAX_ID_LEN) + lastid[i++] = lastch; + getch(); + } + lastid[i] = '\0'; + lastcrc=crcN(lastid); +} + +void getrawid() { + register int i = 0; + while (isidch(lastch)) { + if (i < MAX_ID_LEN) + lastid[i++] = lastch; + getch(); + } + lastid[i] = '\0'; +#ifdef PCH + if (!lastid[1] && lastid[0]=='_') + memcpy(lastid,curpch,MAX_ID_LEN+1); +#endif + lastcrc=crcN(lastid); +} + +void skipspace() { + while (isspace(lastch)) getch(); +} + +extern HTABLE defsyms; +// including #define's +#ifdef OLD_MACRO +int getid(int c) { + register int i; + SYM *sp; + if (c>=0) { + lastid[0] = c; + i = 1; + while (isidch(lastch)) { + if (i < MAX_ID_LEN) + lastid[i++] = lastch; + getch(); + } + lastid[i] = '\0'; + } +#ifdef PCH + if (!lastid[1] && lastid[0]=='_') + memcpy(lastid,curpch,MAX_ID_LEN+1); +#endif +//search_id: + lastcrc=crcN(lastid); +#ifdef OLD_MACRO + if (mac_sp==&mac_stk[MAX_MAC_NUM] || !(sp = search(lastid, lastcrc, (HTABLE *)*mac_sp))) +#endif + sp = search(lastid, lastcrc, &defsyms); + if (sp +#ifdef OLD_MACRO + && strcmp(sp->value.s,sp->name) +#endif + ) { + char *p,*q,c; TABLE *tp; + if ((tp=(TABLE *)sp->tp)!=NULL) { +#ifdef OLD_MACRO + int d=0,nmac=sp->used,nargs=0; + char buf[150],*bp=buf; + SYM *s=tp->head; + *--mac_sp=tp; + if (mac_sp<=mac_stk) fatal("GETMAC/stk_overflow"); + skipspace(); + if (lastch!='(') fatal("GETMAC"); + while (1) { + getch(); + if (lastch=='(') d++; + else if (lastch==')') { if (--d<0) break; } + else if (lastch==',' && !d && (sp->storage_class!=sc_vamac || nargs!=nmac-1)) { + if (nargsvalue.s=strsave(bp=buf); nargs++; + s=s->next; continue; + } else fatal("GETMAC"); + } + *bp++=lastch; + if (bp>=&buf[150]) fatal("GETMAC/too_long"); + } + if (tp->head) { + *bp=0; s->value.s=strsave(buf); + if (++nargs!=nmac) fatal("GETMAC"); + } +#else + int d=0,nmac=sp->used,nargs=0,concat_mode; + char ps[500],args[300]; + char *argb=args,*argp=args; + char c,lastsym[MAX_ID_LEN+1],*psptr,*lptrsav; int lastchsav=lastch; + SYM *s=tp->head; + skipspace(); + if (lastch!='(') return 0; + while (1) { + getch(); + if (lastch=='(') d++; + else if (lastch==')') { if (--d<0) break; } + else if (lastch==',' && !d && (sp->storage_class!=sc_vamac || nargsvalue.s=argb; nargs++; argb=argp; + s=s->next; continue; + } else fatal("Too many args to macro"); + } + if (argb!=argp || !isspace(lastch)) /* remove leading whitespace */ + *argp++=lastch; + if (argp>=&args[350]) fatal("GETMAC/too_long"); + } + if (tp->head) { /* i.e. sc_vamac */ + while (isspace(argp[-1])) /* remove trailing whitespace */ + argp--; + *argp=0; s->value.s=argb; + nargs++; /* this var argument might appear to be "" */ + } + if (nargsvalue.s; + psptr=ps; concat_mode=0; + while ((c=*argp++)) { + if (isbegidch(c)) { + int i=0; SYM *asp; char *str=lastsym; + while (isidch(c)) { + if (ivalue.s; + if (concat_mode && asp==s && sp->storage_class==sc_vamac && !*str + && psptr[-1]==',') + psptr--; + } else memexg(lastsym,lastid,MAX_ID_LEN+1); + i=strlen(str); + memcpy(psptr,str,i); psptr+=i; + concat_mode=0; + } else if (c=='#') { + if (*argp!='#') { /* single # */ + int i=0; SYM *asp; char *str=lastsym; + if (!isbegidch(c=*argp++)) + fatal("# id : Syntax"); + while (isidch(c)) { + if (ivalue.s; + *psptr++='"'; + while ((c=*str++)) { + if (/*c=='\\' ||*/ c=='"') *psptr++='\\'; // ANSI specifies #x with x=\x7F should be "\x7F"... + *psptr++=c; + } + *psptr++='"'; + concat_mode=0; + } else { /* ## */ + argp++; + concat_mode=1; + } + } else if (!concat_mode || !isspace(c)) + concat_mode=0, *psptr++=c; + } + *psptr=0; + q=ps; + lptr-=strlen(q); // se positionner avant le define + // (pas trs catholique mais rapide) + if ((p=lptr)value.s; + lptr-=strlen(q)+1; // se positionner avant le define + // (pas trs catholique mais rapide) +#ifdef OLD_MACRO + if (tp) lptr--; +#endif + if ((p=lptr)'%s', '%s', %d)\n", len,in, q, in, need_ds_update); +#else + char *q_overlapfree = q; +#endif + if ((unsigned int)(oldbytes+n)>(unsigned int)r) + uerrsys("line too long"); + if (n>0) + memmove(in+n,in,oldbytes); + else if (n<0) + memmove(in,in-n,oldbytes+n); + memcpy(in,q_overlapfree,newlen); +#ifdef DUAL_STACK + //printf(" -> '%s'\n", in); + if (need_ds_update) + ds_update(in+(oldbytes+n)); +#endif +} + +void macro_expansion(char *in,char *inbound,int need_ds_update); + +/* + * macro_expand(): expand identifier 'id', and depending on the status of 'id': + * - if 'id' is not a macro, do nothing and return 0 + * - if 'id' is an identifier to be protected from expansion, modify 'oldin' + * in-place to prepend an '@@' and return 0 + * - otherwise, concatenate the expansion of 'id' with the contents of 'in', + * place the result in 'oldin', and return 1 + * + * The resulting line's terminating zero will not exceed 'inbound' (an error is + * raised otherwise), and the dualstack pointer will be updated if + * 'need_ds_update' is non-zero. + * + * The relation between 'in' and 'oldin' should fit one of these scenarios: + * - in == oldin+strlen(id) && !strncmp(id,oldin,strlen(id)) + * - in == oldin, and 'id' must not be protected from expansion + */ +int macro_expand(char *id,int crc/* may equal -1 */,char *in,char *oldin,char *inbound,int need_ds_update) { + restart: { + SYM *sp = search(id, crc, &defsyms); +/* if ((long)sp==0x7c2040 && asm_flag) + bkpt();*/ + if (!sp) { +#ifdef MEXP_SUPPORTS_PCH + int n=pchsearch(id,PCHS_ADD); + if (n>0) + goto restart; +#endif + return 0; +#ifdef PC + } else if ((sp->used&PPSYM_UNDER_EXPANSION)) { +#else + } else if ((short)sp->used<0) { +#endif + expand_do("@@",0,oldin,inbound,need_ds_update); + return 0; + } else if (asm_flag && (sp->used&PPSYM_ASM_KEYWORD) && !(asm_xflag&&!asm_zflag)) { + // for the few ASM keywords (e.g. move, b, l, d7) we don't want to perform expansion, unless: + // - we are currently parsing an asm operand (asm_xflag!=0) + // - *and* we are in __c__ mode (asm_zflag==0) + return 0; + } else { + TABLE *tp; + if ((tp=(TABLE *)sp->tp)!=NULL) { + int d=0,nmac=(int)(char)sp->used,nargs=0,concat_mode; + int string=0,number=0,asm_st=0; +#ifdef DUAL_STACK + void *pop = ds_ensure(800+350); + char *args = ds_var(char *); + char *ps; +#else + char ps[800],args[350]; +#endif + char *argb=args,*argp=args; + char c,lastsym[MAX_ID_LEN+1],*psptr; + SYM *s=tp->head; + while (isspace((c=*in++))); + if (c!='(') return 0; + sp->used|=PPSYM_UNDER_EXPANSION; + while (1) { + c=*in++; + if (c=='(') d++; + else if (c==')') { if (--d<0) break; } + else if (c=='"') { + *argp++=c; + while ((c=*in++) && c!='"') { + if (argp>=&args[350-3]) uerrsys("macro arguments too long"); + *argp++=c; + if (c=='\\') // normally never followed by a 0, since otherwise would be a line continuation + *argp++=*in++; + } + // c is now '"' or 0 + } else if (c==',' && !d && (sp->storage_class!=sc_vamac || nargsvalue.s=argb; nargs++; argb=argp; + s=s->next; continue; + } else + uerrc("too many args to macro"); + } + if (argb!=argp || !isspace(c)) /* remove leading whitespace */ + *argp++=c; + if (argp>=&args[350]) uerrsys("macro arguments too long"); + } + if (tp->head) { + while (isspace(argp[-1])) /* remove trailing whitespace */ + argp--; + *argp=0; + if (!s) uerrc("too many args to macro"); + s->value.s=argb; + nargs++; /* if var, this argument might appear to be "" */ + } + if (nargsvalue.s; + psptr=ps; concat_mode=0; +#ifdef ASM + if (asm_flag && !(sp->used&PPSYM_DEFINED_IN_ASM) && !(asm_xflag&&!asm_zflag)) { + // unless we're already in __c__ mode, transform C defines to + // '(unsigned long)__c__(normal_value)' + // (note: we assimilate !asm_xflag to non-__c__ mode, because + // otherwise getsym caching causes problems) + // + // IMPORTANT: this code has a counterpart a few lines below, + // don't forget to keep it in sync + strcpy(psptr,"(unsigned long)__c__("); + psptr+=strlen(psptr); + } +#endif + while ((c=*argp++)) { + if (!isidch(c)) number=0; + if (c=='\\') { *psptr++=c; c=*argp++; if (!c) break; goto write; } + else if (c=='"') { string=~string; goto write; } + else if (c=='{') { if (asm_st<0) asm_st=100,asm_flag++; goto write; } + else if (c=='}') { if (asm_st>0) asm_st=0,asm_flag--; goto write; } + else if (c>='0' && c<='9' && !string) { number=1; goto write; } + else if (isbegidch(c) && !string && !number) { + int i=0; SYM *asp; char *str=lastsym; + while (isidch(c)) { + if (ivalue.s; + strcpy(psptr,str); +#ifdef NONSTD_MACRO_CONCAT + #ifdef DUAL_STACK + #error fixme + #endif + if (asp) macro_expansion(psptr,&ps[800],1); +#endif +#ifdef STD_MACRO_CONCAT + if (!concat_mode) { + char *p=argp; + while (isspace(*p)) p++; + if (!(*p=='#' && p[1]=='#')) { + #ifdef DUAL_STACK + ds_update(psptr+strlen(psptr)+1); + #endif + macro_expansion(psptr,&ps[800],1); + } + } +#endif + psptr+=strlen(psptr); + concat_mode=0; + } else if (c=='#' && !string) { + if (*argp!='#') { /* single # */ + int i=0; SYM *asp; char *str=lastsym; + char *argpsave=argp; + while (isspace(*argp)) argp++; + if (!isbegidch(c=*argp++)) +// uerrc("# : syntax"); + { c='#'; argp=argpsave; goto write; } + /* (because of immediate data in ASM macros) */ + while (isidch(c)) { + if (ivalue.s; + *psptr++='"'; + while ((c=*str++)) { + if (/*c=='\\' ||*/ c=='"') *psptr++='\\'; // ANSI specifies #x with x=\x7F should be "\x7F"... + *psptr++=c; + } + *psptr++='"'; + concat_mode=0; + } else { /* ## */ + argp++; + concat_mode=1; + while (isspace(psptr[-1])) psptr--; + } + } else if (!concat_mode || !isspace(c)) { + write: + concat_mode=0, *psptr++=c; + } + } + if (asm_st>0) asm_flag--; + if (string) uerrc("unbalanced quote"); +#ifdef ASM + if (asm_flag && !(sp->used&PPSYM_DEFINED_IN_ASM) && !(asm_xflag&&!asm_zflag)) { + *psptr++=')'; + } +#endif + *psptr=0; +#ifdef DUAL_STACK + ds_update(psptr+1); +#endif +#if defined(NONSTD_MACRO_CONCAT_V2) || defined(STD_MACRO_CONCAT) + macro_expansion(ps,&ps[800],1); +#endif + expand_do(ps,in-oldin,oldin,inbound,need_ds_update); +#ifdef DUAL_STACK + /* + * Note: this is slightly tricky, as expand_do() may overwrite part + * of 'ps', 'args', and stuff like that. But it will not do + * anything wrong, because [in,inbound[ was reserved by the caller, + * and we are not writing outside of it. + * + * In fact, the key to this working is that we can postpone any + * ds_pop()ing operation, as long as we do not ds_ensure() or + * ds_pop() anything else during that time interval, and as long as + * we back up the correct dualstack after the ds_pop(). This + * wouldn't be true if for example ds_pop() relied on reading some + * backup data from the dualstack and this backup data could happen + * to be in a previously ds_ensure()d zone. + */ + { + // in fact, this is the caller dualstack only if + // 'need_ds_update' made 'expand_do' update dualstack, + // so we recall it only in this case. + void *caller_dualstack = dualstack; + ds_pop(pop); + if (need_ds_update) + ds_update(caller_dualstack); + } +#endif + } else + sp->used|=PPSYM_UNDER_EXPANSION, expand_do(sp->value.s,in-oldin,oldin,inbound,need_ds_update); + sp->used&=~PPSYM_UNDER_EXPANSION; + return 1; + } + } +} +/* + * macro_expansion(): scan the string starting from 'in', expanding any + * identifiers. + * Modifies 'in' in-place, but only by calling macro_expand(), which in turn + * will only modify it through expand_do(). The dualstack size will be updated + * when 'need_ds_update' is non-zero. + */ +void macro_expansion(char *in,char *inbound,int need_ds_update) { + char c,*p=in; char newid[MAX_ID_LEN+1]; int string=0,number=0; + int asm_st=0; + while ((c=*p++)) { + if (((c>='0' && c<='9') || c=='@') && !string) number=1;/* so that @@id isn't expanded */ + else if (!string && isbegidch(c)) { + if (!number) { + int i=0; char *begin=p-1; + while (isidch(c)) { + if (i0) asm_st=0,asm_flag--; + } + } + if (asm_st>0) asm_flag--; + if (string) uerrc("unmatched quote in macro"); +} +int getid(int c) { + register int i; + int res; + if (c>=0) { + lastid[0] = c; + i = 1; + while (isidch(lastch)) { + if (i < MAX_ID_LEN) + lastid[i++] = lastch; + getch(); + } + lastid[i] = '\0'; + } +#ifdef PCH + if (!lastid[1] && lastid[0]=='_') + memcpy(lastid,curpch,MAX_ID_LEN+1); +#endif + lastcrc=crcN(lastid); + /*if (!strcmp(lastid,"OSContrastUp")) + bkpt();*/ + *--lptr=lastch; +// balance_parenthesis(lptr); + /*if (!strcmp(lastid,"put_sprite_24")) + printf("gjioh");*/ + if (!(res=macro_expand(lastid,lastcrc,lptr,lptr,linemax,0))) + lastst=id; + getch(); + return res; +} +#endif + +/* + * getsch - get a character in a quoted string. + * + * this routine handles all of the escape mechanisms for characters in strings + * and character constants. + * flag is 0, if a character constant is being scanned, + * flag is 1, if a string constant is being scanned + */ +int getsch(int flag) { + /* flag = "return an in-quote character?" */ + register int i, j; +/* + * if we scan a string constant, stop if '"' is seen + */ + if (flag && lastch == '"') { + getch(); + if (!preproc_stmt) { + if (getcache(sconst)) { + getch(); + return getsch(1); + } + } + return -1; + } + if (lastch != '\\') { + i = lastch; + getch(); + return i; + } + getch(); /* get an escaped character */ + if (isdigit(lastch)) { + i = 0; + for (j = 0; j < 3; ++j) { + if (isdigit(lastch) && lastch <= '7') + i = 8*i + radix36(lastch); + else + break; + getch(); + } +// /* signed characters lie in the range -128..127 => shit so disabled */ +// if ((i &= 0377) >= 128) i -= 256; + return i; + } + i = lastch; + getch(); + switch (i) { + case '\n': + return getsch(flag); + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'a': + return '\a'; + case 'v': + return '\v'; + case 'e': + return '\x1B'; + case 'x': + if ((i=radix36(lastch))<0 || i>=16) + error(ERR_SYNTAX); + getch(); + if ((j=radix36(lastch))>=0 && j<16) { + i = 16*i + j; + getch(); + } +// /* signed characters lie in the range -128..127 => shit so disabled */ +// if (i >= 128) i -= 256; + return i; + default: + uwarn("'%c' isn't an escaped character",i); + /* FALL THROUGH */ + case '\\': case '"': case '\'': + return i; + } +} + +int radix36(char c) { +/* + * This function makes assumptions about the character codes. + */ + if (isdigit(c)) + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return -1; +} +#ifndef AS /* otherwise in out68k_as.c */ +int hexatoi(char *s) { + int x=0; + if (strlen(s)>3) return -1; + while (*s) { + int y=radix36(*s++); + if (y<0) return -1; + x<<=4; x+=y; + } + return x; +} +#endif + +static void test_int(int hex_or_octal) { +/* test on long or unsigned constants */ + if (lastch == 'l' || lastch == 'L') { + getch(); + lastst = lconst; + return; + } + if (lastch == 'u' || lastch == 'U') { + /*if (!hex_or_octal) -> why was it so??? */ + getch(); + lastst = uconst; + if (lastch=='l' || lastch=='L') + getch(), lastst = ulconst; + if (short_option && ival > 65535) + lastst = ulconst; + return; + } + if ((long)ival<0) { /* since '-' is treated as unary minus, this only */ + lastst = ulconst; /* happens for values that are >0x7FFFFFFF */ + return; + } + + /* -32768 thus is stored as (unary minus)(32768l) */ +/* + * Although I think it is not correct, octal or hexadecimal + * constants in the range 0x8000 ... 0xffff are unsigned in 16-bit mode + */ + if (short_option) { + if (hex_or_octal && ival > 32767 && ival < 65536) { + lastst = uconst; + return; + } + if (ival > 32767) { + /* -32768 thus is stored as (unary minus)(32768l) */ + lastst = lconst; + return; + } + } +} + +/* + * getbase - get an integer in any base. + * b==0 : base 10 + * b!=0 : base 1<> b)) { + i = (i << b) + j; + getch(); + } else + break; + } + } + ival = i; +#ifndef NOFLOAT + rval = r; +#endif + lastst = iconst; +} + +#ifndef NOFLOAT +/* + * getfrac - get fraction part of a floating number. + */ +static void getfrac() { + double frmul; +#ifdef PC + frmul = 0.1; +#else + frmul = FFP_TENINV; +#endif + while (isdigit(lastch)) { +#ifdef PC + rval += frmul * radix36(lastch); +#else + rval = ffpadd(rval, ffpmul(frmul, ffputof(radix36(lastch)))); +#endif + getch(); +#ifdef PC + frmul *= 0.1; +#else + frmul = ffpmul(frmul, FFP_TENINV); +#endif + } +} + +/* + * getexp - get exponent part of floating number. + * + * this algorithm is primative but usefull. Floating exponents are limited to + * +/-255 but most hardware won't support more anyway. + */ +static void getexp() { + double expo, exmul; + expo = rval; + if (lastch == '-') { +#ifdef PC + exmul = 0.1; +#else + exmul = FFP_TENINV; +#endif + getch(); + } else +#ifdef PC + exmul = 10.0; +#else + exmul = FFP_TEN; +#endif + getbase(0); + lastst = rconst; + while (ival--) +#ifdef PC + expo *= exmul; +#else + expo = ffpmul(expo, exmul); +#endif + rval = expo; +} +#endif + +/* + * getnum - get a number from input. + * + * getnum handles all of the numeric input. it accepts decimal, octal, + * binary, hexadecimal, and floating point numbers. + */ +static void getnum() { + if (lastch == '0') { + getch(); + if (lastch == 'x' || lastch == 'X') { + getch(); + getbase(4); + test_int(1); + return; + } + if (lastch == 'b' || lastch == 'B') { + getch(); + getbase(1); + test_int(1); + return; + } + if (lastch != '.' && lastst != 'e' && lastst != 'E') { + getbase(3); + test_int(1); + return; + } + } + getbase(0); +#ifndef NOFLOAT + if (lastch == '.') { + /* rval already set */ + getch(); + getfrac(); /* add the fractional part */ + lastst = rconst; + } + if (lastch == 'e' || lastch == 'E') { + getch(); + getexp(); /* get the exponent */ + } +#endif + /* + * look for l and u qualifiers + */ + if (lastst == iconst) + test_int(0); + /* + * look for (but ignore) f and l qualifiers + */ + if (lastst == rconst) + if (lastch == 'f' || lastch == 'F' || lastch == 'l' || + lastch == 'L') + getch(); +} + +#ifdef PCH +#ifndef PC +#include "sUnpack.c" +#endif +char sUnpackBuf[500]; +int pchload(char *name,char *data,unsigned int flags,unsigned char *tabp, unsigned char *p0,TI_SHORT *extTab) { + struct sym *sp = 0; + int r=0; + char na[MAX_ID_LEN+1]; + char oldpch[MAX_ID_LEN+1]; +#ifdef MIN_TEMP_MEM + int old_min_temp_mem=min_temp_mem; + min_temp_mem=temp_mem; +#endif + (*tabp)++; +/* if (!strcmp(name,"compare_t")) + bkpt();*/ + if (*data || (flags&PCHID_MACRO)) { // is there a #define ? + int n=0; +#ifndef LOWMEM + global_flag++; +#endif + sp = (SYM *)xalloc((int)sizeof(SYM), _SYM+DODEFINE); +/* if ((long)sp==0x789388) + bkpt();*/ + sp->name = strsave(name); + sp->storage_class = sc_define; +#ifdef NO_CALLOC + sp->tp=NULL; +#endif + if (flags&PCHID_MACRO) { + TABLE *tp; + sp->tp=(TYP *)(tp=(TABLE *)xalloc((int)sizeof(TABLE), _TABLE+DODEFINE)); + #ifdef NO_CALLOC + tp->hash=0; + tp->head=tp->tail=NULL; + #endif + if (*data) { + while (*data) { + SYM *arg; + n++; + arg=(SYM *)xalloc((int)sizeof(SYM), _SYM+DODEFINE); + arg->name=data; + #ifdef NO_CALLOC + arg->tp=NULL; + #endif + insert(arg,(HTABLE *)tp); + while (*data++); + } + if (flags&PCHID_VAMAC) sp->storage_class = sc_vamac; + } + data++; + } + if (flags&PCHID_PACKED) + sp->value.s = strsave(sUnpack(data,sUnpackBuf,p0+w2us(((PCH_HEAD *)p0)->dic_off))); + else sp->value.s = data; + insert(sp,&defsyms); + sp->used=n; +#ifndef LOWMEM + global_flag--; +#endif + r=1; + } + while (*data++); + if (*data) { + TYP *head0=head,*tail0=tail; + char *declid0=declid; + int nparms0=nparms; + char *names0[MAX_PARAMS]; + int bit_offset0=bit_offset, bit_width0=bit_width, bit_next0=bit_next; + int decl1_level0=decl1_level,pch_init0=pch_init; + char lptr_save[LINE_LENGTH]; int l=strlen(data); // TODO: use DUAL_STACK for saving lptr + struct enode *old_init_node=init_node; + int old_middle_decl=middle_decl; + int lcrc=lastcrc; +#ifdef MEXP_SUPPORTS_PCH + char *old_lptr=lptr; + char *old_linemin=linemin,*old_linemax=linemax; +#endif + memcpy(names0,names,MAX_PARAMS*sizeof(char *)); + memcpy(na,lastid,MAX_ID_LEN+1); + memcpy(oldpch,curpch,MAX_ID_LEN+1); + memcpy(curpch,name,MAX_ID_LEN+1); +#ifdef MEXP_SUPPORTS_PCH + lptr=lptr_save+1; + linemin=lptr_save,linemax=lptr_save+LINE_LENGTH; +#else + memcpy(lptr_save,lptr-1,LINE_LENGTH); +#endif + pch_init=1; + lastch=' '; + head=tail=0; + init_node=0; + middle_decl=0; + decl1_level=0; +#ifndef MEXP_SUPPORTS_PCH +#ifdef OLD_MACRO + lptr=linein+MAX_MAC_LEN+1; +#else + lptr=linein+1; +#endif +#endif + sUnpack(data,lptr,p0+w2us(((PCH_HEAD *)p0)->dic_off)); + l=strlen(lptr); +/* memcpy(lptr,data,l);*/ + memcpy(lptr+l," alloca ",10); /* the spaces are the end are there because we don't */ + global_flag++; /* want to read a new line (otherwise bugs) */ + getsym(); + while (lastst != kw_alloca) { + dodecl(sc_global); + if (lastst != kw_alloca) + getsym(); + } + global_flag--; +#ifdef MEXP_SUPPORTS_PCH + lptr=old_lptr-1; /* so that it re-reads the last char */ + linemin=old_linemin,linemax=old_linemax; +#else +#ifdef OLD_MACRO + lptr=linein+MAX_MAC_LEN+1; +#else + lptr=linein+1; +#endif + memcpy(lptr,lptr_save,LINE_LENGTH); /* so that it re-reads the last char */ +#endif + getch(); + lastst = id; + memcpy(lastid,na,MAX_ID_LEN+1); + memcpy(curpch,oldpch,MAX_ID_LEN+1); + init_node=old_init_node; + middle_decl=old_middle_decl; + head=head0; tail=tail0; + pch_init=pch_init0; + declid=declid0; + nparms=nparms0; + bit_offset=bit_offset0; bit_width=bit_width0; bit_next=bit_next0; + decl1_level=decl1_level0; + lastcrc=lcrc; + memcpy(names,names0,MAX_PARAMS*sizeof(char *)); + } +#ifdef AS /* .ext management is enabled only in AS mode */ + while (*data++); + if (*data) { + unsigned char *ext=p0+w2us(extTab[*data-1]); + extscan(ext); /* load .ext files used by current ext */ + extload(ext); /* now write it :) */ + } +#endif +#ifndef MEXP_SUPPORTS_PCH + if (r) getid(-1); +#endif +#ifndef MEXP_SUPPORTS_PCH + (*tabp)--; +#endif +#ifdef MIN_TEMP_MEM + min_temp_mem=old_min_temp_mem; +#endif + return r; +} + +int pchsearch(char *id,int mode) { /* returns 0 if not PCH, 1 if PCH/def, -1 if PCH/init */ + int n=pchnum; + /*if (!strcmp(id,"LINK_ME")) + bkpt();*/ +/* if (!strcmp(id,"unpack")) + bkpt();*/ + while (n--) { + unsigned char *p0=pchdata[n],*tab=pchtab[n],*tabp,*p,c,*q; + TI_SHORT *extTab=(TI_SHORT *)(p0+w2us(pchhead[n]->ext_off)); + int z=PCH_HEAD_SIZE; + do { + p=p0+z; q=id; + while ((c=*p++) && c==*q++); + if (!c && !*q) { + int idnum=(p[4]<<8)+p[5]; + tabp=&tab[idnum&PCHID_MASK]; + if (*tabp) /* really quit, because it would be a mess */ + return 0; /* if we scanned other files for this ID ;) */ + if (mode>0) { /* mode==PCHS_ADD */ +#ifdef REQ_MGT + pchrequired[n]=1; +#endif + return pchload(id,p+6,idnum,tabp,p0,extTab)?1:-1; + } else /* mode==PCHS_UNLOAD */ + (*tabp)++; /* forbid the loading of this symbol */ + } + if (c) while (*p++); + if (c') { + getch(); + lastst = pointsto; + } else + lastst = minus; + break; + case '*': + getch(); + if (lastch == '=') { + getch(); + lastst = astimes; + } else + lastst = star; + break; + case '/': + getch(); + if (lastch == '=') { + getch(); + lastst = asdivide; + /*} else if (lastch == '*') { + getch(); + for (;;) { + if (lastch == '*') { + getch(); + if (lastch == '/') { + getch(); + goto restart; + } + } else getch(); + } + } else if (lastch == '/') { + getch(); + for (;;) { + if (lastch == '\n') { + getch(); + goto restart; + } else getch(); + }*/ + } else + lastst = divide; + break; + case '^': + getch(); + if (lastch == '=') { + getch(); + lastst = asuparrow; + } else + lastst = uparrow; + break; + case ';': + getch(); + lastst = semicolon; + break; + case ':': + getch(); + lastst = colon; + break; + case '=': + getch(); + if (lastch == '=') { + getch(); + lastst = eq; + } else + lastst = assign; + break; + case '>': + getch(); + if (lastch == '=') { + getch(); + lastst = geq; + } else if (lastch == '>') { + getch(); + if (lastch == '=') { + getch(); + lastst = asrshift; + } else + lastst = rshift; + } else + lastst = gt; + break; + case '<': + getch(); + if (lastch == '=') { + getch(); + lastst = leq; + } else if (lastch == '<') { + getch(); + if (lastch == '=') { + getch(); + lastst = aslshift; + } else + lastst = lshift; + } else + lastst = lt; + break; + case '\'': + getch(); + ival = getsch(0); /* get a string char */ + if (lastch != '\'') + error(ERR_SYNTAX); + else + getch(); + lastst = iconst; + break; + case '\"': + if (forbid!=sconst) { + getch_in_string=1; + getch(); + for (i = 0; ; ++i) { + if ((j = getsch(1)) IS_INVALID) + break; + if (i < MAX_STRLEN) + laststr[i] = j; + } + getch_in_string=0; + /* + * Attention: laststr may contain zeroes! + */ + if (i > MAX_STRLEN) { + i = MAX_STRLEN; + uwarn("string constant too long"); + } + lstrlen = i; + laststr[i] = 0; + } + lastst = sconst; + break; + case '!': + getch(); + if (lastch == '=') { + getch(); + lastst = neq; + } else + lastst = not; + break; + case '%': + getch(); + if (lastch == '=') { + getch(); + lastst = asmodop; + } else + lastst = modop; + break; + case '~': + getch(); + lastst = compl; + break; + case '.': + getch(); + if (isdigit(lastch)) { +#ifndef NOFLOAT + rval = 0; + getfrac(); +#endif + lastst = rconst; + if (lastch=='e' || lastch=='E') { + getch(); +#ifndef NOFLOAT + getexp(); +#endif + } + } else if (lastch=='.') { + getch(); + if (lastch!='.') error(ERR_SYNTAX); + getch(); + lastst = dots; + } else + lastst = dot; + break; + case ',': + getch(); + lastst = comma; + break; + case '&': + getch(); + if (lastch == '&') { + lastst = land; + getch(); + } else if (lastch == '=') { + lastst = asand; + getch(); + } else + lastst = and; + break; + case '|': + getch(); + if (lastch == '|') { + lastst = lor; + getch(); + } else if (lastch == '=') { + lastst = asor; + getch(); + } else + lastst = or; + break; + case '(': + getch(); +#ifdef ASM +#ifdef OLD_AMODE_INPUT + if (asm_xflag + && ((lastch=='p' && *lptr=='c') + || (lastch=='s' && *lptr=='p') + || (lastch=='a' && *lptr>='0' && *lptr<='7')) + && (lptr[1]==')' || lptr[1]==',')) + lastst = kw_offs_end; + else +#else + if (asm_xflag + && ((lastch=='p' && *lptr=='c') + || (lastch=='s' && *lptr=='p') + || (lastch=='a' && *lptr>='0' && *lptr<='7')) + && (lptr[1]==')' || lptr[1]==',')) + lastst_flag=1; + else lastst_flag=0; +#endif +#endif + lastst = openpa; + break; + case ')': + getch(); + lastst = closepa; + break; + case '[': + getch(); + lastst = openbr; + break; + case ']': + getch(); + lastst = closebr; + break; + case '{': + getch(); + lastst = begin; + break; + case '}': + getch(); + lastst = end; + break; + case '?': + getch(); + lastst = hook; + break; + case '#': + getch(); + // TODO: rewrite the following (disabled because not ANSI-compliant) + /*getsym(); + if (lastst==id) { + SYM *sp; + if (mac_sp!=&mac_stk[MAX_MAC_NUM] && + (sp = search(lastid, lastcrc, (HTABLE *)*mac_sp))) { + char c,*q=sp->value.s; char buf[MAX_STRLEN],*bp; int i; + lastst=sconst; + bp=buf; + *bp++='"'; + i=MAX_STRLEN-1-2; + do { + if (!(c=*q++)) break; + if (c=='"') { *bp++='\\'; *bp++='"'; } + else *bp++=c; + } while (i--); + *bp++='"'; + lptr-=bp-buf+1; + memcpy(lptr,buf,bp-buf); + getch(); + } else error(ERR_UNDEFINED); + } else if (lastst==lconst||lastst==iconst||lastst==uconst) { + char buf[MAX_STRLEN],*bp; + lastst=sconst; + bp=buf; + *bp++='"'; + sprintf(bp,"%ld",ival); + bp+=strlen(bp); + *bp++='"'; + lptr-=bp-buf+1; + memcpy(lptr,buf,bp-buf); + getch(); + } else error(ERR_IDEXPECT); + getsym();*/ +#ifdef ASM + if (asm_flag) { + lastst = sharp; + break; + } else { +#endif + error(ERR_ILLCHAR); + goto restart; /* get a real token */ +#ifdef ASM + } +#endif +/* if (lastst==iconst || lastst==lconst || lastst==uconst) { + lastst=sconst; + if (forbid!=lastst) sprintf(laststr,"%ld",ival); + else { + char b[20]; int n; + sprintf(b,"%ld",ival); + lptr-=1+(n=strlen(b)); + strncpy(lptr,b,n); + lptr[n]='"'; + } + } else error(ERR_INTEGER);*/ + break; +#ifdef ASM + case '\\': + if (asm_flag) { + if (forbid==(lastst=id)) return; + getch(); + if (getid((int)'\\')) goto restart; + } else { + getch(); + error(ERR_ILLCHAR); + goto restart; /* get a real token */ + } + break; +#endif + case '@': + getch(); + if (lastch=='@') { + getch(); + if (isbegidch(lastch)) { + if (forbid==(lastst=id)) return; + getrawid(); + break; + } + } + /* otherwise fall through */ + default: + getch(); + error(ERR_ILLCHAR); + goto restart; /* get a real token */ + } + if (lastst == id) { + searchkw(); +//#ifdef OLD_MACRO + if (lastst == kw_eval) { + struct enode *ep; + getsym(); + needpunc(openpa); + if (!expression(&ep)) error(ERR_EXPREXPECT); + if (lastst!=closepa) needpunc(closepa); + opt0(&ep); + if (ep->nodetype==en_icon) { + lastst=lconst; + ival=ep->v.i; +#ifndef NOFLOAT + } else if (ep->nodetype==en_fcon) { + lastst=rconst; + rval=ep->v.f; +#endif + } else error(ERR_CONSTEXPECT); + } +#ifdef ASM + else if (asm_flag && lastst == id) { + if (!lastid[2]) { + if (lastid[1]>='0' && lastid[1]<='7') { + lastreg=lastid[1]-'0'; // we don't care if we set lastreg even if + if (lastid[0]=='d') // lastst is an id + lastst=kw_dreg; // (for example 'z6' will set lastreg to 6) + else if (lastid[0]=='a') + lastst=kw_areg; + } else if (lastid[1]=='p' && lastid[0]=='s') + lastst=kw_areg,lastreg=7; + } + asm_searchkw(); + } +#endif +#if defined(PCH) && !defined(MEXP_SUPPORTS_PCH) + if (lastst==id && !(lastsp = search(lastid, lastcrc, &lsyms)) + && !(lastsp = search(lastid, lastcrc, &gsyms))) { +#if 0 + int n=pchnum; + while (n--) { + unsigned char *p0=pchdata[n],*tab=pchtab[n],*tabp,*p,c,*q; + TI_SHORT *extTab=(TI_SHORT *)(p0+w2s(pchhead[n]->ext_off)); + int z=PCH_HEAD_SIZE; + do { + p=p0+z; q=lastid; + while ((c=*p++) && c==*q++); + if (!c && !*q) { + tabp=&tab[(p[4]<<8)+p[5]]; + if (*tabp) /* really quit, because it would be a mess */ + goto pch_done; /* if we scanned other files for this ID ;) */ + if (pchload(p+6,tabp,p0,extTab)) goto restart; + else { + lastsp = gsearch(lastid, lastcrc); + goto pch_done; + } + } + if (c) while (*p++); + if (c0) goto restart; + else if (n<0) lastsp = gsearch(lastid, lastcrc); +#endif + } +#else + if (lastst==id && !(lastsp = search(lastid, lastcrc, &lsyms))) + lastsp = search(lastid, lastcrc, &gsyms); +#endif + } +/* if (global_flag) + if (lastst==id && !strcmp(lastid,"pos")) + bkpt();*/ +/* if (lineid==0x51) + bkpt();*/ +} + +int getcache(enum(e_sym) f) { + enum(e_sym) my_st=lastst; + int my_flag=lastst_flag; + int my_line=lineid,my_prev=prevlineid; + if (cached_sym!=-1) return (cached_sym==f); + cached_sym=-2; // tell getcache not to put anything into cache + forbid=f; + getsym(); + cached_sym=lastst; + cached_flag=lastst_flag; + cached_lineid=my_line; + lastst=my_st; + lastst_flag=my_flag; + lineid=my_line; + prevlineid=my_prev; + forbid=-1; + if (cached_sym==f) cached_sym=-1; + return (cached_sym==-1); +/* enum(e_sym) my_st=lastst,cached=cached_sym; + if ((int)cached_sym2 IS_VALID) return (cached_sym2==f); + cached_sym=-1; // prevent getsym from caching :) + forbid=f; + getsym(); + forbid=-1; + if ((int)cached IS_VALID) { + if ((int)cached_sym2 IS_VALID) fatal("CACHE"); + cached_sym2=lastst; + cached_sym=cached; + lastst=my_st; + if (cached_sym2==f) cached_sym2=-1; + return (cached_sym2==f); + } else { + cached_sym=lastst; + lastst=my_st; + if (cached_sym==f) cached_sym=-1; + return (cached_sym==f); + }*/ +} + +void needpunc(enum(e_sym) p) { + if (lastst == p) + getsym(); + else + uerr(ERR_PUNCT, + p==semicolon?';': + (p==begin?'{': + (p==end?'}': + (p==openpa?'(': + (p==closepa?')': + (p==hook?'?': + (p==comma?',': + (p==closebr?']':' ')))))))); +} + +extern unsigned char sizeof_flag; +extern unsigned char id_are_zero; +void do_compile() { + /* parser initialization */ + sizeof_flag=0; id_are_zero=0; + flags=flags_basegtc; +#ifdef SPEED_OPT + speed_opt_value = default_speed_opt_value; +#endif + /* lexical analyzer / preprocessor initialization */ + initsym(); + /* compilation itself */ + compile(); +} +#ifdef PCH +void closepch() { +#ifdef REQ_MGT + { + FILE *req_file=NULL; + int i,needs_req=0; + for (i=pchnum;i--;) + if (pchrequired[i] && strcmp(pchname[i],"stdhead")) + needs_req++; + if (needs_req) { + char buf[sizeof("[Req_v1]\n")+1]; + char temp[5000]; + *temp=0; + req_file=fopen(proj_file,"r"); + if (req_file) { + while (!feof(req_file)) { + fgets(buf,sizeof("[Req_v1]\n"),req_file); + strcat(temp,buf); + if (!strcmp(buf,"[Req_v1]\n")) { + needs_req=0; + break; + } + } + fclose(req_file); + } + req_file=fopen(proj_file,"w"); + if (!req_file) fatal("Could not open project file."); + fputs(temp,req_file); + if (needs_req) + fputs("[Req_v1]\n",req_file); + needs_req=1; + } +#endif + /* close PCH files */ + while (pchnum) { + pchnum--; +#ifdef REQ_MGT + if (pchrequired[pchnum] && needs_req) + fprintf(req_file,"%s\n",pchname[pchnum]); +#endif + fclose(pchfile[pchnum]); + } +#ifdef REQ_MGT + if (needs_req) + fclose(req_file); + } +#endif +} +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/gtdevcomm.c b/gtc/src/gtdevcomm.c new file mode 100644 index 0000000..286014f --- /dev/null +++ b/gtc/src/gtdevcomm.c @@ -0,0 +1,43 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) communication with the GT-Dev IDE + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "GtDevComm.h" + +extern int has_error; + +char *in_file CGLOB,*out_file CGLOB; +Msg_Callback_t msg_process CGLOB; +Progr_Callback_t progr_process CGLOB; +#include "identity.h" +void _gtdevmain(void); +int Compile(char *in,char *out,Msg_Callback_t _msg_process,Progr_Callback_t _progr_process) { + void *old_a5=bssdata; + int res; + bssdata=malloc(BSS_SIZE); + if (!bssdata) return; + memset(bssdata,0,BSS_SIZE); + in_file=in; out_file=out; + msg_process=_msg_process; + progr_process=_progr_process; + _gtdevmain(); + bssdata=identity(bssdata); + if (!bssdata) + return 2; + res=has_error; + free(bssdata); + bssdata=old_a5; + return res; +} +// vim:ts=4:sw=4 diff --git a/gtc/src/gtdevcomm.h b/gtc/src/gtdevcomm.h new file mode 100644 index 0000000..2a201fb --- /dev/null +++ b/gtc/src/gtdevcomm.h @@ -0,0 +1,44 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) communication with the GT-Dev IDE + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef __GTDEVCOMM_H +#define __GTDEVCOMM_H + +//#include "E:\Paul\89\Ti-GCC\Projects\GT-Dev\SecureCommDef.h" +#include "securecommdef.h" + +#define ET_FATAL -2 +#define ET_WARNING -1 +#define ET_ERROR 0 +#define ET_INTERNAL_WARNING 1 +#define ET_INTERNAL_FAILURE 2 +#define et_isinternal(x) ((x)>0) +#define et_iserror(x) !((x)&1) +#if __TIGCC_BETA__*100+__TIGCC_MINOR__>=94 +#define CALLBACK __ATTR_TIOS_CALLBACK__ +#else +#define CALLBACK +#endif +typedef void (CALLBACK*Msg_Callback_t)(char *message,int err_type,char *func,char *file,int line,int chr); +//typedef _Msg_Callback_t *Msg_Callback_t; +#define MAX_PROGRESS 65535 +typedef void (CALLBACK*Progr_Callback_t)(char *func,char *file,unsigned int fprogress); +//typedef _Progr_Callback_t *Progr_Callback_t; + +extern char *in_file,*out_file; +extern Msg_Callback_t msg_process; +extern Progr_Callback_t progr_process; +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/gtpack/gtpack.c b/gtc/src/gtpack/gtpack.c new file mode 100644 index 0000000..99530f8 --- /dev/null +++ b/gtc/src/gtpack/gtpack.c @@ -0,0 +1,2259 @@ +/****************************************************************************** +* +* A variant of ttpack designed to output XPak compressed data. +* +* ----------------------------------------------------------------------------- +* +* original project name: TIGCC Tools Suite +* file name: ttpack.c +* initial date: 14/08/2000 +* authors: albert@cs.tut.fi +* thomas.nussbaumer@gmx.net +* Paul Froissart +* description: packing program +* +* ----------------------------------------------------------------------------- +* +* based on code from Pasi 'Albert' Ojala, albert@cs.tut.fi +* +* heavily reduced to fit to the needs by thomas.nussbaumer@gmx.net +* +* modified to fit XPak's compression format +* +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +//#define ONCALC_PACKER_EMU +//#define EVEN_LZ // allow only LZ sequences with the same parity +//#define NEW_RANGE // LZhuf-like range coding +//#define X_STATS +#define NO_XVERBOSE +//#define ZRANGE +//#define ZRANGE_FAST + +#include "tt.h" // generic defines +#include "ttversion.h" // tigcc tools suite version info +#include "revtools.h" // used for id displaying +#include "ttunpack.h" // errorcodes definition +#include "packhead.h" // compressed header definition + +#define CVS_FILE_REVISION "$Revision: 1.4 $" + +#define FIXF_MACHMASK 0xff +#define FIXF_WRAP 256 +#define FIXF_DLZ 512 + + +#define F_VERBOSE (1<<0) +#define F_STATS (1<<1) +#define F_AUTO (1<<2) +#define F_NOOPT (1<<3) +#define F_AUTOEX (1<<4) +#define F_TEXTINPUT (1<<5) +#define F_TEXTOUTPUT (1<<6) +#define F_NORLE (1<<9) +#define F_ERROR (1<<15) + +#ifndef min +#define min(a,b) ((a 1..127 */ +#else +#define LRANGE 6144 /* packer() emulation */ +#endif +#ifdef NEW_RANGE +#undef LRANGE +#define LRANGE 4096 +#endif +#ifdef ZRANGE +#undef LRANGE +#define LRANGE 6144 +#endif +#define MAXLZLEN (2< 1..127 */ +#define DEFAULT_LZLEN LRANGE + + + +unsigned short *rle, *elr, *lzlen, *lzpos; +unsigned short *lzlen2, *lzpos2; +int *length, inlen; +unsigned char *indata, *mode, *newesc; +unsigned short *backSkip; + + +enum MODE { + LITERAL = 0, + LZ77 = 1, + RLE = 2, + DLZ = 3, + MMARK = 4 +}; + +int lzopt = 0; + + +int maxGamma = 7; +int reservedBytes = 2; +int escBits = 2; +int escMask = 0xc0; +int extraLZPosBits = 0; +int rleUsed = 31; + + +/* +//============================================================================= +// outputs usage information of this tool +//============================================================================= +void PrintUsage() { + fprintf(stderr, "Usage: ttpack [-] \n" \ + " -hti treat input as hex textinput\n" \ + " -hto generate hex textoutput\n" \ + " -fdelta use delta-lz77 -- shortens some files\n" \ + " e force escape bits\n" \ + " r restrict lz search range\n" \ + " n no RLE/LZ length optimization\n" \ + " s full statistics\n" \ + " v verbose\n" \ + " p force extralzposbits\n" \ + " m max len 5..7 (2*2^5..2*2^7)\n"); +} +*/ + +/* +//============================================================================= +// the packing code +//============================================================================= +int SavePack(int flags,int type, unsigned char *data, int size, char *target, + int start, int escape, unsigned char *rleValues, + int endAddr, int extraLZPosBits,int memStart, int memEnd) +{ + FILE *fp = NULL; + + int i; + + if (!data) return 10; + if (!target) fp = stdout; + + if ((type & FIXF_MACHMASK) == 0) { + // Save without decompressor + + if (fp || (fp = fopen(target, "wb"))) { + PackedHeader cth; + RLEEntries re; + + cth.origsize_lo = inlen & 0xff; + cth.origsize_hi = (inlen >> 8); + #ifndef COMPACT + cth.magic1 = MAGIC_CHAR1; + cth.magic2 = MAGIC_CHAR2; + cth.compsize_lo = (size + rleUsed + sizeof(PackedHeader)) & 0xff; + cth.compsize_hi = (size + rleUsed + sizeof(PackedHeader)) >> 8; + #else + #ifndef OLD_HDR + memcpy(cth.magic,"GTPk",4); + cth.compsize_lo = (size + rleUsed + sizeof(PackedHeader)) & 0xff; + cth.compsize_hi = (size + rleUsed + sizeof(PackedHeader)) >> 8; + #endif + #endif + cth.esc1 = (escape >> (8-escBits)); + //cth.notused3 + //cth.notused4 + cth.esc2 = escBits; + #if !defined(COMPACT) || defined(OLD_HDR) + cth.gamma1 = maxGamma + 1; + cth.gamma2 = (1 << maxGamma); + #endif + cth.extralz = extraLZPosBits; + //cth.notused1 = 0xff; + //cth.notused2 = 0xff; + cth.rleentries = rleUsed; + + for(i=0; i>= 1; + + if (!bitMask) { +#ifndef NO_XVERBOSE + printf("[%02x]\n",(int)(unsigned char)outBuffer[outPointer]); +#endif + bitMask = 0x80; + outPointer++; + } +} + + + +int lenValue[256]; + +//-------------------------------------------- +// why not initializing value lenValue[0] ???? +//-------------------------------------------- +//============================================================================= +// +//============================================================================= +#if K_GAMMA-1 +void InitValueLen() { + int i,h; + + for (i=1; i<256; i++) { + int count = 0; + + if (i<2) count = 0; /* 1 */ + else if (i<4) count = 1; /* 2-3 */ + else if (i<8) count = 2; /* 4-7 */ + else if (i<16) count = 3; /* 8-15 */ + else if (i<32) count = 4; /* 16-31 */ + else if (i<64) count = 5; /* 32-63 */ + else if (i<128) count = 6; /* 64-127 */ + else if (i<256) count = 7; /* 128-255 */ + +// lenValue[i] = (count>>1)+count+2; + switch (count) { + case 0: h=1; break; + case 1: if (i==2) h=1; else h=2; break; + case 2: h=4; break; + case 3: h=5; break; + case 4: h=6; break; + case 5: h=7; break; + case 6: h=8; break; + case 7: h=9; break; + } + lenValue[i]=h+count; + } +} +#else +void InitValueLen() { + int i; + + // could be heavily optimized, but isn't necessary + for (i=1; i<256; i++) { + int count = 0; + + if (i<2) count = 0; /* 1 */ + else if (i<4) count = 1; /* 2-3 */ + else if (i<8) count = 2; /* 4-7 */ + else if (i<16) count = 3; /* 8-15 */ + else if (i<32) count = 4; /* 16-31 */ + else if (i<64) count = 5; /* 32-63 */ + else if (i<128) count = 6; /* 64-127 */ + else if (i<256) count = 7; /* 128-255 */ + + lenValue[i] = 2*count; + /*if (count1) { + bits = (bits<<1) | (value & 1); /* is reversed compared to value */ + value >>= 1; + count++; + PutBit(1); + } + /*if (count same as value */ + bits >>= 1; + } +#endif +} + +#ifdef NEW_RANGE +unsigned char p_len[64] = { + 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +unsigned char p_code[64] = { + 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, + 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, + 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, + 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, + 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, + 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; +//============================================================================= +// +//============================================================================= +void PutRange(int c) { + int i; + + /* output upper 6 bits with encoding */ + i = c >> 6; + PutNBits((unsigned)p_code[i] >> (8-p_len[i]), p_len[i]); + + /* output lower 6 bits directly */ + PutNBits((c & 0x3f), 6); +} +#endif + +int gainedEscaped = 0; +int gainedRle = 0, gainedSRle = 0, gainedLRle = 0; +int gainedLz = 0, gainedRlecode = 0; +int gainedDLz = 0, timesDLz = 0; + +int timesEscaped = 0, timesNormal = 0; +int timesRle = 0, timesSRle = 0, timesLRle = 0; +int timesLz = 0; + +int lenStat[8][4]; + //0: + //1: + //2: SRLE + //3: RLE byte + //4: + +//============================================================================= +// +//============================================================================= +int OutputNormal(int *esc, unsigned char *data, int newesc) { + timesNormal++; + if ((data[0] & escMask) == *esc) { + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + PutBit(0); + PutBit(1); + PutBit(0); + + *esc = newesc; + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + PutNBits(data[0], 8-escBits); + + gainedEscaped += escBits + 3; + timesEscaped++; + return 1; + } + PutNBits(data[0], 8); + return 0; +} + + +//============================================================================= +// +//============================================================================= +void OutputEof(int *esc) { + /* EOF marker */ + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + PutValue(3); /* >2 */ + PutValue((2<>3)); + + gainedRlecode -= LenValue(32+(data>>3)) + 3; + + PutNBits(data, 3); + + lenStat[5][3]++; +} + + +unsigned char rleLen[256]; + + +//============================================================================= +// +//============================================================================= +void InitRleLen() { + int i; + + for (i=0; i<256; i++) rleLen[i] = LenValue(32 + 0) + 3; + for (i=1; i<32; i++) rleLen[rleValues[i]] = LenValue(i); +} + +#define LenRleByte(d) (rleLen[d]) + + +//============================================================================= +// +//============================================================================= +int LenRle(int len, int data) { + int out = 0; + + do { + if (len == 1) { + out += escBits + 3 + 8; + len = 0; + } + else if (len <= (1<>8)+1) + LenRleByte(data); + len -= tmp; + } + } while (len); + return out; +} + + +//============================================================================= +// +//============================================================================= +int OutputRle(int *esc, unsigned char *data, int rlelen) { + int len = rlelen, tmp; + + while (len) { + if (len >= 2 && len <= (1<= 3 || IsShortRleByte(*data))) { + /* Short RLE */ + if (len==2) lenStat[0][2]++; + else if (len<=4) lenStat[1][2]++; + else if (len<=8) lenStat[2][2]++; + else if (len<=16) lenStat[3][2]++; + else if (len<=32) lenStat[4][2]++; + else if (len<=64) lenStat[5][2]++; + else if (len<=128) lenStat[6][2]++; + else if (len<=256) lenStat[6][2]++; + + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + PutBit(0); + PutBit(1); + PutBit(1); + PutValue(len-1); + PutRleByte(*data); + + tmp = 8*len -escBits -3 -LenValue(len-1) -LenRleByte(*data); + gainedRle += tmp; + gainedSRle += tmp; + + timesRle++; + timesSRle++; + return 0; + } + if (len<3) { + while (len--) + OutputNormal(esc, data, *esc); + return 0; + } + + if (len <= maxrlelen) { + /* Run-length encoding */ + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + + PutBit(0); + PutBit(1); + PutBit(1); + + PutValue((1<>(8-maxGamma))); + + PutNBits((len-1), 8-maxGamma); + PutValue(((len-1)>>8) + 1); + PutRleByte(*data); + + tmp = 8*len -escBits -3 -maxGamma -8 -LenValue(((len-1)>>8)+1) + -LenRleByte(*data); + gainedRle += tmp; + gainedLRle += tmp; + + timesRle++; + timesLRle++; + return 0; + } + + /* Run-length encoding */ + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + + PutBit(0); + PutBit(1); + PutBit(1); + + PutValue((1<>(8-maxGamma))); + + PutNBits((maxrlelen-1) & 0xff, 8-maxGamma); + PutValue(((maxrlelen-1)>>8)+1); + PutRleByte(*data); + + tmp = 8*maxrlelen -escBits -3 -maxGamma -8 + -LenValue(((maxrlelen-1)>>8)+1) -LenRleByte(*data); + gainedRle += tmp; + gainedLRle += tmp; + timesRle++; + timesLRle++; + len -= maxrlelen; + data += maxrlelen; + } + return 0; +} + + +#ifdef ZRANGE +char zrlen[96]={ + 0, + 2,2,2,2, + 3,3,3,3, + 4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; +#define ZrLen(p) (zrlen[((p)-1)>>6]) +#endif + + +//============================================================================= +// +//============================================================================= +int LenLz(int lzlen, int lzpos) { +#ifdef EVEN_LZ + if (lzpos&1) return 100000; +#endif + if (lzlen==2) { +#if !defined(ZRANGE) || defined(ZRANGE_FAST) +#ifdef EVEN_LZ + if (lzpos <= 256) return escBits + 2 + 7; +#else + if (lzpos <= 256) return escBits + 2 + 8; +#endif + else return 100000; +#else + if (lzpos <= 64) return escBits + 2 + 7; + else if (lzpos <= 128) return escBits + 2 + 8; + else if (lzpos <= 256) return escBits + 2 + 9; + else return 100000; +#endif + } + +#ifdef ZRANGE + return escBits + 8 + ZrLen(lzpos) + LenValue(lzlen-1); +#else +#ifdef EVEN_LZ + return escBits + 7 + extraLZPosBits + +#else + return escBits + 8 + extraLZPosBits + +#endif + LenValue(((lzpos-1)>>(8+extraLZPosBits))+1) + + LenValue(lzlen-1); +#endif +} + +#ifdef X_STATS +#define XS_NUM (LRANGE/64+1) +int lzstats[16][XS_NUM]; +int lzstatlong[XS_NUM]; +#endif + +//============================================================================= +// +//============================================================================= +int OutputLz(int *esc, int lzlen, int lzpos, char *data, int curpos) { +#ifdef X_STATS + if (lzlen<=16) + lzstats[lzlen-1][(lzpos-1)>>6]++; + else + lzstatlong[(lzpos-1)>>6]++; +#endif + if (lzlen==2) lenStat[0][1]++; + else if (lzlen<=4) lenStat[1][1]++; + else if (lzlen<=8) lenStat[2][1]++; + else if (lzlen<=16) lenStat[3][1]++; + else if (lzlen<=32) lenStat[4][1]++; + else if (lzlen<=64) lenStat[5][1]++; + else if (lzlen<=128) lenStat[6][1]++; + else if (lzlen<=256) lenStat[7][1]++; + + if (lzlen >= 2 && lzlen <= maxlzlen) { + int tmp; + + PutNBits((*esc>>(8-escBits)), escBits); /* escBits>=0 */ + + tmp = ((lzpos-1)>>(8+extraLZPosBits))+2; + if (tmp==2) lenStat[0][0]++; + else if (tmp<=4) lenStat[1][0]++; + else if (tmp<=8) lenStat[2][0]++; + else if (tmp<=16) lenStat[3][0]++; + else if (tmp<=32) lenStat[4][0]++; + else if (tmp<=64) lenStat[5][0]++; + else if (tmp<=128) lenStat[6][0]++; + else if (tmp<=256) lenStat[6][0]++; + + if (lzlen==2) { + PutValue(lzlen-1); + PutBit(0); + if (lzpos > 256) fprintf(stderr,"Error at %d: lzpos too long (%d) for lzlen==2\n",curpos, lzpos); +#ifdef ZRANGE +#ifdef ZRANGE_FAST + PutNBits(((lzpos-1) & 0xff) ^ 0xff, 8); +#else + { + int x=lzpos-1; + switch (x>>6) { + case 0: PutNBits(x,7); break; // x=0b00****** => 0****** + case 1: PutNBits(x+64,8); break; // x=0b01****** => 10****** + case 2: PutNBits(x+256,9); break; // x=0b10****** => 110****** + case 3: PutNBits(x+256,9); break; // x=0b11****** => 111****** + } + } +#endif +#endif + } + else { +#ifdef ZRANGE + PutValue(lzlen-1); +/* PutNBits(0,ZrLen(lzpos)); + PutNBits(0,8);*/ + { + int x=~(lzpos-1),u=(x+64)>>8; + switch (ZrLen(lzpos)) { +/*u=0*/ case 0: PutNBits(x,8); break; +/*u=-1*/ case 2: PutNBits(0x1,2); PutNBits(x,8); break; +/*u=-2*/ case 3: PutNBits(0x0,2); PutNBits(x,8); PutNBits(0x0,1); break; +/*u=-4..-3*/ case 4: PutNBits(0x0,2); PutNBits(x,8); PutNBits(0x2+(u&1),2); break; +/*u=-6..-5*/ case 5: PutNBits(0x2,2); PutNBits(x,8); PutNBits(0x0+(u&1),3); break; +/*u=-12..-7*/ case 6: PutNBits(0x2,2); PutNBits(x,8); PutNBits(0x4+((u+(12&7))&7),4); break; +/*u=-24..-13*/ case 7: PutNBits(0x2,2); PutNBits(x,8); PutNBits(0x14+((u+(24&15))&15),5); break; + } + } +#else +#ifdef X_STATS + PutValue(lzlen-1); +// PutNBits(0,1+3); + PutNBits(0,3); +#else + PutValue(lzlen-1); +#ifndef NEW_RANGE + PutValue( ((lzpos-1) >> (8+extraLZPosBits)) +1); + PutNBits( ((lzpos-1) >> 8), extraLZPosBits); +#endif +#endif +#endif + } +// PutNBits(0xFF, 8); +#ifndef ZRANGE +#ifndef NEW_RANGE +#ifdef EVEN_LZ + PutNBits((((lzpos-1) & 0xff) ^ 0xff) >> 1, 7); + if (lzpos&1) fprintf(stderr, "Error: odd lzpos\n"); +#else + PutNBits(((lzpos-1) & 0xff) ^ 0xff, 8); +#endif +#else + PutRange(lzpos-1); +#endif +#endif + + gainedLz += 8*lzlen -LenLz(lzlen, lzpos); + timesLz++; + return 3; + } + fprintf(stderr, "Error: lzlen too short/long (%d)\n", lzlen); + return lzlen; +} + + + +/* Non-recursive version */ +/* NOTE! IMPORTANT! the "length" array length must be inlen+1 */ + +//============================================================================= +// +//============================================================================= +int OptimizeLength(int optimize) { + int i; + + length[inlen] = 0; /* one off the end, our 'target' */ + for (i=inlen-1; i>=0; i--) { + int r1 = 8 + length[i+1], r2, r3; + +/* if (i<=0x40b1 && !(i&((1<<0)-1))) + printf("");*/ + if (!lzlen[i] && !rle[i] && (!lzlen2 || !lzlen2[i])) { + length[i] = r1; + mode[i] = LITERAL; + continue; + } + + /* If rle>maxlzlen, skip to the start of the rle-maxlzlen.. */ + if (rle[i] > maxlzlen && elr[i] > 1) { + int z = elr[i]; + + i -= elr[i]; + + r2 = LenRle(rle[i], indata[i]) + length[i+ rle[i]]; + if (optimize) { + int ii, mini = rle[i], minv = r2; + + int bot = rle[i] - (1<=bot; ii--) { + int v = LenRle(ii, indata[i]) + length[i + ii]; + if (v < minv) { + minv = v; + mini = ii; + } + } + if (minv != r2) { + lzopt += r2 - minv; + rle[i] = mini; + r2 = minv; + } + } + length[i] = r2; + mode[i] = RLE; + + for (; z>=0; z--) { + length[i+z] = r2; + mode[i+z] = RLE; + } + continue; + } + r3 = r2 = r1 + 1000; /* r3 >= r2 > r1 */ + + if (rle[i]) { + r2 = LenRle(rle[i], indata[i]) + length[i+ rle[i]]; + + if (optimize) { + int ii, mini = rle[i], minv = r2; + + /* Check only the original length and all shorter + lengths that are power of two. + + Does not really miss many 'minimums' this way, + at least not globally.. + + Makes the assumption that the Elias Gamma Code is + used, i.e. values of the form 2^n are 'optimal' */ + ii = 2; + while (rle[i] > ii) { + int v = LenRle(ii, indata[i]) + length[i + ii]; + if (v < minv) { + minv = v; + mini = ii; + } + ii <<= 1; + } + if (minv != r2) { + lzopt += r2 - minv; + rle[i] = mini; + r2 = minv; + } + } + } + if (lzlen[i]) { + r3 = LenLz(lzlen[i], lzpos[i]) + length[i + lzlen[i]]; + + if (optimize && lzlen[i]>2) { + int ii, mini = lzlen[i], minv = r3; + int topLen = LenLz(lzlen[i], lzpos[i]) + - LenValue(lzlen[i]-1); + + /* Check only the original length and all shorter + lengths that are power of two. + + Does not really miss many 'minimums' this way, + at least not globally.. + + Makes the assumption that the Elias Gamma Code is + used, i.e. values of the form 2^n are 'optimal' */ + ii = 4; + while (lzlen[i] > ii) { + int v = topLen + LenValue(ii-1) + length[i + ii]; + if (v < minv) { + minv = v; + mini = ii; + } + ii <<= 1; + } + /* + Note: + 2-byte optimization checks are no longer done + with the rest, because the equation gives too long + code lengths for 2-byte matches if extraLzPosBits>0. + */ + /* Two-byte rescan/check */ + if (backSkip[i] && backSkip[i] <= 256) { +#ifdef EVEN_LZ + if (backSkip[i]&1) { + int j=backSkip[i]; + while (j && (j&1)) + j=backSkip[j]; + if (j && j<=256) { + int v = LenLz(2, j) + length[i + 2]; + + if (v < minv) { + minv = v; + mini = 2; + lzlen[i] = mini; + r3 = minv; + lzpos[i] = j; + } + } + } else { +#endif + /* There are previous occurrances (near enough) */ + int v = LenLz(2, (int)backSkip[i]) + length[i + 2]; + + if (v < minv) { + minv = v; + mini = 2; + lzlen[i] = mini; + r3 = minv; + lzpos[i] = (int)backSkip[i]; + } +#ifdef EVEN_LZ + } +#endif + } + if (minv != r3 && minv < r2) { + lzopt += r3 - minv; + lzlen[i] = mini; + r3 = minv; + } + } + } + + if (r2 <= r1) { + if (r2 <= r3) { + length[i] = r2; + mode[i] = RLE; + } + else { + length[i] = r3; + mode[i] = LZ77; + } + } + else { + if (r3 <= r1) { + length[i] = r3; + mode[i] = LZ77; + } + else { + length[i] = r1; + mode[i] = LITERAL; + } + } + if (lzlen2 && lzlen2[i] > 3) { + r3 = escBits + 2*maxGamma + 16 + LenValue(lzlen2[i]-1) + length[i + lzlen2[i]]; + //r3 = LenDLz(lzlen2[i], lzpos2[i]) + length[i + lzlen2[i]]; + if (r3 < length[i]) { + length[i] = r3; + mode[i] = DLZ; + } + } + } + return length[0]; +} + + +/* + The algorithm in the OptimizeEscape() works as follows: + 1) Only unpacked bytes are processed, they are marked + with MMARK. We proceed from the end to the beginning. + Variable A (old/new length) is updated. + 2) At each unpacked byte, one and only one possible + escape matches. A new escape code must be selected + for this case. The optimal selection is the one which + provides the shortest number of escapes to the end + of the file, + i.e. A[esc] = 1+min(A[0], A[1], .. A[states-1]). + For other states A[esc] = A[esc]; + If we change escape in this byte, the new escape is + the one with the smallest value in A. + 3) The starting escape is selected from the possibilities + and mode 0 is restored to all mode 3 locations. + + */ + +//============================================================================= +// +//============================================================================= +int OptimizeEscape(int *startEscape, int *nonNormal) { + int i, /*j,*/ states = (1<256) { + fprintf(stderr, "Escape optimize: only 256 states (%d)!\n",states); + return 0; + } + + /* Mark those bytes that are actually outputted */ + for (i=0; i=0; i--) { + /* Using a table to skip non-normal bytes does not help.. */ + if (mode[i] == MMARK) { + int k = (indata[i] >> esc8); + + /* Change the tag values back to normal */ + mode[i] = LITERAL; + + /* + k are the matching bytes, + minv is the minimum value, + minp is the minimum index + */ + + newesc[i] = (minp << esc8); + a[k] = minv + 1; + b[k] = b[minp] + 1; + if (k==minp) { + /* Minimum changed -> need to find a new minimum */ + /* a[k] may still be the minimum */ + minv++; + for (k=states-1; k>=0; k--) { + if (a[k] < minv) { + minv = a[k]; + minp = k; + /* + There may be others, but the first one that + is smaller than the old minimum is equal to + any other new minimum. + */ + break; + } + } + } + } + } + + /* Select the best value for the initial escape */ + if (startEscape) { + i = inlen; /* make it big enough */ + for (j=states-1; j>=0; j--) { + if (a[j] <= i) { + *startEscape = (j << esc8); + i = a[j]; + } + } + } + if (nonNormal) + *nonNormal = other; + return b[startEscape ? (*startEscape>>esc8) : 0]; +#else + { + /* this fairly simple (but efficient) algo comes from GTPk */ + char esc_used[256]; + int esc_rem=states-1; + int lastesc=-1,escaped=0; + int k; + memset(esc_used,0,256); + for (i=0; i> esc8); + + mode[i] = LITERAL; + + if (!esc_used[k] && !esc_rem--) { + memset(esc_used,0,256); + esc_rem=states-1; + escaped++; + if (lastesc>=0) newesc[lastesc] = (k << esc8); + else if (startEscape) *startEscape = (k << esc8); + lastesc=i; + } else { + esc_used[k]=1; + } + } + } + for (k=0;;k++) { + if (!esc_used[k]) { + if (lastesc>=0) newesc[lastesc] = (k << esc8); + else if (startEscape) *startEscape = (k << esc8); + break; + } + } + newesc[0] = *startEscape; + if (nonNormal) + *nonNormal = other; + return escaped; + } +#endif +} + + +//============================================================================= +// Initialize the RLE byte code table according to all RLE's found so far O(n) +//============================================================================= +void InitRle(int flags) { + int p, mr, mv, i; + + for (i=1; i<32; i++) { + mr = -1; + mv = 0; + + for (p=0; p<256; p++) { + if (rleHist[p] > mv) { + mv = rleHist[p]; + mr = p; + } + } + if (mr>=0) { + rleValues[i] = mr; + rleHist[mr] = -1; + } else + break; + } + InitRleLen(); +} + + +//============================================================================= +// Initialize the RLE byte code table according to RLE's actually used O(n) +//============================================================================= +void OptimizeRle(int flags) { + int p, mr, mv, i; + + if ((flags & F_NORLE)) { + rleUsed = 0; + return; + } + if (flags & F_STATS) fprintf(stderr, "RLE Byte Code Re-Tune, RLE Ranks:\n"); + + for (p=0; p<256; p++) rleHist[p] = 0; + + for (p=0; p mv) { + mv = rleHist[p]; + mr = p; + } + } + if (mr>=0) { + rleValues[i] = mr; + if (flags & F_STATS) { + fprintf(stderr, " %2d.0x%02x %-3d ", i, mr, mv); + if (!((i - 1) % 6)) fprintf(stderr, "\n"); + } + rleHist[mr] = -1; + } + else { + break; + } + } + rleUsed = i-1; + if (rleUsed) + for (;i<32;i++) + rleValues[i]=rleValues[i-1]; + + if (flags & F_STATS) + if (((i - 1) % 6)!=1) fprintf(stderr, "\n"); + InitRleLen(); +} + + +int outlen; + +//============================================================================= +// +//============================================================================= +int PackLz77(int lzsz, int flags, int *startEscape,int endAddr, int memEnd, int type) +{ + int i, j, p, headerSize; + int escape; + unsigned char *hashValue; + unsigned char *a; + int k; + + unsigned short *lastPair; + + int rescan = 0; + +#ifndef NO_XVERBOSE + int vescape; +#endif + + + + if (lzsz < 0 || lzsz > lrange) { + fprintf(stderr, "LZ range must be from 0 to %d (was %d). Set to %d.\n", + lrange, lzsz, lrange); + lzsz = lrange; + } + if (lzsz > 65535) { + fprintf(stderr, + "LZ range must be from 0 to 65535 (was %d). Set to 65535.\n", + lzsz); + lzsz = 65535; + } + if (!lzsz) fprintf(stderr, "Warning: zero LZ range. Only RLE packing used.\n"); + + InitRleLen(); + length = (int *)calloc(sizeof(int), inlen + 1); + mode = (unsigned char *)calloc(sizeof(unsigned char), inlen); + rle = (unsigned short *)calloc(sizeof(unsigned short), inlen); + elr = (unsigned short *)calloc(sizeof(unsigned short), inlen); + lzlen = (unsigned short *)calloc(sizeof(unsigned short), inlen); + lzpos = (unsigned short *)calloc(sizeof(unsigned short), inlen); + if ((type & FIXF_DLZ)) { + lzlen2 = (unsigned short *)calloc(sizeof(unsigned short), inlen); + lzpos2 = (unsigned short *)calloc(sizeof(unsigned short), inlen); + } + else { + lzlen2 = lzpos2 = NULL; + } + newesc = (unsigned char *)calloc(sizeof(unsigned char), inlen); + backSkip = (unsigned short *)calloc(sizeof(unsigned short), inlen); + hashValue = (unsigned char *)malloc(inlen); + lastPair = (unsigned short *)calloc(sizeof(unsigned short), 256*256); + + /* error checking */ + if (!length || !mode || !rle || !elr || !lzlen || !lzpos || !newesc || + !lastPair || !backSkip + || ((type & FIXF_DLZ) && (!lzlen2 || !lzpos2)) + || !hashValue) + { + fprintf(stderr, "Memory allocation failed!\n"); + goto errorexit; + } + + i = 0; + j = 0; + a = indata + inlen; + for (p=inlen-1; p>=0; p--) { + k = j; + j = i; + i = *--a; /* Only one read per position */ + hashValue[p] = i*3 + j*5 + k*7; /* 7.95 % */ + } + + /* Detect all RLE and LZ77 jump possibilities */ + for (p=0; p=2) { + rleHist[indata[p]]++; + + for (i=rlelen-1; i>=0; i--) { + rle[p+i] = rlelen-i; + elr[p+i] = i; /* For RLE backward skipping */ + } + + } + } + + /* check LZ77 code */ + if (p+rle[p]+1=0 && i>=bot) { + /* Got a 2-byte match at least */ + maxval = 2; + maxpos = p-i; + + /* + A..AB rlep # of A's, B is something else.. + + Search for bytes that are in p + (rlep-1), i.e. + the last rle byte ('A') and the non-matching one + ('B'). When found, check if the rle in the compare + position (i) is long enough (i.e. the same number + of A's at p and i-rlep+1). + + There are dramatically less matches for AB than for + AA, so we get a huge speedup with this approach. + We are still guaranteed to find the most recent + longest match there is. + */ + + i = (int)lastPair[(indata[p+(rlep-1)]<<8) | indata[p+rlep]] -1; + while (i>=bot /* && i>=rlep-1 */) { /* bot>=rlep-1, i>=bot ==> i>=rlep-1 */ + + /* Equal number of A's ? */ + if (!(rlep-1) || rle[i-(rlep-1)]==rlep) { /* 'head' matches */ + /* rlep==1 ==> (rlep-1)==0 */ + /* ivanova.run: 443517 rlep==1, + 709846 rle[i+1-rlep]==rlep */ + + /* + Check the hash values corresponding to the last + two bytes of the currently longest match and + the first new matching(?) byte. If the hash + values don't match, don't bother to check the + data itself. + */ + if ( + hashValue[i+maxval-rlep-1] == hashCompare + ) { + unsigned char *a = indata + i+2; /* match */ + unsigned char *b = indata + p+rlep-1+2;/* curpos */ + int topindex = inlen-(p+rlep-1); + + /* the 2 first bytes ARE the same.. */ + j = 2; + while (j < topindex && *a++==*b++) + j++; + + if (j + rlep-1 > maxval) { + int tmplen = j+rlep-1, tmppos = p-i+rlep-1; + + if (tmplen > maxlzlen) + tmplen = maxlzlen; + + /* Accept only versions that really are shorter */ + if (tmplen*8 - LenLz(tmplen, tmppos) > + maxval*8 - LenLz(maxval, maxpos)) { + maxval = tmplen; + maxpos = tmppos; + hashCompare = hashValue[p+maxval-2]; + } + if (maxval == maxlzlen) + break; + } + } + } + if (!backSkip[i]) + break; /* No previous occurrances (near enough) */ + i -= (int)backSkip[i]; + } + + /* + If there is 'A' in the previous position also, + RLE-like LZ77 is possible, although rarely + shorter than real RLE. + */ + if (p && rle[p-1] > maxval) { + maxval = rle[p-1] - 1; + maxpos = 1; + } + /* + Last, try to find as long as possible match + for the RLE part only. + */ + if (maxval < maxlzlen && rlep > maxval) { + bot = p - lzsz; + if (bot < 0) + bot = 0; + + /* Note: indata[p] == indata[p+1] */ + i = (int)lastPair[indata[p]*257] -1; + while (/* i>= rlep-2 &&*/ i>=bot) { + if (elr[i] + 2 > maxval) { + maxval = min(elr[i] + 2, rlep); + maxpos = p - i + (maxval-2); + if(maxval == rlep) + break; /* Got enough */ + } + i -= elr[i]; + if (!backSkip[i]) + break; /* No previous occurrances (near enough) */ + i -= (int)backSkip[i]; + } + } + if (p+maxval > inlen) { + fprintf(stderr,"Error @ %d, lzlen %d, pos %d - exceeds inlen\n",p, maxval, maxpos); + maxval = inlen - p; + } + if (maxpos<=256 || maxval > 2) { + if (maxpos < 0) fprintf(stderr, "Error @ %d, lzlen %d, pos %d\n",p, maxval, maxpos); + lzlen[p] = (maxval=0 && i>=bot) { + maxval = 2; + maxpos = p-i; + + /* + A..AB rlep # of A's, B is something else.. + + Search for bytes that are in p + (rlep-1), i.e. + the last rle byte ('A') and the non-matching one + ('B'). When found, check if the rle in the compare + position (i) is long enough (i.e. the same number + of A's at p and i-rlep+1). + + There are dramatically less matches for AB than for + AA, so we get a huge speedup with this approach. + We are still guaranteed to find the most recent + longest match there is. + */ + + i = (int)lastPair[(((indata[p+(rlep-1)] + rot) & 0xff)<<8) | + ((indata[p+rlep] + rot) & 0xff)] -1; + while (i>=bot /* && i>=rlep-1 */) { /* bot>=rlep-1, i>=bot ==> i>=rlep-1 */ + + /* Equal number of A's ? */ + if (!(rlep-1) || rle[i-(rlep-1)]==rlep) { /* 'head' matches */ + /* rlep==1 ==> (rlep-1)==0 */ + /* ivanova.run: 443517 rlep==1, + 709846 rle[i+1-rlep]==rlep */ + + /* + Check the hash values corresponding to the last + two bytes of the currently longest match and + the first new matching(?) byte. If the hash + values don't match, don't bother to check the + data itself. + */ + if (indata[i+maxval-rlep+1] == valueCompare) { + unsigned char *a = indata + i+2; /* match */ + unsigned char *b = indata + p+rlep-1+2;/* curpos */ + int topindex = inlen-(p+rlep-1); + + /* the 2 first bytes ARE the same.. */ + j = 2; + while (j < topindex && *a++==((*b++ + rot) & 0xff)) + j++; + + if (j + rlep-1 > maxval) { + int tmplen = j+rlep-1, tmppos = p-i+rlep-1; + + if (tmplen > maxlzlen) + tmplen = maxlzlen; + + /* Accept only versions that really are shorter */ + if (tmplen*8 - LenLz(tmplen, tmppos) > + maxval*8 - LenLz(maxval, maxpos)) { + maxval = tmplen; + maxpos = tmppos; + + valueCompare = (indata[p+maxval] + rot) & 0xff; + } + if (maxval == maxlzlen) + break; + } + } + } + if (!backSkip[i]) + break; /* No previous occurrances (near enough) */ + i -= (int)backSkip[i]; + } + + if (p+maxval > inlen) { + fprintf(stderr,"Error @ %d, lzlen %d, pos %d - exceeds inlen\n",p, maxval, maxpos); + maxval = inlen - p; + } + if (maxval > 3 && maxpos <= 256 && + (maxval > lzlen2[p] || + (maxval == lzlen2[p] && maxpos < lzpos2[p]))) { + if (maxpos < 0) + fprintf(stderr, "Error @ %d, lzlen %d, pos %d\n",p, maxval, maxpos); + lzlen2[p] = (maxval p || ptr > 0xffff) + ptr = 0; + + backSkip[p] = ptr; + lastPair[index] = p+1; + } + } + if ((flags & F_NORLE)) { + for (p=1; p lzlen[p]) { + lzlen[p] = (rle[p]>escBits) & 0xff; + + /* Find the optimum path for selected escape bits (no optimize) */ + OptimizeLength(0); + + /* Optimize the escape selections for this path & escBits */ + escaped = OptimizeEscape(&escape, &other); + + /* Compare value: bits lost for escaping -- bits lost for prefix */ + c = (escBits+3)*escaped + other*escBits; + if (flags & F_STATS) { + fprintf(stderr, " %d:%d", escBits, c); + fflush(stderr); /* for SAS/C */ + } + if (c < mv) { + mb = escBits; + mv = c; + } else { + /* minimum found */ + break; + } + if (escBits==4 && (flags & F_STATS)) fprintf(stderr, "\n"); + } + if (mb==1) { /* Minimum was 1, check 0 */ + int escaped; + + escBits = 0; + escMask = 0; + + /* Find the optimum path for selected escape bits (no optimize) */ + OptimizeLength(0); + /* Optimize the escape selections for this path & escBits */ + escaped = OptimizeEscape(&escape, NULL); + + if ((flags & F_STATS)) { + fprintf(stderr, " %d:%d", escBits, 3*escaped); + fflush(stderr); /* for SAS/C */ + } + if (3*escaped < mv) { + mb = 0; + /* mv = 3*escaped; */ + } + } + if ((flags & F_STATS)) fprintf(stderr, "\n"); + + if (flags & F_VERBOSE) fprintf(stderr, "Selected %d-bit escapes\n", mb); + escBits = mb; + escMask = (0xff00>>escBits) & 0xff; + } + + + if (!(flags & F_NOOPT)) { + if (flags & F_VERBOSE) { + fprintf(stderr, "Optimizing LZ77 and RLE lengths..."); + fflush(stderr); + } + } + + /* Find the optimum path (optimize) */ + OptimizeLength((flags & F_NOOPT)?0:1); + if (flags & F_STATS) { + if (!(flags & F_NOOPT)) fprintf(stderr, " gained %d units.\n", lzopt/8); + } + else { + //fprintf(stderr, "\n"); + } + + if (1 || (flags & F_AUTOEX)) { + long lzstat[5] = {0,0,0,0,0}, i, cur = 0, old = extraLZPosBits; + + if (flags & F_VERBOSE) { + fprintf(stderr, "Selecting LZPOS LO length.. "); + fflush(stderr); + } + + for (p=0; p> 8)+1 > (1< (1< (1<<(maxGamma-1))) { + if (rle[p] <= (1< 10) { + if (flags & F_VERBOSE) fprintf(stderr,"Note: Using option -m%d you may get better results.\n",maxGamma+1); + } + if (maxGamma > 5 && stat[0] + stat[1] + stat[3] < 4) { + if (flags & F_VERBOSE) fprintf(stderr,"Note: Using option -m%d you may get better results.\n",maxGamma-1); + } + } + + /* Optimize the escape selections */ + OptimizeEscape(&escape, NULL); + if (startEscape) *startEscape = escape; + OptimizeRle(flags); /* Retune the RLE selections */ + +#ifdef NO_XVERBOSE + if (flags & F_VERBOSE) { + int oldEscape = escape; + if (flags & F_VERBOSE) printf("normal RLE LZLEN LZPOS(absolute)\n\n"); + + for (p=0; p"); + j += lzlen2[p]; + } else + printf(" "); + if (lzpos2) { + if (flags & F_VERBOSE) printf(" %04x*%03d*+%02x", lzpos2[p], lzlen2[p],(indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + if (flags & F_VERBOSE) printf(" 001 %03d %03d %04x(%04x) %02x %s\n", + rle[p],lzlen[p],lzpos[p],p-lzpos[p],indata[p], + (mode[p] & MMARK)?"#":" "); + break; + case MMARK | LITERAL: + case LITERAL: + if (flags & F_VERBOSE) { + if (j==p) printf(">"); + else printf(" "); + + if (lzpos2) { + printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p], + (indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + } + if (j==p) { + if (flags & F_VERBOSE) { + printf("*001* %03d %03d %04x(%04x) %02x %s %02x", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" ", newesc[p]); + } + if ((indata[p] & escMask) == escape) { + escape = newesc[p]; + if (flags & F_VERBOSE) printf(""); + } + if (flags & F_VERBOSE) printf("\n"); + j += 1; + } else { + if (flags & F_VERBOSE) printf("*001* %03d %03d %04x(%04x) %02x %s %02x\n", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" ", newesc[p]); + } + break; + case MMARK | LZ77: + case LZ77: + if (j==p) { + if (flags & F_VERBOSE) printf(">"); + j += lzlen[p]; + } else + if (flags & F_VERBOSE) printf(" "); + if (lzpos2) { + if (flags & F_VERBOSE) printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p], + (indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + if (flags & F_VERBOSE) printf(" 001 %03d *%03d* %04x(%04x) %02x %s\n", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" "); + break; + case MMARK | RLE: + case RLE: + if (j==p) { + if (flags & F_VERBOSE) printf(">"); + j += rle[p]; + } else + if (flags & F_VERBOSE) printf(" "); + if (lzpos2) { + if (flags & F_VERBOSE) printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p], + (indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + if (flags & F_VERBOSE) printf(" 001 *%03d* %03d %04x(%04x) %02x %s\n", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" "); + break; + default: + j++; + break; + } + mode[p] &= ~MMARK; + } + escape = oldEscape; + } +#endif + +#ifndef NO_XVERBOSE + if (flags & F_VERBOSE) { + for (p=0; p"); + j += lzlen2[p]; + } else + printf(" "); + if (lzpos2) { + if (flags & F_VERBOSE) printf(" %04x*%03d*+%02x", lzpos2[p], lzlen2[p],(indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + if (flags & F_VERBOSE) printf(" 001 %03d %03d %04x(%04x) %02x %s\n", + rle[p],lzlen[p],lzpos[p],p-lzpos[p],indata[p], + (mode[p] & MMARK)?"#":" "); + break; + case MMARK | LITERAL: + case LITERAL: + if (flags & F_VERBOSE) { + if (j==p) printf(">"); + else printf(" "); + + if (lzpos2) { + printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p], + (indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + } + if (j==p) { + if (flags & F_VERBOSE) { + printf("*001* %03d %03d %04x(%04x) %02x %s %02x", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" ", newesc[p]); + } + if ((indata[p] & escMask) == vescape) { + vescape = newesc[p]; + if (flags & F_VERBOSE) printf(""); + } + if (flags & F_VERBOSE) printf("\n"); + j += 1; + } else { + if (flags & F_VERBOSE) printf("*001* %03d %03d %04x(%04x) %02x %s %02x\n", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" ", newesc[p]); + } + break; + case MMARK | LZ77: + case LZ77: + if (j==p) { + if (flags & F_VERBOSE) printf(">"); + j += lzlen[p]; + } else + if (flags & F_VERBOSE) printf(" "); + if (lzpos2) { + if (flags & F_VERBOSE) printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p], + (indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + if (flags & F_VERBOSE) printf(" 001 %03d *%03d* %04x(%04x) %02x %s\n", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" "); + break; + case MMARK | RLE: + case RLE: + if (j==p) { + if (flags & F_VERBOSE) printf(">"); + j += rle[p]; + } else + if (flags & F_VERBOSE) printf(" "); + if (lzpos2) { + if (flags & F_VERBOSE) printf(" %04x %03d +%02x", lzpos2[p], lzlen2[p], + (indata[p] - indata[p-lzpos2[p]]) & 0xff); + } + if (flags & F_VERBOSE) printf(" 001 *%03d* %03d %04x(%04x) %02x %s\n", + rle[p], lzlen[p], lzpos[p], p-lzpos[p], indata[p], + (mode[p] & MMARK)?"#":" "); + break; + default: + j++; + break; + } + mode[p] &= ~MMARK; + } +#endif + switch (mode[p]) { + case LITERAL: /* normal */ + length[p] = outPointer; + + OutputNormal(&escape, indata+p, newesc[p]); + p++; + break; + + case DLZ: + for (i=0; i>(8-escBits)), escBits); + PutValue(lzlen2[p]-1); + PutValue((2< 2 && lzlen[p] > rle[p]) { + int bot = p - lzpos[p] + 1, i; + unsigned short rlep = rle[p]; + + if (!rlep) + rlep = 1; + if (bot < 0) + bot = 0; + bot += (rlep-1); + + i = p - (int)backSkip[p]; + while (i>=bot /* && i>=rlep-1 */) { + /* Equal number of A's ? */ + if (rlep==1 || rle[i-rlep+1]==rlep) { /* 'head' matches */ + unsigned char *a = indata + i+1; /* match */ + unsigned char *b = indata + p+rlep-1+1; /* curpos */ + int topindex = inlen-(p+rlep-1); + + j = 1; + while (j < topindex && *a++==*b++) + j++; + + if (j + rlep-1 >= lzlen[p]) { + int tmppos = p-i+rlep-1; +#ifdef EVEN_LZ + if (!(tmppos&1)) { +#endif + + rescan += + LenLz(lzlen[p], lzpos[p]) - + LenLz(lzlen[p], tmppos); +#ifdef EVEN_LZ + if (tmppos&1) + fprintf(stderr,"Error: misalign in tmppos\n"); +#endif + lzpos[p] = tmppos; + break; +#ifdef EVEN_LZ + } +#endif + } + } + if (!backSkip[i]) + break; /* No previous occurrances (near enough) */ + i -= (int)backSkip[i]; + } + } + + for (i=0; i= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= '0' && c <= '9') return c - '0'; + return NO_HEX_CHARACTER; +} + + +//============================================================================= +// converts hex text into binary +//============================================================================= +int ConvertText2Bin(unsigned char* ib,int origlen) { + int pos; + int cnt = 0; + int searchforendofline = 0; + int len_after_convert = 0; + unsigned char val = 0; + unsigned char actual; + + len_after_convert = 0; + for (pos = 0; pos < origlen;pos++) { + if (searchforendofline) { + if (ib[pos] == '\n') searchforendofline = 0; + continue; + } + if (ib[pos] == '/') { + cnt = 0; + if (pos < origlen-1 && ib[pos+1] == '/') searchforendofline = 1; + continue; + } + + actual = hex2int(ib[pos]); + if (actual == NO_HEX_CHARACTER) { + cnt = 0; + continue; + } + if (cnt == 0) { + val = actual*16; + cnt++; + } + else { + val += actual; + cnt=0; + ib[len_after_convert++] = val; + } + } + return(len_after_convert); +} + +void *GTPackDo(void *buf,unsigned short *buflen) { + int startEscape; + char *ptr; + +// unsigned long timeused = clock(); + + lrange = LRANGE; + maxlzlen = MAXLZLEN; + maxrlelen = MAXRLELEN; + + InitValueLen(); + + indata = buf; + inlen = *buflen; + PackLz77(lrange, F_AUTO|F_AUTOEX, &startEscape, 1234, 12345, 0); + free(indata); + { + int i; + PackedHeader cth; + RLEEntries re; + + cth.origsize_lo = inlen & 0xff; + cth.origsize_hi = (inlen >> 8); + memcpy(cth.magic,"GTPk",4); + cth.compsize_lo = (outlen + rleUsed + sizeof(PackedHeader)) & 0xff; + cth.compsize_hi = (outlen + rleUsed + sizeof(PackedHeader)) >> 8; + cth.esc1 = (startEscape >> (8-escBits)); + cth.esc2 = escBits; + cth.extralz = extraLZPosBits; + cth.rleentries = rleUsed; + + for(i=0; i> (8-escBits) +// unsigned char notused3; +// unsigned char notused4; + unsigned char esc2; // escBits + unsigned char gamma1; // maxGamma + 1 + unsigned char gamma2; // (1<> (8-escBits) + unsigned char extralz; // extraLZPosBits + unsigned char rleentries; // rleUsed +} PackedHeader; +#endif + + +#define GetUnPackedSize(p) (unsigned int)((p)->origsize_lo | ((p)->origsize_hi << 8)) +#define IsPacked(p) ((p)->magic1 == MAGIC_CHAR1 && (p)->magic2 == MAGIC_CHAR2) + + +typedef struct { + unsigned char value[MAX_RLE_ENTRIES]; +} RLEEntries; + + +#endif + + +//############################################################################# +//###################### NO MORE FAKES BEYOND THIS LINE ####################### +//############################################################################# +// +//============================================================================= +// Revision History +//============================================================================= +// +// $Log: packhead.h,v $ +// Revision 1.4 2005/08/04 21:27:43 Paul Froissart +// adapted for XPak +// +// Revision 1.3 2000/08/20 15:24:28 Thomas Nussbaumer +// macros to get unpacked size and to check if packed added +// +// Revision 1.2 2000/08/16 23:08:55 Thomas Nussbaumer +// magic characters changed to TP ... t(igcc tools) p(acked file) +// +// Revision 1.1 2000/08/14 22:49:57 Thomas Nussbaumer +// initial version +// +// diff --git a/gtc/src/gtpack/revtools.h b/gtc/src/gtpack/revtools.h new file mode 100644 index 0000000..e0b5dea --- /dev/null +++ b/gtc/src/gtpack/revtools.h @@ -0,0 +1,108 @@ +/****************************************************************************** +* +* project name: TIGCC Tools Suite +* file name: revtools.h +* initial date: 23/08/2000 +* author: thomas.nussbaumer@gmx.net +* description: macros for automatic handling of version number output +* which is in sync with the CVS version number +* +* examine one of the pctools source codes to see how it works ;-) +* +* [NO CVS ID HERE BY INTENTION] +* +******************************************************************************/ + +//----------------------------------------------------------------------------- +// [Usage] +// +// (1) include this file into your tool +// +// +// (2) AFTER (!!) all includes put the following lines into your source code: +// +// #ifdef CVS_FILE_REVISION +// #undef CVS_FILE_REVISION +// #endif +// ---------------------------------------------------------------------------- +// DON'T EDIT THE NEXT REVISION BY HAND! THIS IS DONE AUTOMATICALLY BY THE +// CVS SYSTEM !!! +// ---------------------------------------------------------------------------- +// #define CVS_FILE_REVISION "$Revision$" +// +// It must be placed AFTER (!!) all includes otherwise the macros may be +// expanded wrong where you use them. For example: if you have added the above +// lines at the top of your file and include afterwards a file which does +// the same, the version of the included file will be used further due to the +// #undef CVS_FILE_REVISION. Everything clear? +// +// +// (3) to output the cvs revision number you can now to a simple: +// +// printf(CVSREV_PRINTPARAMS) +// +// if your file has, for example, the revision 1.3 the following string will +// be printed: v1.03 +// +// the prefix before the subversion is used to get equal-sized output strings +// for mainversions between 1 ... 9 and subversion between 1 .. 99 +// +// if your program leaves that range and you need to have equal-sized output +// strings you have to implement it by your own by using the +// CVSREV_MAIN and CVSREV_SUB macros which returns the main and sub versions +// as plain integers. if there is something wrong with your revision string +// CVSREV_MAIN and/or CVSREV_SUB will deliver 0, which is no valid CVS main +// or subversion number. +// +// i will suggest that you use the CVS system. its simple to handle, keeps +// track of your revisions and their history and with the smart macros below +// you haven't to worry anymore about the version output strings of your +// program. if you want a special version number you can force CVS at every +// time to give this version number to your program (0 is not allowed as +// main and subversion number - thats the only pity) +// +// within this tools suite every tool will use the automatic version handling +// but the tool suite version number itself will be handled "by hand". +// this number shouldn't change that quickly as with the tools. +// +//----------------------------------------------------------------------------- +#ifndef __REV_TOOLS_H__ +#define __REV_TOOLS_H__ +#include +#include +#include + +//----------------------------------------------------------------------------- +// just used internally +//----------------------------------------------------------------------------- +#define CVS_TRUNC_PREFIX ((strlen((CVS_FILE_REVISION))<=11) ? 0 : (CVS_FILE_REVISION+11)) +#define CVS_FIND_COMMA (strchr(CVS_TRUNC_PREFIX,'.')) +#define CVSREV_MAIN (int)(!(CVS_TRUNC_PREFIX) ? 0 : atoi(CVS_TRUNC_PREFIX)) +#define CVSREV_SUB (int)(!(CVS_TRUNC_PREFIX) ? 0 : (!(CVS_FIND_COMMA) ? 0 : atoi(CVS_FIND_COMMA+1))) + +//----------------------------------------------------------------------------- +// NOTE: THE FOLLOWING MACRO WILL ONLY HANDLE MAIN VERSION < 10 AT CONSTANT +// LENGTH !!! +// (subversions from 1 .. 99 are mapped to 01 .. 99) +// +// the following macro may be used to setup a printf(),sprintf() or fprintf() +// call +//----------------------------------------------------------------------------- +#define CVSREV_PRINTPARAMS "v%d.%02d",CVSREV_MAIN,CVSREV_SUB + + +#define PRINT_ID(name) fprintf(stderr,"\n");fprintf(stderr, name" ");\ + fprintf(stderr,CVSREV_PRINTPARAMS);\ + fprintf(stderr," - TIGCC Tools Suite v"TTV_MAIN TTV_SUB"\n" \ + "(c) thomas.nussbaumer@gmx.net " TTV_DATE"\n\n"); + + + + + + +#endif + +//############################################################################# +//###################### NO MORE FAKES BEYOND THIS LINE ####################### +//############################################################################# diff --git a/gtc/src/gtpack/tt.h b/gtc/src/gtpack/tt.h new file mode 100644 index 0000000..c29a180 --- /dev/null +++ b/gtc/src/gtpack/tt.h @@ -0,0 +1,48 @@ +/****************************************************************************** +* +* project name: TIGCC Tools Suite +* file name: tt.h +* initial date: 13/08/2000 +* author: thomas.nussbaumer@gmx.net +* description: generic definitions for TIGCC Tools Suite +* +* $Id: tt.h,v 1.3 2000/08/23 20:29:43 Thomas Nussbaumer Exp $ +* +******************************************************************************/ + +#ifndef __TT_H__ +#define __TT_H__ + +#define CALC_TI89 0 +#define CALC_TI92P 1 + +#define SIGNATURE_TI89 "**TI89**" +#define SIGNATURE_TI92P "**TI92P*" + +#define DEFAULT_FOLDER "main" + +#define DEFAULT_ITEMS_PER_LINE 10 + +#endif + +//############################################################################# +//###################### NO MORE FAKES BEYOND THIS LINE ####################### +//############################################################################# +// +//============================================================================= +// Revision History +//============================================================================= +// +// $Log: tt.h,v $ +// Revision 1.3 2000/08/23 20:29:43 Thomas Nussbaumer +// added a 'P' to the TI92p definitions +// +// Revision 1.2 2000/08/23 01:04:41 Thomas Nussbaumer +// corrected signature of TI92p +// +// Revision 1.1 2000/08/13 20:24:16 Thomas Nussbaumer +// initial version +// +// +// +// diff --git a/gtc/src/gtpack/ttunpack.h b/gtc/src/gtpack/ttunpack.h new file mode 100644 index 0000000..5dcc0bd --- /dev/null +++ b/gtc/src/gtpack/ttunpack.h @@ -0,0 +1,49 @@ +/****************************************************************************** +* +* project name: TIGCC Tools Suite +* file name: ttunpack.h +* initial date: 14/08/2000 +* author: thomas.nussbaumer@gmx.net +* description: defines of errorcodes of decompression routine and its +* declaration +* $Id: ttunpack.h,v 1.2 2000/08/20 15:26:21 Thomas Nussbaumer Exp $ +* +******************************************************************************/ + +#ifndef __TTUNPACK_H__ +#define __TTUNPACK_H__ + +#define K_GAMMA 1 +#define M_GAMMA 0 + +#define ERRPCK_OKAY 0 +#define ERRPCK_NOESCFOUND 248 +#define ERRPCK_ESCBITS 249 +#define ERRPCK_MAXGAMMA 250 +#define ERRPCK_EXTRALZP 251 +#define ERRPCK_NOMAGIC 252 +#define ERRPCK_OUTBUFOVERRUN 253 +#define ERRPCK_LZPOSUNDERRUN 254 + +int _tt_Decompress(unsigned char *src, unsigned char *dest); +#define UnPack _tt_Decompress + +#endif + + +//############################################################################# +//###################### NO MORE FAKES BEYOND THIS LINE ####################### +//############################################################################# +// +//============================================================================= +// Revision History +//============================================================================= +// +// $Log: ttunpack.h,v $ +// Revision 1.2 2000/08/20 15:26:21 Thomas Nussbaumer +// prefix of unpack routine (_tt_) corrected +// +// Revision 1.1 2000/08/14 22:49:57 Thomas Nussbaumer +// initial version +// +// diff --git a/gtc/src/gtpack/ttversion.h b/gtc/src/gtpack/ttversion.h new file mode 100644 index 0000000..404feba --- /dev/null +++ b/gtc/src/gtpack/ttversion.h @@ -0,0 +1,53 @@ +/****************************************************************************** +* +* project name: TIGCC Tools Suite +* file name: ttversion.h +* initial date: 13/08/2000 +* author: thomas.nussbaumer@gmx.net +* description: TIGCC Tools Suite version definitions +* +* $Id: ttversion.h,v 1.7 2000/10/01 14:59:22 Thomas Nussbaumer Exp $ +* +******************************************************************************/ + +#ifndef __TTVERSION_H__ +#define __TTVERSION_H__ + +#define TTV_MAIN "0.95" +#define TTV_SUB "" +#define TTV_DATE "01/10/2000" + +#endif + +//############################################################################# +//###################### NO MORE FAKES BEYOND THIS LINE ####################### +//############################################################################# +// +//============================================================================= +// Revision History +//============================================================================= +// +// $Log: ttversion.h,v $ +// Revision 1.7 2000/10/01 14:59:22 Thomas Nussbaumer +// generic commit +// +// Revision 1.6 2000/08/27 23:52:39 Thomas Nussbaumer +// forcing version to 0.41 +// +// Revision 1.5 2000/08/23 20:31:37 Thomas Nussbaumer +// next version step +// +// Revision 1.4 2000/08/23 01:05:59 Thomas Nussbaumer +// next version step +// +// Revision 1.3 2000/08/16 23:09:15 Thomas Nussbaumer +// version actualized to 0.15 +// +// Revision 1.2 2000/08/13 20:26:12 Thomas Nussbaumer +// version now 0.10 (preview release) +// +// Revision 1.1 2000/08/13 16:02:13 Thomas Nussbaumer +// initial version +// +// +// diff --git a/gtc/src/identity.h b/gtc/src/identity.h new file mode 100644 index 0000000..acf588a --- /dev/null +++ b/gtc/src/identity.h @@ -0,0 +1,22 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) volatilizing a value + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef __IDENTITY +#define __IDENTITY +void *identity(void *x) { + return x; +} +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/init.c b/gtc/src/init.c new file mode 100644 index 0000000..bc8d03d --- /dev/null +++ b/gtc/src/init.c @@ -0,0 +1,434 @@ +/* + * GTools C compiler + * ================= + * source file : + * initialisations + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#define USE_MEMMGT +#include "cglbdec.h" + +long inittype(TYP *,TYP **); +static long initstruct(TYP *,TYP **), initarray(TYP *,TYP **), initunion(TYP *,TYP **); +static int initchar(), initshort(), initlong(), initpointer(); +#ifndef NOFLOAT +static int initfloat(); +#ifdef DOUBLE +static int initdouble(); +#endif +#endif +static struct enode *constexpr(); +extern TYP *copy_type(TYP *s); + +TYP *copy_type_global(TYP *tp) { + TYP *tp2; + temp_local++; + global_flag++; + tp2=copy_type(tp); + global_flag--; + temp_local--; + return tp2; +} + +void doinit(struct sym *sp, int align) { + nl(); + if (lastst != assign) + genstorage(sp, align); + else { + struct slit *strtab_old=strtab; + int glob = global_flag; + int no_locblk = !locblk; +/* if (lineid>=0x100) + bkpt();*/ + strtab = 0; + global_flag = 0; + tmp_use(); + temp_local++; + global_strings++; + dseg(); /* select data segment */ + put_align(align); +#ifndef AS + if (sp->storage_class == sc_static) + put_label((unsigned int) sp->value.i); + else + g_strlab(sp->name); +#else +#ifdef PC +#define gnu_hook(x,y) ((x)?(x):(y)) +#else +#define gnu_hook(x,y) ((x)?:(y)) +#endif + if (sp->storage_class == sc_static) { + extern int glblabel; + put_label(gnu_hook(sp->value.splab,sp->value.splab=nxtglabel())); + } else + put_label(splbl(sp)); +#endif + getsym(); + (void) inittype(sp->tp,&sp->tp); +/* if (strtab) + bkpt();*/ + if (strtab) + dumplits(); + global_strings--; + temp_local--; + tmp_free(); /* just in case, but shouldn't get used because of temp_local */ + if (no_locblk && locblk) + rel_local(); + global_flag = glob; + strtab = strtab_old; + } +} + +long inittype(TYP *tp,TYP **tpp) { + int brace_seen = 0; + long nbytes; + if (lastst == begin) { + brace_seen = 1; + getsym(); + } + switch (tp->type) { + case bt_char: + case bt_uchar: + nbytes = initchar(); + break; + case bt_short: + case bt_ushort: + nbytes = initshort(); + break; + case bt_pointer: + if (tp->val_flag) + nbytes = initarray(tp,tpp); + else { + nbytes = initpointer(); + } + break; + case bt_ulong: + case bt_long: + nbytes = initlong(); + break; +#ifndef NOFLOAT + case bt_float: + nbytes = initfloat(); + break; +#ifdef DOUBLE + case bt_double: + nbytes = initdouble(); + break; +#endif +#endif + case bt_struct: + nbytes = initstruct(tp,tpp); + break; + case bt_union: + nbytes = initunion(tp,tpp); + break; + default: + error(ERR_NOINIT); + nbytes = 0; + } + if (brace_seen) + needpunc(end); + return nbytes; +} + +/*void modf_btp(TYP *new_btp,TYP *tp) { + tp=copy_type(tp); + tp->btp=new_btp; + modf(tp,modfp); +}*/ + +extern unsigned int pos; +static long initarray(TYP *tp,TYP **tpp) { + long nbytes; + char *p; + int len; +#ifdef AS + unsigned int max_pos=pos; +#endif +// tmp_use(); + nbytes = 0; + if (lastst == sconst && (tp->btp->type == bt_char || + tp->btp->type == bt_uchar)) { + len = lstrlen; + nbytes = len; + p = laststr; + while (len--) + genbyte(*p++); + if (!tp->size) /* if tp->size!=0, then the padding stuff takes care of it */ + genbyte(0), nbytes++; + while (nbytes < tp->size) + genbyte(0), nbytes++; + getsym(); /* skip sconst */ + } else if (lastst == kw_incbin) { + FILE *fp; int size; +#ifndef PC + unsigned char type; +#endif +/* getsym(); + if (lastst!=sconst) + error(ERR_SYNTAX);*/ + skipspace(); + if (lastch!='"') + error(ERR_SYNTAX); + getch(); + getidstr(); + if (lastch!='"') + error(ERR_SYNTAX); + getch(); + getsym(); + fp=fopen(lastid,"rb"); + if (!fp) + uerr(ERR_CANTOPEN,lastid); +#ifdef PC + p=malloc(100000); + size=fread(p,1,100000,fp); +#else + p=*(char **)fp; + size=*(unsigned short *)p; + type=p[size+1]; + if (type==0xF3 || type==0xE0) size--; + else if (type==0xF8) { size--; do size--; while (p[size+1]); } +#endif + if (tp->size && size>tp->size) size=tp->size; + nbytes=size; + while (size--) genbyte(*p++); + while (nbytessize) { + genbyte(0); + nbytes++; + } + } else if (lastst == end) + goto pad; + else { + int i,additional,size; + for (i=0;;) { + additional=0; + if (lastst == openbr) { + getsym(); { + int j=intexpr(); + long diff=tp->btp->size*(j-i); + if (lastst == dots) { + getsym(); + additional=intexpr()-j; + } + if (lastst != closebr) error(ERR_SYNTAX); + else { + getsym(); + if (lastst == assign) getsym(); + if (i=0) { + nbytes += (size=inittype(tp->btp,NULL)); i++; +#ifdef AS + while (additional--) rewrite(size), nbytes+=size, i++; +#endif + } + #ifdef AS + if (pos>max_pos) max_pos=pos; + #endif + if (lastst == comma) + getsym(); + if (lastst == end || lastst == semicolon) { + pad: + #ifdef AS + if (possize) { + genbyte(0); + nbytes++; + } + break; + } + if (tp->size > 0 && nbytes >= tp->size) + break; + } + } +#if 0 + if (tp->size == 0) + tp->size = nbytes; + if (nbytes > tp->size) + error(ERR_INITSIZE); +#else + if (tp->size && nbytes > tp->size) + error(ERR_INITSIZE); + if (tp->size != nbytes && tpp) + /* fix the symbol's size, unless tpp=0 (item of a struct/union or array) */ + tp = copy_type_global(tp), + *tpp = tp, + tp->size = nbytes; // we need this for the 'sizeof' operator... +#endif +// tmp_free(); + return nbytes; +} + +static long initunion(TYP *tp,TYP **tpp) { + struct sym *sp; + long nbytes; + + int brace_seen = 0; + if (lastst == begin) { + brace_seen = 1; + getsym(); + } + + sp = tp->lst.head; +/* + * Initialize the first branch + */ + if (sp == 0) + return 0; + nbytes = inittype(sp->tp,NULL); + while (nbytes < tp->size) { + genbyte(0); + nbytes++; + } + + if (tp->size != nbytes && tpp) + tp = copy_type_global(tp), + *tpp = tp, + tp->size = nbytes; // we need this for the 'sizeof' operator... + + if (brace_seen) + needpunc(end); +} + +static long initstruct(TYP *tp,TYP **tpp) { + struct sym *sp; + long nbytes; + nbytes = 0; + sp = tp->lst.head; /* start at top of symbol table */ + if (lastst != end) + while (sp != 0) { + while (nbytes < sp->value.i) { /* align properly */ + nbytes++; + genbyte(0); + } + nbytes += inittype(sp->tp,NULL); + if (lastst == comma) + getsym(); + if (lastst == end || lastst == semicolon) + break; + sp = sp->next; + } + while (nbytes < tp->size) { + genbyte(0); + nbytes++; + } + if (tp->size != nbytes && tpp) + tp = copy_type_global(tp), + *tpp = tp, + tp->size = nbytes; // we need this for the 'sizeof' operator... + + return tp->size; +} + +static int initchar() { + genbyte((int) intexpr()); + return 1; +} + +static int initshort() { + genword((int) intexpr()); + return 2; +} + +static int initlong() { +/* + * We allow longs to be initialized with pointers now. + * Thus, we call constexpr() instead of intexpr. + */ +#if 0 +/* + * This is more strict + */ + genlong(intexpr()); + return 4; +#endif + genptr(constexpr()); + return 4; +} + +#ifndef NOFLOAT +static int initfloat() { +#ifndef NOFLOAT + double floatexpr(); +#ifdef PC + genfloat(floatexpr()); +#else +#ifndef BCDFLT + genptr(floatexpr()); +#else + genfloat(floatexpr()); +#endif +#endif +#endif +#ifdef NOFLOAT + genptr(0l); +#endif + return 4; +} + +#ifdef DOUBLE +static int initdouble() { +#ifdef NOFLOAT + int i; + for (i=0; i< tp_double.size; i++) + genbyte(0); +#endif +#ifndef NOFLOAT + double floatexpr(); + gendouble(floatexpr()); +#endif + return tp_double.size; +} +#endif +#endif + +static int initpointer() { + genptr(constexpr()); + return 4; +} + +static struct enode *constexpr() { + struct enode *ep; + struct typ *tp; +/* if (lineid==0x1e0) + bkpt();*/ + tp=exprnc(&ep); + if (tp == 0) { + error(ERR_EXPREXPECT); + return 0; + } + opt0(&ep); + if (!tst_const(ep)) { + error(ERR_CONSTEXPECT); + return 0; + } + return ep; +} +// vim:ts=4:sw=4 diff --git a/gtc/src/intexpr.c b/gtc/src/intexpr.c new file mode 100644 index 0000000..a29da9a --- /dev/null +++ b/gtc/src/intexpr.c @@ -0,0 +1,96 @@ +/* + * GTools C compiler + * ================= + * source file : + * integer expression routines + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifndef NOFLOAT +#include "ffplib.h" +#endif + +#ifndef NOFLOAT +double floatexpr() { +/* floating point expression */ + struct enode *ep; + struct typ *tp; + + tp = exprnc(&ep); + if (tp == 0) { + error(ERR_FPCON); + return (double) 0; + } + + opt0(&ep); + + if (ep->nodetype == en_icon) +#ifdef PC + return (double) ep->v.i; +#else + return ffpltof(ep->v.i); +#endif + + if (ep->nodetype == en_fcon) + return ep->v.f; + + error (ERR_SYNTAX); + return (double) 0; +} +#endif /* !NOFLOAT */ + +long intexpr() { + struct enode *ep; + struct typ *tp; + long val; + + tmp_use(); + tp = exprnc(&ep); + if (tp == 0) { + error(ERR_INTEXPR); + return 0; + } + opt0(&ep); + + if (ep->nodetype != en_icon) { + error(ERR_SYNTAX); + return 0; + } + val=ep->v.i; + tmp_free(); + return val; +} + +#if 0 +long intexpr_notemp() { + struct enode *ep; + struct typ *tp; + + tp = exprnc(&ep); + if (tp == 0) { + error(ERR_INTEXPR); + return 0; + } + opt0(&ep); + + if (ep->nodetype != en_icon) { + error(ERR_SYNTAX); + return 0; + } + return ep->v.i; +} +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/memmgt.c b/gtc/src/memmgt.c new file mode 100644 index 0000000..856e335 --- /dev/null +++ b/gtc/src/memmgt.c @@ -0,0 +1,532 @@ +/* + * GTools C compiler + * ================= + * source file : + * memory management + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#define USE_MEMMGT +#include "cglbdec.h" + +int glbsize CGLOB, /* size left in current global block */ + locsize CGLOB, /* size left in current local block */ + tmpsize CGLOB, /* size left in current temp block */ + glbindx CGLOB, /* global index */ + locindx CGLOB, /* local index */ + tmpindx CGLOB; /* temp index */ + +int temp_mem CGLOB,temp_local CGLOB; +#ifdef MIN_TEMP_MEM +int min_temp_mem CGLOB; +#endif + +#ifdef PC +int glbmem CGLOB,locmem CGLOB; +#endif + +int max_mem CGLOB, /* statistics... */ + glo_mem CGLOB; + +struct blk *locblk CGLOB, /* pointer to local block list */ + *glbblk CGLOB, /* pointer to global block list */ + *tmpblk CGLOB; /* pointer to temporary block list */ + +#ifdef PC +//void *calloc(); +#endif +static void _err_attr error_memory() { + uerrc2("not enough memory to compile function '%s'",func_sp->name); +} +int *_xalloc(int siz) { + struct blk *bp; + char *rv; + if (temp_local) /* this is NOT perfect, but it's close to being so :) */ + goto glb_xalloc; +/* if (locmem>=50000) + bkpt();*/ +/* if (siz>=1000) + bkpt();*/ +#ifdef MIN_TEMP_MEM + if (temp_mem<=min_temp_mem) { +#else + if (!temp_mem) { +#endif + glb_xalloc: + if (global_flag) { + #ifdef PC + glbmem += siz; + #endif + if (glbsize >= siz) { + rv = &(glbblk->m[glbindx]); + glbsize -= siz; + glbindx += siz; +/* if ((long)rv==0x789388) + bkpt();*/ + return (int *) rv; + } else { + // bp = (struct blk *) calloc(1, (int) sizeof(struct blk)); + bp = (struct blk *) malloc(sizeof(struct blk)); + if (!bp) { +#ifdef PC + msg("not enough memory.\n"); + _exit(1); +#else + error_memory(); + fatal("Not enough global memory"); +#endif + } + memset(bp, 0, sizeof(struct blk)); + glo_mem++; + bp->next = glbblk; + glbblk = bp; + glbsize = BLKLEN - siz; + glbindx = siz; + return (int *) glbblk->m; + } + } else { /* not global */ + #ifdef PC + locmem += siz; + #endif + if (locsize >= siz) { + rv = &(locblk->m[locindx]); + locsize -= siz; + /*if ((long)rv==0x7f86bc) + bkpt();*/ + locindx += siz; + #ifdef PC + if (0x80000000&(long)rv) + fatal("A DIRTY HACK FAILED ON YOUR CONFIG. " + "LOOK AT OUT68K_AS.C TO SOLVE THE PROBLEM"); + #endif +/* if (func_sp) infunc("chk_curword") + if ((long)rv==0x7b4bf8) + bkpt();*/ +/* if ((long)rv==0x7e5cd0) + bkpt();*/ + return (int *) rv; + } else { + // bp = (struct blk *) calloc(1, (int) sizeof(struct blk)); + bp = (struct blk *) malloc(sizeof(struct blk)); + if (!bp) { +#ifdef PC + msg("not enough local memory.\n"); + _exit(1); +#else + error_memory(); + fatal("Not enough local memory"); +#endif + } + memset(bp, 0, sizeof(struct blk)); + bp->next = locblk; + locblk = bp; + locsize = BLKLEN - siz; + locindx = siz; + return (int *) locblk->m; + } + } + } else { + if (tmpsize >= siz) { + rv = &(tmpblk->m[tmpindx]); + tmpsize -= siz; + tmpindx += siz; + return (int *) rv; + } else { +// bp = (struct blk *) calloc(1, (int) sizeof(struct blk)); + bp = (struct blk *) malloc(sizeof(struct blk)); + if (!bp) { +#ifdef PC + msg("not enough temporary memory.\n"); + _exit(1); +#else + error_memory(); + fatal("Not enough temporary memory"); +#endif + } +/* if (bp==0x789364) + bkpt();*/ + memset(bp, 0, sizeof(struct blk)); + bp->next = tmpblk; + tmpblk = bp; + tmpsize = BLKLEN - siz; + tmpindx = siz; + return (int *) tmpblk->m; + } + } +} + +int blk_free(struct blk *bp1) { + int blkcnt = 0; + struct blk *bp2; + while (bp1) { + bp2 = bp1->next; + (void) free((char *) bp1); + blkcnt++; + bp1 = bp2; + } + return blkcnt; +} + +#ifdef DUAL_STACK +typedef struct _ds_block { + void *lo,*hi; + struct _ds_block *pop; + void *popstackptr; +} DS_BLOCK; +static DS_BLOCK *ds_current CGLOB; +void *dualstack CGLOB; +void *ds_currentlo CGLOB,*ds_currenthi CGLOB; + +#ifdef PC +int n_ds_allocations CGLOB; +#endif +void ds_allocatleast(unsigned int size) { + size+=DS_BSIZE; + DS_BLOCK *ds_new = malloc(sizeof(DS_BLOCK)+size); + ds_new->lo = (void *)(ds_new+1); + ds_new->hi = (void *)((char *)ds_new->lo+size); + ds_new->pop = ds_current; + ds_new->popstackptr = dualstack; + ds_current = ds_new; + ds_currentlo = ds_current->lo; + ds_currenthi = ds_current->hi; + dualstack = ds_currentlo; +#ifdef PC + n_ds_allocations++; +#endif +} +void ds_free(void) { + DS_BLOCK *ds_old = ds_current; + ds_current = ds_old->pop; + ds_currentlo = ds_current ? ds_current->lo : 0; + ds_currenthi = ds_current ? ds_current->hi : 0; + dualstack = ds_old->popstackptr; + free(ds_old); +} +void rel_dualstack(void) { + while (ds_current) + ds_free(); +#ifdef PC + //msg2(" performed %d dual-stack-related allocations\n",n_ds_allocations); +#endif +} +#endif + +#define VERBOSE +#ifdef GARBAGE_COLLECT +void d_enode(struct enode **node) { + struct enode *dest,*ep=*node; + if (!ep) return; + if (ep->nodetype==en_icon) { *node=mk_icon(ep->v.i); return; } + dest=xalloc((int)sizeof(struct enode), ENODE); + memcpy(dest,ep,sizeof(struct enode)); + *node=dest; + switch (ep->nodetype) { + case en_land: case en_lor: + case en_asand: case en_asor: case en_asxor: + case en_aslsh: case en_asrsh: + case en_asmul: case en_asmod: case en_asdiv: + case en_asadd: case en_assub: + case en_gt: case en_ge: + case en_lt: case en_le: + case en_eq: case en_ne: + case en_cond: case en_assign: + case en_and: case en_or: case en_xor: + case en_lsh: case en_rsh: + case en_mul: case en_mod: case en_div: + case en_add: case en_sub: + case en_fcall: case en_void: + d_enode(&ep->v.p[1]); + case en_deref: + case en_ainc: case en_adec: + case en_uminus: case en_not: case en_compl: + case en_ref: + case en_cast: /* hum hum */ + case en_fieldref: + d_enode(&ep->v.p[0]); + case en_tempref: + case en_autocon: + case en_labcon: + case en_nacon: + case en_fcon: + return; + case en_compound: + d_snode(&ep->v.st); + return; + default: + ierr(D_ENODE,1); + } +} + +void d_snode(struct snode **node) { + struct snode *dest,*block=*node; + if (!block) return; + dest=xalloc((int)sizeof(struct snode), SNODE); + memcpy(dest,block,sizeof(struct snode)); + *node=dest; + while (block != 0) { + switch (block->stype) { + case st_return: + case st_expr: + d_enode(&block->exp); + break; + case st_loop: + d_enode(&block->exp); + d_snode(&block->s1); + d_enode(&block->v2.e); + break; + case st_while: + case st_do: + d_enode(&block->exp); + d_snode(&block->s1); + break; + case st_for: + d_enode(&block->exp); + d_enode(&block->v1.e); + d_snode(&block->s1); + d_enode(&block->v2.e); + break; + case st_if: + d_enode(&block->exp); + d_snode(&block->s1); + d_snode(&block->v1.s); + break; + case st_switch: + d_enode(&block->exp); + d_snode(&block->v1.s); + break; + case st_case: + case st_default: + d_snode(&block->v1.s); + break; + case st_compound: + case st_label: + d_snode(&block->s1); + case st_goto: + case st_break: + case st_continue: + break; + case st_asm: + d_amode(&(struct amode *)block->v1.i); + break; + default: + ierr(D_SNODE,1); + } + block = block->next; + } +} + +void d_amode(struct amode **node) { + struct amode *dest,*mode=*node; + if (!mode) return; + dest=xalloc((int)sizeof(struct amode), AMODE); + memcpy(dest,mode,sizeof(struct amode)); + *node=dest; + d_enode(&dest->offset); +} +extern struct ocode *_peep_head; +void d_ocodes(void) { + struct ocode *dest=NULL,**node=&_peep_head,*instr; + while ((instr=*node)) { + instr->back=dest; + dest=xalloc((int)sizeof(struct ocode), OCODE); + memcpy(dest,instr,sizeof(struct ocode)); + *node=dest; + d_amode(&dest->oper1); + d_amode(&dest->oper2); + node=&dest->fwd; + } + *node=NULL; +} + +extern struct snode *dump_stmt; +void collect(int g) { + struct blk *blk=glbblk; + glbsize=glbindx=0; + glbblk=NIL_BLK; + alloc_dump(g); + // dump snodes & most enodes +// d_snode(&dump_stmt); + // dump ocodes & amodes & the rest of enodes +// d_ocodes(); + // dump most syms & most strs & typs & tables & the rest of syms & a few strs + d_table(&gsyms); d_table(>ags); d_table(&defsyms); + // dump slits & the rest of strs +// + // no dump is needed for cse's since it is a cooperative garbage-collection +} +#endif + +int _k_=0; +void tmp_use() { + temp_mem++; + _k_++; +} +void tmp_free() { + if (!--temp_mem && tmpblk) { +#ifdef PC + int n=0; +#endif +#ifndef LIFO_TMP_FREE + /* Maybe I'm wrong, but I think that this solution + * is quite bad for the TIOS heap manager... */ + struct blk *nxt; + while ((nxt=tmpblk->next)) + #ifdef PC + n++, + #endif + free(tmpblk),tmpblk=nxt; +#else + struct blk *nxt=tmpblk->next,*tofree; + while (nxt) + #ifdef PC + n++, + #endif + tofree=nxt, nxt=nxt->next, free(tofree); +#endif +#ifdef _DBG_SHOW_TEMPMEM + printf("*"); +#ifdef PC + printf("(%dk)",n*BLKLEN/1024); +// getchar(); +#endif +#endif + tmpsize = BLKLEN; + tmpindx = 0; + memset(tmpblk,0,BLKLEN); + /*blk_free(tmpblk); + tmpblk = 0; + tmpsize = 0;*/ + } +} + +void rel_local() { + unsigned int mem; +#ifndef AS +#define pos 0 +#else + extern unsigned int pos; +#endif +#ifdef PC +#ifdef GARBAGE_COLLECT + collect(0); +#endif +#ifdef LISTING + alloc_dump(0); +#endif +#endif + if ((mem=blk_free(locblk))+glo_mem+(2*pos)/BLKLEN > (unsigned int)max_mem) { + max_mem = mem+glo_mem+(2*pos)/BLKLEN; + /*if (max_mem>330/4) + bkpt();*/ + } +#ifndef AS +#undef pos +#endif +#ifdef PC + locmem = 0; +#endif + locblk = 0; + locsize = 0; +//#ifndef PC +#ifndef GTDEV +#ifdef PC + if (verbose) +#endif + msg2("%d kb\n", (int)(mem * BLKLEN/1024)); +#endif +//#endif +#ifdef VERBOSE +#ifdef LISTING +#if 0 + if (list_option) + msg2(" releasing %2d kb local tables.\n", + mem * BLKLEN/1024); +#endif +#endif +#endif +} + +void rel_global() { + int mem; + if ((mem=blk_free(glbblk)) > max_mem) + max_mem = mem; +#ifdef PC + glbmem = 0; +#endif + glo_mem = 0; + glbblk = 0; + glbsize = 0; + blk_free(tmpblk); + tmpblk = 0; + tmpsize = 0; +#ifdef PC +#ifdef LISTING + alloc_dump(1); +#endif +#endif +#ifdef VERBOSE +#ifdef LISTING + if (list_option) + msg2(" releasing %2d kb global tables.\n", + mem * BLKLEN/1024); +#endif +#ifdef DUAL_STACK + //if (ds_current) + // msg("oops, a dual stack remains\n"); + rel_dualstack(); +#endif +#ifndef GTDEV +#ifdef PC + if (verbose) { + msg2("Max memory request : %d kb\n", + (int)(max_mem * BLKLEN/1024)); + msg("\n"); + if (max_mem * BLKLEN/1024<150) + msg("On-calc portability : very good\n"); + else if (max_mem * BLKLEN/1024<230) + msg("On-calc portability : good\n"); + else if (max_mem * BLKLEN/1024<290) + msg("On-calc portability : questionable\n"); + else if (max_mem * BLKLEN/1024<360) + msg("On-calc portability : difficult without splitting\n"); + else + msg("On-calc portabilty : impossible without splitting\n"); + msg("\n"); + } +#endif +#endif +#endif + max_mem = 0; +} + +void clean_up() { + blk_free(tmpblk); + blk_free(locblk); + blk_free(glbblk); +#ifdef DUAL_STACK + //if (ds_current) + // msg("oops, a dual stack remains\n"); + rel_dualstack(); +#endif + temp_mem = 0; + glbblk = locblk = tmpblk = 0; +/*#ifdef OPTIMIZE_BSS + free(bssdata); +#endif*/ +} + +#undef VERBOSE +// vim:ts=4:sw=4 diff --git a/gtc/src/optimize.c b/gtc/src/optimize.c new file mode 100644 index 0000000..7de0d7a --- /dev/null +++ b/gtc/src/optimize.c @@ -0,0 +1,887 @@ +/* + * GTools C compiler + * ================= + * source file : + * optimization + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +static void fold_const(); + +void dooper(struct enode **node) { +/* + * dooper will execute a constant operation in a node and modify the node to + * be the result of the operation. + */ + struct enode *ep = *node; + enum(e_node) type = ep->nodetype; + +#define ep0 ep->v.p[0] +#define ep1 ep->v.p[1] +#define epi ep->v.i +#define epf ep->v.f +#define ulong unsigned long + + ep->nodetype = ep0->nodetype; + if (ep0->nodetype == en_fcon) { +#ifndef NOFLOAT + switch (type) { + case en_uminus: +#ifdef PC + epf = - ep0->v.f; +#else + epf = ep0->v.f; + if (epf) epf^=0x80; +#endif + break; + case en_not: + ep->nodetype = en_icon; + epi = (ep0->v.f) ? 0 : 1; + break; + case en_add: +#ifdef PC + epf = ep0->v.f + ep1->v.f; +#else + epf = ffpadd(ep0->v.f, ep1->v.f); +#endif + break; + case en_sub: +#ifdef PC + epf = ep0->v.f - ep1->v.f; +#else + epf = ffpsub(ep0->v.f, ep1->v.f); +#endif + break; + case en_mul: +#ifdef PC + epf = ep0->v.f * ep1->v.f; +#else + epf = ffpmul(ep0->v.f, ep1->v.f); +#endif + break; + case en_div: + if (ep1->v.f == 0) { + uwarn("division by zero"); + ep->nodetype = en_div; + } else { +#ifdef PC + epf = ep0->v.f / ep1->v.f; +#else + epf = ffpdiv(ep0->v.f, ep1->v.f); +#endif + } + break; + case en_eq: + ep->nodetype = en_icon; + epi = (ep0->v.f == ep1->v.f) ? 1 : 0; + break; + case en_ne: + ep->nodetype = en_icon; + epi = (ep0->v.f != ep1->v.f) ? 1 : 0; + break; + case en_land: + ep->nodetype = en_icon; + epi = (ep0->v.f && ep1->v.f) ? 1 : 0; + break; + case en_lor: + ep->nodetype = en_icon; + epi = (ep0->v.f || ep1->v.f) ? 1 : 0; + break; + case en_lt: + ep->nodetype = en_icon; +#ifdef PC + epi = (ep0->v.f < ep1->v.f) ? 1 : 0; +#else + epi = (ffpcmp_c(ep0->v.f, ep1->v.f) < 0) ? 1 : 0; +#endif + break; + case en_le: + ep->nodetype = en_icon; +#ifdef PC + epi = (ep0->v.f <= ep1->v.f) ? 1 : 0; +#else + epi = (ffpcmp_c(ep0->v.f, ep1->v.f) <= 0) ? 1 : 0; +#endif + break; + case en_gt: + ep->nodetype = en_icon; +#ifdef PC + epi = (ep0->v.f > ep1->v.f) ? 1 : 0; +#else + epi = (ffpcmp_c(ep0->v.f, ep1->v.f) > 0) ? 1 : 0; +#endif + break; + case en_ge: + ep->nodetype = en_icon; +#ifdef PC + epi = (ep0->v.f >= ep1->v.f) ? 1 : 0; +#else + epi = (ffpcmp_c(ep0->v.f, ep1->v.f) >= 0) ? 1 : 0; +#endif + break; + default: + ep->nodetype = type; + iwarn(DOOPER,1); + break; + } +#endif /* NOFLOAT */ + return; + } + /* + * Thus, ep0->nodetype is en_icon + * We have to distinguish unsigned long from the other cases + * + * Since we always store in ep->v.i, it is + * ASSUMED THAT (long) (ulong) ep->v.i == ep->v.i always + */ + if (ep0->etype == bt_ulong || ep0->etype == bt_pointer) { + switch (type) { + case en_uminus: + epi = - ep0->v.i; + break; + case en_not: + epi = ((ulong) ep0->v.i) ? 0 : 1; + break; + case en_compl: + epi = ~ (ulong) ep0->v.i; + epi = strip_icon(epi, ep->etype); + break; + case en_add: + epi = (ulong) ep0->v.i + (ulong) ep1->v.i; + break; + case en_sub: + epi = (ulong) ep0->v.i - (ulong) ep1->v.i; + break; + case en_mul: + epi = (ulong) ep0->v.i * (ulong) ep1->v.i; + break; + case en_div: + if ((ulong) ep1->v.i == 0) { + uwarn("division by zero"); + ep->nodetype = en_div; + } else { + epi = (ulong) ep0->v.i / (ulong) ep1->v.i; + } + break; + case en_mod: + if ((ulong) ep1->v.i == 0) { + uwarn("division by zero"); + ep->nodetype = en_mod; + } else { + epi = (ulong) ep0->v.i % (ulong) ep1->v.i; + } + break; + case en_and: + epi = (ulong) ep0->v.i & (ulong) ep1->v.i; + break; + case en_or: + epi = (ulong) ep0->v.i | (ulong) ep1->v.i; + break; + case en_xor: + epi = (ulong) ep0->v.i ^ (ulong) ep1->v.i; + break; + case en_eq: + epi = ((ulong) ep0->v.i == (ulong) ep1->v.i) ? 1 : 0; + break; + case en_ne: + epi = ((ulong) ep0->v.i != (ulong) ep1->v.i) ? 1 : 0; + break; + case en_land: + epi = ((ulong) ep0->v.i && (ulong) ep1->v.i) ? 1 : 0; + break; + case en_lor: + epi = ((ulong) ep0->v.i || (ulong) ep1->v.i) ? 1 : 0; + break; + case en_lt: + epi = ((ulong) ep0->v.i < (ulong) ep1->v.i) ? 1 : 0; + break; + case en_le: + epi = ((ulong) ep0->v.i <= (ulong) ep1->v.i) ? 1 : 0; + break; + case en_gt: + epi = ((ulong) ep0->v.i > (ulong) ep1->v.i) ? 1 : 0; + break; + case en_ge: + epi = ((ulong) ep0->v.i >= (ulong) ep1->v.i) ? 1 : 0; + break; + case en_lsh: +#ifdef MINIMAL_SIZES + epi = (ulong) ep0->v.i << (char) ep1->v.i; +#else + epi = (ulong) ep0->v.i << (ulong) ep1->v.i; +#endif + break; + case en_rsh: +#ifdef MINIMAL_SIZES + epi = (ulong) ep0->v.i >> (char) ep1->v.i; +#else + epi = (ulong) ep0->v.i >> (ulong) ep1->v.i; +#endif + break; + default: + ep->nodetype = type; + iwarn(DOOPER,2); + break; + } + } else { + switch (type) { + case en_uminus: + epi = - ep0->v.i; + break; + case en_not: + epi = (ep0->v.i) ? 0 : 1; + break; + case en_compl: + epi = ~ ep0->v.i; + epi = strip_icon(epi, type); + break; + case en_add: + epi = ep0->v.i + ep1->v.i; + break; + case en_sub: + epi = ep0->v.i - ep1->v.i; + break; + case en_mul: + epi = ep0->v.i * ep1->v.i; + break; + case en_div: + if (ep1->v.i == 0) { + uwarn("division by zero"); + ep->nodetype = en_div; + } else { + epi = ep0->v.i / ep1->v.i; + } + break; + case en_mod: + if (ep1->v.i == 0) { + uwarn("division by zero"); + ep->nodetype = en_mod; + } else { + epi = ep0->v.i % ep1->v.i; + } + break; + case en_and: + epi = ep0->v.i & ep1->v.i; + break; + case en_or: + epi = ep0->v.i | ep1->v.i; + break; + case en_xor: + epi = ep0->v.i ^ ep1->v.i; + break; + case en_eq: + epi = (ep0->v.i == ep1->v.i) ? 1 : 0; + break; + case en_ne: + epi = (ep0->v.i != ep1->v.i) ? 1 : 0; + break; + case en_land: + epi = (ep0->v.i && ep1->v.i) ? 1 : 0; + break; + case en_lor: + epi = (ep0->v.i || ep1->v.i) ? 1 : 0; + break; + case en_lt: + epi = (ep0->v.i < ep1->v.i) ? 1 : 0; + break; + case en_le: + epi = (ep0->v.i <= ep1->v.i) ? 1 : 0; + break; + case en_gt: + epi = (ep0->v.i > ep1->v.i) ? 1 : 0; + break; + case en_ge: + epi = (ep0->v.i >= ep1->v.i) ? 1 : 0; + break; + case en_lsh: +#ifdef MINIMAL_SIZES + epi = ep0->v.i << (char)ep1->v.i; +#else + epi = ep0->v.i << ep1->v.i; +#endif + break; + case en_rsh: +#ifdef MINIMAL_SIZES + epi = ep0->v.i >> (char)ep1->v.i; +#else + epi = ep0->v.i >> ep1->v.i; +#endif + break; + default: + ep->nodetype = type; + iwarn(DOOPER,3); + break; + } + } +#undef ep0 +#undef ep1 +#undef epi +#undef epf +#undef ulong +} + +int pwrof2(long i) { +/* + * return which power of two i is or -1. + */ + int p; + long q; + q = 2; + p = 1; + while (q > 0) { + if (q == i) + return p; + q <<= 1; + ++p; + } + return -1; +} + +long mod_mask(long i) { +/* + * make a mod mask for a power of two. + */ + long m; + m = 0; + while (i--) + m = (m << 1) | 1; + return m; +} + +void opt0(struct enode **node) { +/* + * opt0 - delete useless expressions and combine constants. + * + * opt0 will delete expressions such as x + 0, + * x - 0, + * x * 0, + * x * 1, + * 0 / x, + * x / 1, + * x % (1<<3), + * etc from the tree pointed to by node and combine obvious + * constant operations. It cannot combine name and label constants but will + * combine icon type nodes. + */ + struct enode *ep; + +#define ep0 ep->v.p[0] +#define ep1 ep->v.p[1] + + long val, sc; + enum(e_node) typ; + ep = *node; + if (ep == 0) + return; + typ = ep->nodetype; + switch (typ) { + case en_ref: + case en_fieldref: + case en_ainc: + case en_adec: + case en_deref: + opt0(&ep0); + break; + case en_uminus: + case en_compl: + opt0(&ep0); + /* + * This operation applied twice is a no-op + */ + if (ep0->nodetype == typ) { + *node = ep0->v.p[0]; + break; + } + if (ep0->nodetype == en_icon || ep0->nodetype == en_fcon) + dooper(node); + break; + case en_not: + opt0(&ep0); + if (ep0->nodetype == en_icon || ep0->nodetype == en_fcon) + dooper(node); + break; + case en_add: + case en_sub: + opt0(&ep0); + opt0(&ep1); + /* + * a + (-b) = a - b + * a - (-b) = a + b + * (-a) + b = b - a + */ + if (ep1->nodetype == en_uminus) { + ep1 = ep1->v.p[0]; + ep->nodetype = typ = (typ == en_add) ? en_sub : en_add; + } + if (ep0->nodetype == en_uminus && typ == en_add) { + ep0 = ep0->v.p[0]; + swap_nodes(ep); + ep->nodetype = typ = en_sub; + } + /* + * constant expressions + */ + if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) || + (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon)) { + dooper(node); + break; + } + /*infunc("DrawNumberOfClock") + bkpt();*/ + /* the following would bug, as : + short my_array[2]={12,570}; + int i=2; + while (i--) printf("%d",my_array[i]); + wouldn't print 570 correctly... */ +#ifdef BUGGY_AND_ANYWAY_NOT_COMPAT_WITH_NO_OFFSET_AUTOCON + if (typ == en_add) { + if (ep1->nodetype == en_autocon) + swap_nodes(ep); + } +#endif + if (ep0->nodetype == en_icon) { + if (ep0->v.i == 0) { + if (typ == en_sub) { + ep0 = ep1; + ep->nodetype = typ = en_uminus; + } else + *node = ep1; + break; +#ifdef PREFER_POS_VALUES + } else if (ep0->nodetype==en_add && ep0->v.i<0) { + ep0->v.i=-ep0->v.i; + swap_nodes(ep); + ep->nodetype=en_sub; +#endif + } + } else if (ep1->nodetype == en_icon) { +#ifdef BUGGY_AND_ANYWAY_NOT_COMPAT_WITH_NO_OFFSET_AUTOCON + if (ep0->nodetype == en_autocon && typ == en_add) { + ep0->v.i += ep1->v.i; + *node = ep0; + break; + } +#endif + if (ep1->v.i == 0) { + *node = ep0; + break; +#ifdef PREFER_POS_VALUES + } else if (ep1->v.i<0) { + ep->nodetype^=1; + ep1->v.i=-ep1->v.i; +#endif + } + } + break; + case en_mul: + opt0(&ep0); + opt0(&ep1); + /* + * constant expressions + */ + if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) || + (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon)) { + dooper(node); + break; + } + if (ep0->nodetype == en_icon) { + val = ep0->v.i; + if (val == 0) { + *node = ep0; + break; + } + if (val == 1) { + *node = ep1; + break; + } + sc = pwrof2(val); + if (sc IS_VALID) { + swap_nodes(ep); + ep1->v.i = sc; + ep->nodetype = en_lsh; + } + } else if (ep1->nodetype == en_icon) { + val = ep1->v.i; + if (val == 0) { + *node = ep1; + break; + } + if (val == 1) { + *node = ep0; + break; + } + sc = pwrof2(val); + if (sc IS_VALID) { + ep1->v.i = sc; + ep->nodetype = en_lsh; + } + } + break; + case en_div: + opt0(&ep0); + opt0(&ep1); + /* + * constant expressions + */ + if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) || + (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon)) { + dooper(node); + break; + } + if (ep0->nodetype == en_icon) { + if (ep0->v.i == 0) { /* 0/x */ + *node = ep0; + break; + } + } else if (ep1->nodetype == en_icon) { + val = ep1->v.i; + if (val == 1) { /* x/1 */ + *node = ep0; + break; + } + sc = pwrof2(val); + if (sc IS_VALID) { + ep1->v.i = sc; + ep->nodetype = en_rsh; + } + } + break; + case en_mod: + opt0(&ep0); + opt0(&ep1); + /* + * constant expressions + */ + if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) || + (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon)) { + dooper(node); + break; + } + if (ep1->nodetype == en_icon) { + sc = pwrof2(ep1->v.i); + if (sc IS_VALID) { + ep1->v.i = mod_mask(sc); + ep->nodetype = en_and; + } + } + break; + case en_land: + case en_lor: +#if 0 /* perhaps this isn't *that* useful... and ep0/ep1 are long to access */ + opt0(&ep0); + opt0(&ep1); + if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) || + (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon)) + dooper(node); + else { + typ = (typ==en_lor); + if (ep0->nodetype == en_icon) { + if ((!ep0->v.i)!=typ) /* absorbing element */ + ep = ep0; + else /* "neutral" element */ + //ep = ep1; -> not quite, should be !!x + (void)0; + } else if (ep1->nodetype == en_icon) { + if ((!ep1->v.i)!=typ) /* absorbing element */ + ep->nodetype = en_void, ep1->v.i=typ; + else /* "neutral" element */ + //ep = ep0; -> not quite, should be !!x + (void)0; + } + } + break; +#else + /* FALL THROUGH */ +#endif + case en_and: + case en_or: + case en_xor: + case en_eq: + case en_ne: + case en_lt: + case en_le: + case en_gt: + case en_ge: + opt0(&ep0); + opt0(&ep1); + /* + * constant expressions + */ + if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) || + (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon)) + dooper(node); + break; + case en_lsh: + case en_rsh: + opt0(&ep0); + opt0(&ep1); + if (ep0->nodetype == en_icon && ep1->nodetype == en_icon) { + dooper(node); + break; + } + /* + * optimize a << 0 and a >> 0 + */ + if (ep1->nodetype == en_icon && ep1->v.i == 0) + *node = ep0; + break; + case en_cond: + opt0(&ep0); + opt0(&ep1); + if (ep0->nodetype == en_icon) { + if (ep0->v.i) { + if (ep1->v.p[0]) *node=ep1->v.p[0]; + else *node=ep0; + } else + *node=ep1->v.p[1]; + } + break; + case en_asand: + case en_asor: + case en_asxor: + case en_asadd: + case en_assub: + case en_asmul: + case en_asdiv: + case en_asmod: + case en_asrsh: + case en_aslsh: + case en_fcall: + case en_void: + case en_assign: + opt0(&ep0); + opt0(&ep1); + break; + /* now handled in expr.c */ + case en_cast: + opt0(&ep0); + if (ep0->nodetype == en_icon) { +#ifndef NOFLOAT + if (ep->etype != bt_float +#ifdef DOUBLE + && ep->etype != bt_double +#endif + ) { +#endif + ierr(OPT0,1); +/* ep->nodetype = en_icon; + ep->v.i = ep0->v.i;*/ +#ifndef NOFLOAT + } else { +#ifdef XCON_DOESNT_SUPPORT_FLOATS +#error Fix me now :) +#endif + ep->nodetype = en_fcon; +#ifdef PC + ep->v.f = (double)ep0->v.i; +#else +#ifndef BCDFLT + ep->v.f = ffpltof(ep0->v.i); +#else + ep->v.f = (double)ep0->v.i; +#endif +#endif + } +#endif + } + /* perhaps BUGGY */ + else if ((ep0->nodetype == en_labcon || ep0->nodetype == en_nacon) + && ep->esize<=ep0->esize) { + ep0->etype = ep->etype; + ep0->esize = ep->esize; + ep=ep0; + *node=ep; + } +#ifndef NOFLOAT + else if (ep0->nodetype == en_fcon && bt_integral(ep->etype)) { + ep->nodetype = en_icon; +#ifdef PC + ep->v.i = (long)ep0->v.f; +#else + ep->v.i = ffpftol(ep0->v.f); +#endif + } +#endif + break; + /*case en_icon: + case en_fcon: + case en_labcon: + case en_nacon: + case en_autocon: + case en_tempref: + break; + default: + uwarn("Didn't optimize nodetype %d. Please send me your source code.",typ);*/ + } + +#undef ep0 +#undef ep1 +} + +static long xfold(struct enode *node) { +/* + * xfold will remove constant nodes and return the values to the calling + * routines. + */ + long i; + if (node == 0) + return 0; + switch (node->nodetype) { + case en_icon: + i = node->v.i; + node->v.i = 0; + return i; + case en_add: + return xfold(node->v.p[0]) + xfold(node->v.p[1]); + case en_sub: + return xfold(node->v.p[0]) - xfold(node->v.p[1]); + case en_mul: + if (node->v.p[0]->nodetype == en_icon) + return xfold(node->v.p[1]) * node->v.p[0]->v.i; + else if (node->v.p[1]->nodetype == en_icon) + return xfold(node->v.p[0]) * node->v.p[1]->v.i; + else { + fold_const(&node->v.p[0]); + fold_const(&node->v.p[1]); + return 0; + } + /* + * CVW: This seems wrong to me... case en_lsh: if( + * node->v.p[0]->nodetype == en_icon ) return xfold(node->v.p[1]) << + * node->v.p[0]->v.i; else if( node->v.p[1]->nodetype == en_icon ) + * return xfold(node->v.p[0]) << node->v.p[1]->v.i; else return 0; + */ + case en_uminus: + return -xfold(node->v.p[0]); + case en_lsh: + case en_rsh: + case en_div: + case en_mod: + case en_asadd: + case en_assub: + case en_asmul: + case en_asdiv: + case en_asmod: + case en_and: + case en_land: + case en_or: + case en_lor: + case en_xor: + case en_asand: + case en_asor: + case en_asxor: + case en_void: + case en_fcall: + case en_assign: + case en_eq: + case en_ne: + case en_lt: + case en_le: + case en_gt: + case en_ge: + fold_const(&node->v.p[0]); + fold_const(&node->v.p[1]); + return 0; + case en_ref: + case en_fieldref: + case en_compl: + case en_not: + case en_deref: + fold_const(&node->v.p[0]); + return 0; + /* + * This is not stricly legal: (long)(x+10) * 4l might not be the same + * as (long)(x) * 4l + 40l but it is the same as long as no overflows + * occur + */ + case en_cast: +#ifdef DONTDEF + return xfold(node->v.p[0]); +#endif + /* + * Well, sometimes I prefer purity to efficiency + * It is a matter of taste how you decide here.... + */ + fold_const(&node->v.p[0]); + return 0; + } + return 0; +} + +static void fold_const(struct enode **node) { +/* + * reorganize an expression for optimal constant grouping. + */ + struct enode *ep; + long i; + ep = *node; + if (ep == 0) + return; + if (ep->nodetype == en_add) { + if (ep->v.p[0]->nodetype == en_icon) { + ep->v.p[0]->v.i += xfold(ep->v.p[1]); + return; + } else if (ep->v.p[1]->nodetype == en_icon) { + ep->v.p[1]->v.i += xfold(ep->v.p[0]); + return; + } + } else if (ep->nodetype == en_sub) { + if (ep->v.p[0]->nodetype == en_icon) { + ep->v.p[0]->v.i -= xfold(ep->v.p[1]); + return; + } else if (ep->v.p[1]->nodetype == en_icon) { + ep->v.p[1]->v.i -= xfold(ep->v.p[0]); + return; + } + } + i = xfold(ep); + if (i != 0) { +/* + * strip_icon is in fact harmless here since this value is + * just added to *node + * consider in 16-bit mode: + * + * int day, year; + * day = 365 * (year - 1970); + * + * and look at the code, which is transformed to + * + * day = 365*year + 1846; + * + * which works if the multiplication returns the lower 16 bits of + * the result correctly. + */ + i = strip_icon(i, (*node)->etype); + ep = mk_icon(i); + ep->etype = (*node)->etype; + ep->esize = (*node)->esize; + ep = mk_node(en_add, *node, ep); + ep->etype = (*node)->etype; + ep->esize = (*node)->esize; + *node = ep; + } +} + +void opt4(struct enode **node) { +/* + * apply all constant optimizations. + */ + /* opt0(node); */ + fold_const(node); + opt0(node); +} +// vim:ts=4:sw=4 diff --git a/gtc/src/out68k_as.c b/gtc/src/out68k_as.c new file mode 100644 index 0000000..43f840c --- /dev/null +++ b/gtc/src/out68k_as.c @@ -0,0 +1,3017 @@ +/* + * GTools C compiler + * ================= + * source file : + * assembled binary output + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +#ifdef PC +void nl(void) { +} +#define nl() while (0) +#endif + +#ifdef SECURIZED_ALIGN +#define put_align(__a) while (0) +#else +#define put_align(__a) put_align2() +#endif + +#ifdef PC +#define tabs "\t" +#else +#define tabs " " +#endif + +#define N_TAB 64 +#define N_TAB_LOG 6 +typedef struct _ltab { + struct _ltab *nxt; + unsigned int t[N_TAB]; +} LTAB; +#define N_REF 8 +#define N_REF_LOG 3 +typedef struct _ref { + unsigned int r[N_REF]; + struct _ref *nxt; // very important to be afterwards : if nxt==NULL, then r[N_REF]==0 +} REF; +typedef struct _gtab { + struct _gtab *nxt; + unsigned int t[N_TAB]; + REF *r[N_TAB]; +} GTAB; + +typedef struct _rtype { + REF *r0,*r; +} RTYPE; +typedef struct _func { + RTYPE rt; + unsigned int f; + struct _func *nxt; +} FUNC; +typedef struct _xtab { + struct _xtab *nxt; + RTYPE *t[N_TAB]; +} XTAB; + +FILE *output CGLOB; +unsigned char *bin CGLOB; +struct slit *strtab CGLOB; +long lc_bss CGLOB; +xstatic int lc_stk CGLOB,uses_lc_stk CGLOB; +xstatic char odd CGLOB; // for put_align +xstatic int extlabel CGLOB; +int glblabel CGLOB; +struct ocode *scope_head CGLOB; +unsigned int pos CGLOB,bin_size CGLOB; +int nostub_mode CGLOB; +#ifdef EXE_OUT +int exestub_mode CGLOB; +#else +#define exestub_mode 0 +#endif +LTAB *loc_tab CGLOB; +GTAB *glb_tab CGLOB; +XTAB *ext_tab CGLOB; +LTAB *exp_tab CGLOB; // warning : the content is the exported label (but not the offset) +FUNC *rom_funcs CGLOB; +#ifdef RAM_CALLS +FUNC *ram_funcs CGLOB; +#endif +RTYPE reloc_tab CGLOBL,bss_tab CGLOBL; +HTABLE alsyms CGLOBL; +TABLE libsyms CGLOBL; // (FUNC *)sym->value.i + +#ifdef SIZE_STATS +xstatic unsigned int c_compiler_sz CGLOB; +#endif + +#ifdef MC680X0 +/* variable initialization */ +enum e_gt { + nogen, bytegen, wordgen, longgen, floatgen +}; +enum e_sg { + noseg, codeseg, dataseg +}; + + +char *outlate(); +#ifndef NOFLOAT +#ifdef PC +unsigned long double2ffp(); +#else +#define double2ffp(__x) (__x) +#endif +#endif +void wrt2(short x); +void set_label(int lab,unsigned int pos); +unsigned int lab_src(int n); +void put_label(int lab); +void put_align2(void); + +enum(e_gt) gentype; +enum(e_sg) curseg; +int outcol; + +#define BIN_STEP 128 + +void out_init() { +// fputs("gtc_compiled:\n", output); + curseg = noseg; + gentype = nogen; + outcol = 0; + lc_stk = 0; + odd = 0; + extlabel = -1; + glblabel = -32768; + scope_head = 0; + pos = 4; + hashinit(&alsyms); + reloc_tab.r = 0; + bss_tab.r = 0; + libsyms.tail = libsyms.head = 0; + rom_funcs = 0; +#ifdef RAM_CALLS + ram_funcs = 0; +#endif + loc_tab = 0; + glb_tab = 0; + ext_tab = 0; + nostub_mode = 0; +#ifdef EXE_OUT + exestub_mode = 0; +#endif + bin = malloc(bin_size = BIN_STEP); + pos = 4; + put_label(label("gtc_compiled")); +#ifdef SIZE_STATS + c_compiler_sz=0; +#endif +} + +char *unres_name(int lab) { + SYM *ttail; int crc=N_HASH;; + while (crc--) { + ttail=alsyms.h[crc].tail; + while (ttail) { + if ((short)ttail->value.splab==(short)lab) + return ttail->name; + ttail = ttail->prev; + } + } + return 0; +} +void scan_unresolved() { + GTAB *t=glb_tab; int l=0x8000; + while (t) { + REF **r=t->r; int n; + n=N_TAB; + while (n--) { + if (*r++) + uerrc2("unresolved symbol '%s'",unres_name(l)); + l++; + } + t=t->nxt; + } +} + +int eval_rt(RTYPE *r) { + int n=1; + REF *p=r->r0,*q=r->r; + while (p!=q) + n+=N_REF,p=p->nxt; + if (p) { + unsigned int *a=p->r; + while (*a++) n++; + } + return n; +} +unsigned int eval_functab(FUNC *f) { + int n=1; + while (f) + n+=1+eval_rt(&f->rt),f=f->nxt; + return n+n; +} +unsigned int eval_libs() { + int n=2; + SYM *sp=libsyms.head; + while (sp) + n+=10+eval_functab((FUNC *)sp->value.i),sp=sp->next; +// return 2; + return n; +} +unsigned int eval_export() { + int i=N_TAB,n=i; + int *a; + if (!exp_tab) + return 0; + a=exp_tab->t; + while (i--) + if (*a++) n=i; + return (1+N_TAB-n)<<1; +} + +#ifdef PC +xstatic unsigned char *hdr CGLOB,*hdrp CGLOB; +#else +xstatic unsigned short *hdr CGLOB,*hdrp CGLOB; +#endif +xstatic short hshift CGLOB; +#ifdef PC +void _wri(unsigned short x) { + unsigned char hi=(char)(x>>8),lo=(char)x; + *hdrp++=hi; + *hdrp++=lo; +} +void _ovwri(unsigned int i,unsigned short x) { + unsigned char hi=(char)(x>>8),lo=(char)x; + if (i&1) fatal("ODD OVWRI"); + hdr[i+0]=hi; + hdr[i+1]=lo; +} +void _orwri(unsigned int i,unsigned short x) { + unsigned char hi=(char)(x>>8),lo=(char)x; + if (i&1) fatal("ODD ORWRI"); + hdr[i+0]|=hi; + hdr[i+1]|=lo; +} +#define wri(x) (_wri((unsigned short)(x))) +#define ovwri(i,x) (_ovwri(i,(unsigned short)(x))) +#define orwri(i,x) (_orwri(i,(unsigned short)(x))) +#else +#define wri(x) (*hdrp++=x) +#define ovwri(i,x) (*(unsigned short *)((char *)hdr+i)=x) +#define orwri(i,x) (*(unsigned short *)((char *)hdr+i)|=x) +#endif +void write_rt(RTYPE *r) { + REF *p=r->r0; + while (p) { + unsigned int x,*a=p->r; int n; + if ((p=p->nxt)) { + n=N_REF; while (n--) wri((*a++)+hshift); + } else + while ((x=*a++)) wri(x+hshift); + } + wri(0); +} +void write_reloc( +#ifdef OBJ_OUT + int directly_to_bin +#else + #define directly_to_bin 0 +#endif + ) { + RTYPE *r=&reloc_tab; + REF *p=r->r0; + while (p) { + unsigned int x,*a=p->r; int n; + if ((p=p->nxt)) { + n=N_REF; while (n--) { + x=*a++; + directly_to_bin?wrt2(x+hshift+2):wri(x+hshift); + #ifdef PC + { short a=bin[x+2]<<8; + a+=bin[x+3]+hshift; /* logically, shouldn't overflow... */ + bin[x+2]=(unsigned char)(a>>8); + bin[x+3]=(unsigned char)(a); + } + #else + *(long *)(bin+x)+=hshift; + #endif + } + } else + while ((x=*a++)) { + #ifdef PC + { short a=bin[x+2]<<8; + a+=bin[x+3]+hshift; /* logically, shouldn't overflow... */ + bin[x+2]=(unsigned char)(a>>8); + bin[x+3]=(unsigned char)(a); + } + #else + *(long *)(bin+x)+=hshift; + #endif + directly_to_bin?wrt2(x+hshift+2):wri(x+hshift); + } + } + directly_to_bin?wrt2(0):wri(0); +} +#undef directly_to_bin +void write_functab(FUNC *f0) { + int n=0; FUNC *f=f0; + while (f) + n++,f=f->nxt; + wri(n-1); + f=f0; + while (f) + wri(f->f),write_rt(&f->rt),f=f->nxt; +} +void write_libs() { + int n=0; + SYM *sp=libsyms.head; +// wri(0); return; + while (sp) + n++,sp=sp->next; + wri(n); + sp=libsyms.head; + while (sp) { + memset(hdrp,0,8); + strcpy((char *)hdrp,sp->name); + hdrp+=8/sizeof(*hdrp); + wri(0); + sp=sp->next; + } + sp=libsyms.head; + while (sp) + write_functab((FUNC *)sp->value.i),sp=sp->next; +} +unsigned int qlab_src(int n); +void write_export(unsigned int l) { + int *a=exp_tab->t,x; + l=(l>>1)-1; + wri((short)l); + while (l--) { + if ((x=*a++)) + x=qlab_src(x)+hshift; + wri(x); + } +} + +#ifdef EXE_OUT +typedef struct { + short t; // type + unsigned short loc; // location, offset based on relocated output +} EXE_ITEM; +int +#ifdef PC +#ifdef _MSC_VER +__cdecl +#endif +#else +CALLBACK +#endif +exe_compare(const void *a,const void *b) { + return ((EXE_ITEM *)a)->loc-((EXE_ITEM *)b)->loc; +} +void *GTPackDo(void *buf,unsigned int *buflen); +#include "out68k_exe.h" +#endif + +readonly char pgm_init[0x1A]={0x61,0,0,0,'6','8','k','P'}; +readonly char lib_init[0x1A]={0x4E,0x75,0x4E,0x75,'6','8','k','L'}; +readonly char pgm_stub[0xA]={0x2F,0x38,0x00,0x34,0x66,0x02,0x50,(char)0x8F,0x4E,0x75}; +void wrt2(short x); +void wrt1(char x); +void out_close() { +#ifdef PC + int calctype_used[]={0,0,0}; + char *calc_symbols[]={"USE_TI89","USE_TI92PLUS","USE_V200"}; + int calc,specific=1,something; + for (something=0;!something;specific=0) + for (calc=0;calc<3;calc++) + if (!specific || search(calc_symbols[calc],-1,&defsyms)) + calctype_used[calc]++,something++; +#endif + if (bin) { + /* + * 0x1A+(2+10*nLibs+2*(nLibs+nLibCalls+nLibFuncs))+(2+2+2*(nRomFuncs+nRomCalls)) + * +2+2+(4+nBSS*2)+(2+nExport*2) + * +0xA+(nReloc+1)*2 + * = + * 0x1A+(2+10*nLibs+nLibs(eval(Lib)))+(2+eval(rom)) + * +2+2+(4+nBSS*2)+(2+nExport*2) + * +0xA+eval_rt(reloc_tab)*2 + * = + * 0x1A+(2+eval_libs())+(2+eval(rom)) + * +2+2+(4+nBSS*2)+(2+nExport*2) + * +0xA+eval_rt(reloc_tab)*2 + */ + SYM *mainsym; + unsigned int rom=eval_functab(rom_funcs)-2,lib=eval_export(); +#ifdef RAM_CALLS + unsigned int ram=eval_functab(ram_funcs)-2; +#else +#define ram 0 +#endif +#ifdef OBJ_OUT + int object=!!search("_GENERIC_ARCHIVE",-1,&defsyms); + if (!object) { +#endif + int nostub=search("_nostub",-1,&alsyms) || search("_nostub",-1,&gsyms) + || search("_nostub",-1,&defsyms) || nostub_mode; +#ifdef EXE_OUT + int exestub=!!search("EXE_OUT",-1,&defsyms); + if (exestub) nostub=0; +#else +#define exestub 0 +#endif + debug('+'); + if (nostub) { + if (ram || rom) fatal("RAM/ROM_CALL in _nostub"); + if (libsyms.head) fatal("Libraries in _nostub"); + if (bss_tab.r) fatal("BSS in _nostub"); + hshift=0; +#ifdef EXE_OUT + } else if (exestub) { + if (ram) fatal("RAM_CALL in EXE format"); + if (libsyms.head) fatal("Libraries in exe format"); +#endif + } else { + hdrp=hdr=malloc((hshift=0x1A-4+(eval_libs())+(rom?rom+4:2) + +(ram?ram+4:2)+(eval_rt(&reloc_tab)<<1)+(bss_tab.r?4+(eval_rt(&bss_tab)<<1):0) + +(lib)+(lib?0:0xA))+4); + if (!hdr) + fatal("memory"); + memcpy(hdr,lib?lib_init:pgm_init,0x1A); + hdrp+=0x1A/sizeof(*hdrp); + write_libs(); // import table + wri(rom); // ROM table + if (rom) write_functab(rom_funcs); + #ifdef RAM_CALLS + wri(ram); // RAM table + if (ram) write_functab(ram_funcs); + #else + wri(0); // no RAM table + #endif + #ifdef OBJ_OUT + write_reloc(0); // reloc table + #else + write_reloc(); // reloc table + #endif + if (bss_tab.r) { + ovwri(0x14,(char *)hdrp-(char *)hdr); // BSS table + wri(lc_bss>>16),wri(lc_bss); + write_rt(&bss_tab); + } + if (lib) { + ovwri(0x16,(char *)hdrp-(char *)hdr); // export table + write_export(lib); + } + if (!lib) { + ovwri(0x02,(char *)hdrp-(char *)hdr-2); // stub + memcpy(hdrp,pgm_stub,0xA); + hdrp+=0xA/sizeof(*hdrp); + } + #ifdef PC + if (hdrp!=hdr+(hshift+4)/sizeof(*hdrp)) + ierr(LINK_MISPL,1); + #endif + /* link with file */ + if ((mainsym=search("VERSION",-1,&defsyms))) { + + ovwri(0x10,1<<8); + } + } + mainsym=NULL; + if (!lib && ((!nostub && !exestub) || !search("NO_MAIN",-1,&defsyms))) { + if (!(mainsym=search("_main",-1,&alsyms)) && !(mainsym=search("__main",-1,&alsyms))) + fatal("_main not found"); + if (!nostub && !exestub) { + ovwri(0x0C,qlab_src(mainsym->value.splab)+hshift); + if (!!search("NO_SCREEN",-1,&defsyms)) + orwri(0x10,(1<<2)); + } + } + scan_unresolved(); + + /* finally, write the output to the file */ + if (nostub) { + if (!mainsym) + memmove(bin,bin+4,pos-4),pos-=4,hshift=-4; + else { + #ifdef PC + bin[0]=0x60,bin[1]=0x00; + bin[2]=(unsigned char)((qlab_src(mainsym->value.splab)-2)>>8); + bin[3]=(unsigned char)((qlab_src(mainsym->value.splab)-2)); + #else + *(short *)bin=0x6000; + *(short *)(bin+2)=qlab_src(mainsym->value.splab)-2; + #endif + hshift=0; + } + put_align2(); + wrt2(0); + { + RTYPE *r=&reloc_tab; + REF *p=r->r0; + while (p) { + unsigned int x,*a=p->r; int n; + if ((p=p->nxt)) { + n=N_REF; while (n--) { + #ifdef PC + { short z=bin[(x=*a++)+2+hshift]<<8; + z+=bin[x+3+hshift]+hshift; + wrt2(z); + } + #else + wrt2(*(unsigned short *)(bin+(x=*a++)+2+hshift)+hshift); + #endif + if (*(unsigned short *)(bin+x+hshift)!=0) + uerrc("invalid _nostub relocation"); + *(unsigned short *)(bin+x+2+hshift)=0; + wrt2((unsigned short)(x+hshift)); + } + } else + while ((x=*a++)) { + #ifdef PC + { short z=bin[x+2+hshift]<<8; + z+=bin[x+3+hshift]+hshift; + wrt2(z); + } + #else + wrt2(*(unsigned short *)(bin+x+2+hshift)+hshift); + #endif + if (*(unsigned short *)(bin+x+hshift)!=0) + uerrc("invalid _nostub relocation"); + *(unsigned short *)(bin+x+2+hshift)=0; + wrt2((unsigned short)(x+hshift)); + } + } + } + wrt1((char)0xF3); + rel_global(); + #ifndef PC + fwrite(bin,1,pos,output); + #endif +#ifdef EXE_OUT + } else if (exestub) { +#ifdef TWIN_COMPILE + if (twinc_necessary) { + rel_global(); + goto close_it; // don't lose time compressing... + } else { +#endif + #define EXE_END -1 + #define EXE_PROGRELOC 0 + #define EXE_BSSRELOC 1 + #define EXE_ROMRELOC 2 + #define EXE_ROMRELOC_NOJSR (0x100|EXE_ROMRELOC) + EXE_ITEM *exe_data=calloc(6000,sizeof(EXE_ITEM)); /* 12 kb */ + EXE_ITEM *exe_ptr=exe_data; + int exe_num; + if (!exe_data) + fatal("Memory"); + memmove(bin,bin+4,pos-4),pos-=4; + { + RTYPE *r=&reloc_tab; + REF *p=r->r0; + while (p) { + unsigned int x,*a=p->r; int n; + if ((p=p->nxt)) { + n=N_REF; while (n--) { + exe_ptr->t=EXE_PROGRELOC; + exe_ptr->loc=(*a++)-4; + exe_ptr++; + } + } else + while ((x=*a++)) { + exe_ptr->t=EXE_PROGRELOC; + exe_ptr->loc=x-4; + exe_ptr++; + } + } + } + { + FUNC *f=rom_funcs; + while (f) { + RTYPE *r=&f->rt; + REF *p=r->r0; + while (p) { + unsigned int x,*a=p->r; int n; + if ((p=p->nxt)) { + n=N_REF; while (n--) { + exe_ptr->t=EXE_ROMRELOC; + exe_ptr->loc=(*a++)-4; + if (*(long *)(bin+exe_ptr->loc)) + fatal("Invalid ROM_CALL"); + bin[exe_ptr->loc+2]=f->f>>8; + bin[exe_ptr->loc+3]=f->f&255; + if (bin[exe_ptr->loc-2]==0x4e + && bin[exe_ptr->loc-1]==0xb9) + exe_ptr->loc-=2; + else bin[exe_ptr->loc+2]|=0x80,exe_ptr->t=EXE_ROMRELOC_NOJSR; + exe_ptr++; + } + } else + while ((x=*a++)) { + exe_ptr->t=EXE_ROMRELOC; + exe_ptr->loc=x-4; + if (*(long *)(bin+exe_ptr->loc)) + fatal("Invalid ROM_CALL"); + bin[exe_ptr->loc+2]=f->f>>8; + bin[exe_ptr->loc+3]=f->f&255; + if (bin[exe_ptr->loc-2]==0x4e + && bin[exe_ptr->loc-1]==0xb9) + exe_ptr->loc-=2; + else bin[exe_ptr->loc+2]|=0x80,exe_ptr->t=EXE_ROMRELOC_NOJSR; + exe_ptr++; + } + } + f=f->nxt; + } + } + exe_ptr->t=-1; exe_ptr->loc=pos; exe_ptr++; + exe_num=exe_ptr-exe_data; + qsort(exe_data,exe_num,sizeof(EXE_ITEM),exe_compare); + { + long relocated_size; + unsigned short last_pos=0; unsigned char *ptr=bin,*out=bin; + char *reloc_ptr=(char *)exe_data,*last_esc=NULL; + int last_esc_num=0; + int i=exe_num; exe_ptr=exe_data; + while (i--) { + unsigned char *dest_ptr=bin+exe_ptr->loc; + unsigned short delta; short type; +#ifdef PC +#define g16(p) (p+=2,(p[-2]<<8)+p[-1]) +#define rd16(p) ((p[0]<<8)+p[1]) +#define w16(p,v) (*p++=(v)>>8,*p++=(v)&255,(void)0) +#else +#define g16(p) (*((int *)p)++) +#define rd16(p) (*((int *)p)) +#define w16(p,v) (g16(p)=(v)) +#endif + while (ptr=dest_ptr) break; + w16(out,rd16(ptr)+((char *)ptr-(char *)bin)); + ptr+=2; + } + } + delta=(exe_ptr->loc-last_pos)+2; + last_pos=exe_ptr->loc; + if ((delta&1)) + uerrc("invalid relocation offset"); + delta>>=1; + switch ((type=exe_ptr->t)) { // we *NEED* to save exe_ptr->t as it will be lost + case EXE_PROGRELOC: + if (g16(ptr)) + uerrc("invalid _nostub relocation"); + w16(out,rd16(ptr)-4); // parameters to w16 can't have side-fx... + ptr+=2; + last_pos+=4; + break; + case EXE_ROMRELOC: + ptr+=4; + w16(out,rd16(ptr)); // parameters to w16 can't have side-fx... + ptr+=2; + last_pos+=6; + break; + case EXE_ROMRELOC_NOJSR: + ptr+=2; + w16(out,rd16(ptr)); // parameters to w16 can't have side-fx... + ptr+=2; + last_pos+=4; + break; + } + if (delta<128) + *reloc_ptr++=delta&255; + else *reloc_ptr++=128|(delta>>8),*reloc_ptr++=delta&255; + if (!last_esc_num--) + last_esc=reloc_ptr,*reloc_ptr++=0,last_esc_num=3; + if (type IS_INVALID) { + *reloc_ptr++=0; + break; + } + (*last_esc)|=type<<(last_esc_num<<1); + exe_ptr++; + } + rel_global(); + exe_num=reloc_ptr-(char*)exe_data; + *reloc_ptr=0; /* (same remark as below...) */ + reloc_ptr=realloc(exe_data,exe_num+1); /* we don't know if we will need padding... */ + relocated_size=pos; + pos=out-bin; + bin=realloc(bin,pos); +#if 0 + { + unsigned int i; + for (i=0; i>8,header[3]=loader_offset&255; + *(long *)(header+4)=0; + } else { + #ifdef PC + const unsigned char header32[8]= + #else + memcpy(header,(char[]) + #endif + {0x41,0xFA,0x7F,0xF2,0x4E,0xE8,0x80,0x0C} + #ifdef PC + ; memcpy(header,header32, 8); + #else + , 8); + #endif + loader_offset+=(0x800C-2); + header[6]=loader_offset>>8,header[7]=loader_offset&255; + loader_offset-=(0x800C-2); // restore it for future use + } + bin=realloc(bin,8+12+pos+exe_num+(bss_tab.r?exeloadersize_bss:exeloadersize_nobss)); + if (!bin) + fatal("Memory"); + memmove(bin+8+12,bin,pos); + memcpy(bin,header,8); + exe_hdr[2]=pos>>8,exe_hdr[3]=pos&255; + exe_hdr[5]=(char)((relocated_size>>16)&255), + exe_hdr[6]=(char)((relocated_size>>8)&255), + exe_hdr[7]=(char)(relocated_size&255); + if (bss_tab.r) + fatal("BSS in exes are not implemented"); + memcpy(bin+8,exe_hdr,12); + memcpy(bin+8+12+pos,reloc_ptr,exe_num); + free(reloc_ptr); + memcpy(bin+8+12+pos+exe_num,bss_tab.r?exeloader_bss:exeloader_nobss, + bss_tab.r?exeloadersize_bss:exeloadersize_nobss); +#ifdef PC + if (verbose) { + msg2("RAM required during execution : %5u bytes\n",(unsigned int)relocated_size); + msg2("Memory required for EXE program : %5u bytes\n",8+12+pos+exe_num); + msg2("Memory required for EXE loader : %5u bytes\n",bss_tab.r?exeloadersize_bss:exeloadersize_nobss); + } +#endif + pos=8+12+pos+exe_num+(bss_tab.r?exeloadersize_bss:exeloadersize_nobss); + bin[pos-3]=(loader_offset+22+2)>>8,bin[pos-2]=(loader_offset+22+2)&255; +#ifdef PC + if (verbose) + msg2("Total program size : %5u bytes\n",pos); +#endif + } + } + #ifndef PC + fwrite(bin,1,pos,output); + #endif +#ifdef TWIN_COMPILE + } +#endif +#endif + } else { + rel_global(); + put_align2(); + wrt2(0); + wrt1((char)0xF3); + #ifdef PC + if (!(bin=realloc(bin,bin_size+=hshift))) + fatal("Memory"); + memmove(bin+hshift+4,bin+4,pos-4); + memcpy(bin,hdr,hshift+4); + pos+=hshift; + #else + fwrite(hdr,1,hshift+4,output); + fwrite(bin+4,1,pos-4,output); + #endif + free(hdr); + } +#ifdef OBJ_OUT + } else { + unsigned int len; + int j; + if (pos&1) + wrt1(0); + len=pos-4; + + /* reloc table */ + hshift=-4; + write_reloc(1); + + /* export table */ + j=N_HASH; + while (j--) { + SYM *sp = gsyms.h[j].head; + while (sp) { + if ((sp->storage_class == sc_external && sp->used) || + (sp->storage_class == sc_global && sp->value.splab)) { +#ifdef PC + if (!lab_src(sp->value.splab)) + fatal("UNDEF LABEL"); // should this happen ? +#endif + wrt2(lab_src(sp->value.splab)-2/*fix offset for object format*/); + } + sp = sp->next; + } + } + wrt2(0); + j=N_HASH; + while (j--) { + SYM *sp = gsyms.h[j].head; + while (sp) { + if ((sp->storage_class == sc_external && sp->used) || + (sp->storage_class == sc_global && sp->value.i != -1)) { + char *s=sp->name; + do + wrt1(*s); + while (*s++); + } + sp = sp->next; + } + } + if (pos&1) + wrt1(0); + + /* import table */ + { + GTAB *t=glb_tab; + while (t) { + REF **r=t->r; int m=N_TAB; + while (m--) { + REF *q; + if ((q=*r++)) { + while (q) { + unsigned int p,*a=q->r; + int n=N_REF; + while (n--) { + if (!(p=*a++)) + goto ref_done; + if (p&1) + fatal("Negative reloc in object output"); + // warning, this is a 16-bit reloc, but we have to store it as a 32-bit one + #define offs_convert(p) (p-2/*since 16->32 bit*/-4/*convert bin[] offsets to final object offsets*/) + if (!offs_convert(p)) + fatal("Word reloc at beginning"); + wrt2(offs_convert(p)); + #undef offs_convert + } + q=q->nxt; + } + ref_done: + wrt2(0); + } + } + t=t->nxt; + } + } + wrt2(0); + { + GTAB *t=glb_tab; int l=0x8000; + while (t) { + REF **r=t->r; int m=N_TAB; + while (m--) { + if (*r++) { + char *s=unres_name(l); + do + wrt1(*s); + while (*s++); + } + l++; + } + t=t->nxt; + } + } + if (pos&1) + wrt1(0); + wrt2(0); // leave space for future BSS extension + hdr=bin; // hack pawa =) + ovwri(0x0,pos-4); + ovwri(0x2,len+2); + #ifndef PC + wrt1(0); + wrt1('E'); + wrt1('X'); + wrt1('T'); + wrt1(0); + wrt1(0xF8); + fwrite(bin,1,pos,output); + #endif + } +#endif + #ifdef PC + { +#ifdef OBJ_OUT + if (!object) { +#endif + char *extensions[]={".89z",".9xz",".v2z"}; + for (calc=0;calc<3;calc++) { + if (calctype_used[calc]) { + unsigned int tifilelen; + extern char *calcfolder; + char *tifile=create_ti_file(calc,0x21,calcname,calcfolder,bin,pos,&tifilelen); + char *buffer; FILE *fp; + buffer=alloca(strlen(outputname)+strlen(extensions[calc])+1); + strcpy(buffer,outputname); + strcat(buffer,extensions[calc]); + if (!(fp=fopen(buffer,"wb"))) + fatal("Could not open output file."); + fwrite(tifile,1,tifilelen,fp); + free(tifile); + fclose(fp); + } + } +#ifdef OBJ_OUT + } else { + char buffer[100]; FILE *fp; + strcpy(buffer,calcname); + strcat(buffer,".ext"); + if (!(fp=fopen(buffer,"wb"))) + fatal("Could not open output file."); + fwrite(bin,1,pos,fp); + fclose(fp); + } +#endif + } + #endif + #ifdef TWIN_COMPILE + close_it: + #endif + free(bin); + bin=0; + } +} + +void bin_chk(unsigned int pos) { + while (bin_size>N_TAB_LOG; + LTAB *p=local(n)?loc_tab:(LTAB *)glb_tab,*o; + debugf("lab_set(%x,%x)\n",n,v); + global_flag+=n&0x8000; + if (!p) { + if (local(n)) + loc_tab=p=(LTAB *)xalloc(sizeof(LTAB),_TAB); + else glb_tab=(GTAB *)(p=(LTAB *)xalloc(sizeof(GTAB),_TAB)); + } + while (i--) + if (!(p=(o=p)->nxt)) + o->nxt=p=(LTAB *)xalloc(local(n)?sizeof(LTAB):sizeof(GTAB),_TAB); + global_flag&=0x7FFF; +#ifndef PC + n&=N_TAB-1; + p->t[n]=v; +#else + i=n&(N_TAB-1); + p->t[i]=v; +#endif +} + +#ifdef PC +/* that's what we use if we want the storage to be persistent, even if we call it from a + * temp_mem location + */ +void *xallocnt(int s,int m) { + void *p; + temp_local++; + p=xalloc(s,m); + temp_local--; + return p; +} +/* xallocnt in global mode */ +void *xallocntg(int s,int m) { + void *p; + global_flag++; + p=xallocnt(s,m); + global_flag--; + return p; +} +#else +#define xallocnt(s,m) _xallocnt(s) +void *_xallocnt(int s) { + void *p; + temp_local++; + p=xalloc(s,0); + temp_local--; + return p; +} +#define xallocntg(s,m) _xallocnt(s) +void *_xallocntg(int s) { + void *p; + global_flag++; + p=xallocnt(s,0); + global_flag--; + return p; +} +#endif +unsigned int lab_src(int n) { + int i=(n&0x7FFF)>>N_TAB_LOG; + LTAB *p=local(n)?loc_tab:(LTAB *)glb_tab,*o; + debugfq("lab_src(%x)",n); + global_flag+=n&0x8000; + if (!p) { + if (local(n)) + loc_tab=p=(LTAB *)xallocnt(sizeof(LTAB),_TAB); + else glb_tab=(GTAB *)(p=(LTAB *)xallocntg(sizeof(GTAB),_TAB)); + } + while (i--) + if (!(p=(o=p)->nxt)) + o->nxt=p=(LTAB *)(local(n)?xallocnt(sizeof(LTAB),_TAB):xallocntg(sizeof(GTAB),_TAB)); + global_flag&=0x7FFF; + n&=N_TAB-1; + debugf("=%x\n",p->t[n]); + return p->t[n]; +} + +RTYPE **xt_find(int n) { + int i=(n=(int)((short)~n))>>N_TAB_LOG; + XTAB *p=ext_tab,*o; + global_flag++; + if (!p) + ext_tab=p=(XTAB *)xalloc(sizeof(XTAB),_TAB); + while (i--) + if (!(p=(o=p)->nxt)) + o->nxt=p=(XTAB *)xalloc(sizeof(XTAB),_TAB); + global_flag--; + n&=N_TAB-1; + return &p->t[n]; +} + +int *exp_find(int n) { + int i=n>>N_TAB_LOG; + LTAB *p=exp_tab,*o; + global_flag++; + if (!p) + exp_tab=p=(LTAB *)xalloc(sizeof(LTAB),_TAB); + while (i--) + if (!(p=(o=p)->nxt)) + o->nxt=p=(LTAB *)xalloc(sizeof(LTAB),_TAB); + global_flag--; + n&=N_TAB-1; + return (int *)&p->t[n]; +} + +/*void loc_clear() { + LTAB *p=loc_tab,*o; + while (p) { + memset(p->t,0,sizeof(p->t)); + p=p->nxt; + } +}*/ + +unsigned int qlab_src(int n) { + int i=(n&0x7FFF)>>N_TAB_LOG; + LTAB *p=local(n)?loc_tab:(LTAB *)glb_tab; + n&=N_TAB-1; + while (i--) p=p->nxt; + return p->t[n]; +} + +REF *ref_add(REF *r,unsigned int v) { + unsigned int *a; + debugf("ref_add(%lx,%x)\n",r,v); + a=r->r; + while (*a++); + if (a>(unsigned int *)&r->nxt) { + global_flag++; + (r=r->nxt=(REF *)xalloc(sizeof(REF),_REF+REF_ADD))->r[0]=v; + global_flag--; + } else a[-1]=v; + return r; +} + +REF **glb_ref(int n) { + int i=(n&0x7FFF)>>N_TAB_LOG; + GTAB *p=glb_tab; + n&=N_TAB-1; + while (i--) + p=p->nxt; + return &p->r[n]; +} + +void lab_add_ref(int n,unsigned int r) { + int i=(n&0x7FFF)>>N_TAB_LOG; + GTAB *p=glb_tab; REF **ro; + debugf("lab_add_r(%x,%x)\n",n,r); +#ifndef PC +// asm("0: jbra 0b"); +#endif + if (local(n)) + uerrc2("local label not found: '%s'",unres_name(n)); + global_flag++; + n&=N_TAB-1; + while (i--) + p=p->nxt; + ro=&p->r[n]; + if (!*ro) + *ro=(REF *)xalloc(sizeof(REF),_REF+LAB_ADD_REF); + while ((*ro)->nxt) + ro=&(*ro)->nxt; + global_flag--; + ref_add(*ro,r); +} +void rt_add_ref(RTYPE *rt,unsigned int r) { // effectively appends reloc to reloc table + debugf("rt_add_r(%lx,%x)\n",rt,r); + if (!rt->r) { + global_flag++; + rt->r0=rt->r=(REF *)xalloc(sizeof(REF),_REF+RT_ADD_REF); + global_flag--; + } + rt->r=ref_add(rt->r,r); +} +FUNC *func_search(FUNC **f0,unsigned int f) { + while (*f0) + if ((*f0)->f==f) break; + else f0=&(*f0)->nxt; + if (*f0) return *f0; + global_flag++; + *f0=(FUNC *)xalloc(sizeof(FUNC),_RT); + global_flag--; + (*f0)->f=f; + return *f0; +} + +typedef struct gv_ret { + long i; + int ir,xr,tr; // Internal/eXternal/Total Relocation count +} GV; +int get_value(struct enode *ep,GV *r,unsigned int rp,int m) { + int lab; unsigned int p; + r->ir=0; r->xr=0; + gv_restart: + switch (ep->nodetype) { + case en_autocon: + case en_icon: +#ifndef NOFLOAT +#ifndef PC + case en_fcon: +#endif +#endif + r->i=ep->v.i; + r->tr=0; + break; +#ifndef NOFLOAT +#ifdef PC +#ifndef BCDFLT + case en_fcon: + r->i=double2ffp(ep->v.f); + r->tr=0; + break; +#endif +#endif +#endif + case en_labcon: + case en_nacon: + lab=ep->v.enlab; + r->tr=1; + if (global(lab)) { + r->ir=1; + if (!(p=lab_src(lab))) { + if (rp) + lab_add_ref(lab,(rp+2)+m); + r->i=0; + return 1; + } else + r->i=p; + } else { + if (m) uerrc("negative external reference"); + r->i=0,r->xr=1; + if (rp) { + RTYPE *rt=*xt_find(lab); + if (((long)rt)&0x80000000) { // DIRTY, but no hidden bug possible (cf xalloc) + r->i=((long)rt)&0x7FFFFFFF; // BSS ref + rt_add_ref(&bss_tab,rp); + } else rt_add_ref(rt,rp); // lib/ROM ref + } + return 1; + } + break; + case en_add: + case en_sub: + { + GV a,b; + int res=get_value(ep->v.p[0],&a,rp,m); + res|=get_value(ep->v.p[1],&b,rp,ep->nodetype==en_sub?1-m:m); + r->xr=a.xr+b.xr; + r->tr=a.tr+b.tr; + if (ep->nodetype==en_sub) { + if (b.xr) + uerrc("negative external reference"); + r->i=a.i-b.i,r->ir=a.ir-b.ir; + } else + r->i=a.i+b.i,r->ir=a.ir+b.ir; + return res; + } + break; + case en_uminus: + m=1-m; + ep=ep->v.p[0]; + goto gv_restart; + default: + uerrc("invalid expression"); + } + return 0; +} +int involved_lab(struct enode *ep) { + gv_restart: + switch (ep->nodetype) { + case en_autocon: + case en_icon: +#ifndef NOFLOAT +#ifdef PC + case en_fcon: +#endif +#endif + return -1; + case en_labcon: + case en_nacon: + return ep->v.enlab; + case en_add: + case en_sub: + return max(involved_lab(ep->v.p[0]),involved_lab(ep->v.p[1])); + case en_uminus: + ep=ep->v.p[0]; + goto gv_restart; + default: + uerrc("invalid expression"); + } + return -1; +} + +xstatic int rel CGLOB, is_long CGLOB; +long get_long(struct enode *ep,unsigned int rp) { + GV v; + get_value(ep,&v,rp,0); + if (v.ir) { + rt_add_ref(&reloc_tab,rp); + if (v.ir!=1) + uerr(ERRA_INVALIDREL); + } + rel=v.ir+v.xr; + return v.i; +} +short get_pcword(struct enode *ep,unsigned int rp) { + GV v; + int no_check=get_value(ep,&v,rp-2,0); + if (v.ir!=1 || v.xr) + uerr(ERRA_INVALIDREL); + if (!no_check) { + v.i -= rp; + if (v.i>32767L || v.i<-32768L) +#ifdef TWIN_COMPILE + { + if (!twinc_necessary) uwarn("twin compilation required"); + twinc_necessary=1; + *twinc_info++=involved_lab(ep); + *twinc_info++=rp; + } +#else + uerrc("PC-relative mode not allowed here"); +#endif +// v.i += rp; + return (short)v.i; + } else + return (short)v.i-(short)rp; +} +short get_word(struct enode *ep,unsigned int rp,int sign) { + GV v; + int no_check=get_value(ep,&v,rp-2,0); + if (v.ir || v.xr) + uerr(ERRA_INVALIDREL); + /* otherwise this would bug with myval&0xFFFF7FFF which is converted to and.w */ + if (!no_check && (v.i>(sign?32767L:65535L) || v.i<(sign?-32768L:-65535L))) +// if (!no_check && (v.i>(sign?32767L:65535L) || v.i<-32768L)) + uerrc("value can't fit in a word"); + return (short)v.i; +} +long get_offs(struct enode *ep,unsigned int rp) { + GV v; int l=0; + get_value(ep,&v,0,0); + if (v.ir || v.xr) + l=1; + if (v.i>32767L || v.i<-32768L) + l=1; + if ((is_long=l)) + return get_long(ep,rp); + else return get_word(ep,rp,1); +} +unsigned char get_byte(struct enode *ep) { + GV v; + get_value(ep,&v,0,0); + if (v.tr) + uerr(ERRA_INVALIDREL); + if ((unsigned long)(((unsigned long)v.i)+128)>255) + uerrc("value can't fit in a byte"); + return (unsigned char)v.i; +} +unsigned short get_quick(struct enode *ep) { + GV v; + get_value(ep,&v,0,0); + if (v.tr) + uerr(ERRA_INVALIDREL); + if ((unsigned long)(((unsigned long)v.i)-1)>=8) + uerrc("value can't fit in a quick constant"); + if (v.i==8) + v.i=0; + return (unsigned short)v.i; +} + +enum { + oi_move=1, + oi_moveq=oi_move+8, + oi_clr=oi_moveq+1, + oi_lea=oi_clr+1, + oi_add=oi_lea+1, + oi_addi=oi_add+4, + oi_addq=oi_addi+1, + oi_sub=oi_addq+1, + oi_subi=oi_sub+4, + oi_subq=oi_subi+1, + oi_muls=oi_subq+1, + oi_mulu=oi_muls+1, + oi_divs=oi_mulu+1, + oi_divu=oi_divs+1, + oi_and=oi_divu+1, + oi_andi=oi_and+3, + oi_or=oi_andi+1, + oi_ori=oi_or+3, + oi_eor=oi_ori+1, + oi_eori=oi_eor+2, + oi_lsl=oi_eori+1, + oi_lsr=oi_lsl+3, + oi_jmp=oi_lsr+3, + oi_jsr=oi_jmp+1, + oi_movem=oi_jsr+1, + oi_rts=oi_movem+3, + oi_bra=oi_rts+1, + oi_bsr=oi_bra+1, + oi_beq=oi_bsr+1, + oi_bne=oi_beq+1, + oi_bhs=oi_bne+1, + oi_bge=oi_bhs+1, + oi_bhi=oi_bge+1, + oi_bgt=oi_bhi+1, + oi_bls=oi_bgt+1, + oi_ble=oi_bls+1, + oi_blo=oi_ble+1, + oi_blt=oi_blo+1, + oi_tst=oi_blt+1, + oi_ext=oi_tst+1, + oi_swap=oi_ext+1, + oi_neg=oi_swap+1, + oi_not=oi_neg+1, + oi_cmp=oi_not+1, + oi_link=oi_cmp+5, + oi_unlk=oi_link+1, + oi_label=oi_unlk+1, + oi_pea=oi_label+0, + oi_cmpi=oi_pea+1, + oi_dbra=oi_cmpi+1, + oi_asr=oi_dbra+1, + oi_bset=oi_asr+3, + oi_bclr=oi_bset+4, + oi_bchg=oi_bclr+4, + _oi_asm=oi_bchg+4, + _oi_adj=_oi_asm+0, +#ifndef ASM + __oi_end=_oi_adj+0 +#endif +#ifdef ASM + /* ASM-only */ + oi_asl=_oi_adj+0, + oi_rol=oi_asl+3, + oi_ror=oi_rol+3, + oi_roxl=oi_ror+3, + oi_roxr=oi_roxl+3, + oi_btst=oi_roxr+3, + oi_exg=oi_btst+4, + oi_dc=oi_exg+4, + oi_ds=oi_dc+1, + oi_dcb=oi_ds+1, + oi_bvs=oi_dcb+1, + oi_bvc=oi_bvs+1, + oi_bpl=oi_bvc+1, + oi_bmi=oi_bpl+1, + oi_trap=oi_bmi+1, + oi_negx=oi_trap+1, + oi_addx=oi_negx+1, + oi_subx=oi_addx+2, + oi_chk=oi_subx+2, + oi_even=oi_chk+1, + oi_dbeq=oi_even+1, + oi_dbne=oi_dbeq+1, +#ifndef LIGHT_DBXX_AND_SXX + oi_dbhs=oi_dbne+1, + oi_dbge=oi_dbhs+1, + oi_dbhi=oi_dbge+1, + oi_dbgt=oi_dbhi+1, + oi_dbls=oi_dbgt+1, + oi_dble=oi_dbls+1, + oi_dblo=oi_dble+1, + oi_dblt=oi_dblo+1, + oi_dbvs=oi_dblt+1, + oi_dbvc=oi_dbvs+1, + oi_dbpl=oi_dbvc+1, + oi_dbmi=oi_dbpl+1, + oi_st=oi_dbmi+1, + oi_sf=oi_st+1, + oi_seq=oi_sf+1, + oi_sne=oi_seq+1, + oi_shs=oi_sne+1, + oi_sge=oi_shs+1, + oi_shi=oi_sge+1, + oi_sgt=oi_shi+1, + oi_sls=oi_sgt+1, + oi_sle=oi_sls+1, + oi_slo=oi_sle+1, + oi_slt=oi_slo+1, + oi_svs=oi_slt+1, + oi_svc=oi_svs+1, + oi_spl=oi_svc+1, + oi_smi=oi_spl+1, + oi_tas=oi_smi+1, + __oi_end=oi_tas+1 +#else + __oi_end=oi_dbne+1 +#endif +#endif +}; + +readonly unsigned char opi[_op_max+2]={ + oi_move, oi_moveq, oi_clr, oi_lea, oi_add, oi_addi, oi_addq, oi_sub, oi_subi, oi_subq, + oi_muls, oi_mulu, oi_divs, oi_divu, oi_and, oi_andi, oi_or, oi_ori, oi_eor, oi_eori, + oi_lsl, oi_lsr, oi_jmp, oi_jsr, oi_movem, + oi_rts, oi_bra, oi_bsr, oi_beq, oi_bne, oi_bhs, oi_bge, oi_bhi, + oi_bgt, oi_bls, oi_ble, oi_blo, oi_blt, oi_tst, oi_ext, oi_swap, oi_neg, oi_not, oi_cmp, + oi_link, oi_unlk, oi_label, oi_pea, oi_cmpi, oi_dbra, oi_asr, + oi_bset, oi_bclr, oi_bchg, _oi_asm, _oi_adj, +#ifdef ASM + /* ASM-only */ + oi_asl, oi_rol, oi_ror, oi_roxl, oi_roxr, oi_btst, oi_exg, oi_dc, oi_ds, oi_dcb, + oi_bvs, oi_bvc, oi_bpl, oi_bmi, oi_trap, oi_negx, oi_addx, oi_subx, oi_chk, oi_even, + oi_dbeq, oi_dbne, +#ifndef LIGHT_DBXX_AND_SXX + oi_dbhs, oi_dbge, oi_dbhi, oi_dbgt, oi_dbls, oi_dble, oi_dblo, oi_dblt,/* unsigned, signed */ + oi_dbvs, oi_dbvc, oi_dbpl, oi_dbmi, + oi_st, oi_sf, oi_seq, oi_sne, + oi_shs, oi_sge, oi_shi, oi_sgt, oi_sls, oi_sle, oi_slo, oi_slt, /* unsigned, signed */ + oi_svs, oi_svc, oi_spl, oi_smi, oi_tas, +#endif +#endif + __oi_end +}; + +typedef struct _opcode { + char impl,nargs,model,lenf; + unsigned short bo; + int a1,a2; +} OPCODE; +enum { + M_BASIC, M_BASICSWAPPED, M_BRANCH, M_DC, M_ALIGN +}; +enum { L_0=1<<0, L_1=1<<1, L_2=1<<2, L_4=1<<4 }; +enum { + A_DREG=0x1, + A_AREG=0x2, + A_MEM0=0x4, + A_MEM=0x84, + A_PCR=0x8, + A_IMM=0x10, + A_MASK1=0x20, + A_MASK2=0x40, + A_ADEC=0x80, + D_RAW2=0x0100, // |= %00000000 00000000 +WORD + D_RAW=0x0200, // |= %00000000 00000000 (+DAT) + D_LOW=0x0400, // |= %00000000 dddddddd + D_EA2=0x0800, // |= %0000nnnm mm000000 (+DAT) + D_SZ3=0x3000, // |= %00000000 0S000000 (argument-independent) + D_SZ2=0x1000, // |= %0000000S 00000000 (argument-independent) + D_SZ=0x2000, // |= %00000000 ss000000 (argument-independent) + D_Q=0x4000, // |= %0000qqq0 00000000 + D_EA=0x8000, // |= %00000000 00mmmnnn (+DAT) +}; +#define A_CCR A_MASK1 +#define A_SR A_MASK2 +#define A_USP A_MASK1 +/* we have to implement A_CCR and A_SR like that to avoid the use + * of a longword for flags... */ +#define A_SRC A_DREG|A_AREG|A_MEM|A_PCR|A_IMM +#define A_SRC2 A_DREG|A_MEM|A_PCR|A_IMM +#define A_DST A_DREG|A_AREG|A_MEM +#define A_DST2 A_DREG|A_MEM + +// for each enum(e_op) value : +readonly OPCODE ops[]={ + // op_label + {0}, + // op_move + {1,2,M_BASIC,L_2,0x3000,A_SRC|D_EA,A_DST|D_EA2}, // movea is in fact the same instruction + {1,2,M_BASIC,L_4,0x2000,A_SRC|D_EA,A_DST|D_EA2}, + {1,2,M_BASIC,L_1,0x1000,A_SRC2|D_EA,A_DST2|D_EA2}, // move.b does not accept aregs + {1,2,M_BASIC,L_2,0x44C0,A_SRC2|D_EA,A_CCR}, + {1,2,M_BASIC,L_2,0x46C0,A_SRC2|D_EA,A_SR}, + {1,2,M_BASIC,L_2,0x40C0,A_SR,A_DST2|D_EA}, + {1,2,M_BASIC,L_4,0x4E60,A_AREG|D_LOW,A_USP}, + {1,2,M_BASIC,L_4,0x4E68,A_USP,A_AREG|D_LOW}, + // op_moveq + {1,2,M_BASIC,L_0+L_4,0x7000,A_IMM|D_LOW,A_DREG|D_Q}, + // op_clr + {1,1,M_BASIC,L_1+L_2+L_4,0x4200,A_DST2|D_EA|D_SZ}, + // op_lea + {1,2,M_BASIC,L_0,0x41C0,A_MEM|A_PCR|D_EA,A_AREG|D_Q}, + // op_add + {1,2,M_BASIC,L_1+L_2+L_4,0xD000,A_SRC|D_EA|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0xD100,A_DREG|D_Q|D_SZ,A_MEM|D_EA}, + {1,2,M_BASIC, L_2+L_4,0xD0C0,A_SRC|D_EA|D_SZ2,A_AREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0x0600,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_addi + {1,2,M_BASIC,L_1+L_2+L_4,0x0600,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_addq + {1,2,M_BASIC,L_1+L_2+L_4,0x5000,A_IMM|D_Q|D_SZ,A_DST|D_EA}, + // op_sub + {1,2,M_BASIC,L_1+L_2+L_4,0x9000,A_SRC|D_EA|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0x9100,A_DREG|D_Q|D_SZ,A_MEM|D_EA}, + {1,2,M_BASIC, L_2+L_4,0x90C0,A_SRC|D_EA|D_SZ2,A_AREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0x0400,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_subi + {1,2,M_BASIC,L_1+L_2+L_4,0x0400,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_subq + {1,2,M_BASIC,L_1+L_2+L_4,0x5100,A_IMM|D_Q|D_SZ,A_DST|D_EA}, + // op_muls + {1,2,M_BASIC,L_2,0xC1C0,A_SRC2|D_EA,A_DREG|D_Q}, + // op_mulu + {1,2,M_BASIC,L_2,0xC0C0,A_SRC2|D_EA,A_DREG|D_Q}, + // op_divs + {1,2,M_BASIC,L_2,0x81C0,A_SRC2|D_EA,A_DREG|D_Q}, + // op_divu + {1,2,M_BASIC,L_2,0x80C0,A_SRC2|D_EA,A_DREG|D_Q}, + // op_and + {1,2,M_BASIC,L_1+L_2+L_4,0xC000,A_SRC2|D_EA|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0xC100,A_DREG|D_Q|D_SZ,A_MEM|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0x0200,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_andi + {1,2,M_BASIC,L_1+L_2+L_4,0x0200,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_or + {1,2,M_BASIC,L_1+L_2+L_4,0x8000,A_SRC2|D_EA|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0x8100,A_DREG|D_Q|D_SZ,A_MEM|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0x0000,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_ori + {1,2,M_BASIC,L_1+L_2+L_4,0x0000,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_eor + {1,2,M_BASIC,L_1+L_2+L_4,0xB100,A_DREG|D_Q|D_SZ,A_DST2|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0x0A00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_eori + {1,2,M_BASIC,L_1+L_2+L_4,0x0A00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_lsl + {1,2,M_BASIC,L_1+L_2+L_4,0xE108,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE128,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE3C0,A_MEM|D_EA}, + // op_lsr + {1,2,M_BASIC,L_1+L_2+L_4,0xE008,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE028,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE2C0,A_MEM|D_EA}, + // op_jmp + {1,1,M_BASIC,L_0,0x4EC0,A_MEM|A_PCR|D_EA}, + // op_jsr + {1,1,M_BASIC,L_0,0x4E80,A_MEM|A_PCR|D_EA}, + // op_movem - contains a little hack : default size is .l, so we separe L_4 from L_2. + // Uses M_BASICSWAPPED because when 'uses_link' is set, the link reg needs to be after + // the reg mask. + {1,2,M_BASIC,L_4,0x4880,A_MASK1|D_RAW|D_SZ3,A_MEM|D_EA}, /* LBUG : A_MEM&~POST_I */ + {1,2,M_BASIC,L_2,0x4880,A_MASK1|D_RAW|D_SZ3,A_MEM|D_EA}, /* LBUG : A_MEM&~POST_I */ + {1,2,M_BASICSWAPPED,L_2+L_4,0x4C80,A_MASK2|D_RAW,A_MEM0|D_EA|D_SZ3}, + // op_rts + {1,0,M_BASIC,L_0,0x4E75}, + // op_bra + {1,1,M_BRANCH,L_0+L_1+L_2,0x6000}, + // op_bsr + {1,1,M_BRANCH,L_0+L_1+L_2,0x6100}, + // op_beq + {1,1,M_BRANCH,L_0+L_1+L_2,0x6700}, + // op_bne + {1,1,M_BRANCH,L_0+L_1+L_2,0x6600}, + // op_bhs + {1,1,M_BRANCH,L_0+L_1+L_2,0x6400}, + // op_bge + {1,1,M_BRANCH,L_0+L_1+L_2,0x6C00}, + // op_bhi + {1,1,M_BRANCH,L_0+L_1+L_2,0x6200}, + // op_bgt + {1,1,M_BRANCH,L_0+L_1+L_2,0x6E00}, + // op_bls + {1,1,M_BRANCH,L_0+L_1+L_2,0x6300}, + // op_ble + {1,1,M_BRANCH,L_0+L_1+L_2,0x6F00}, + // op_blo + {1,1,M_BRANCH,L_0+L_1+L_2,0x6500}, + // op_blt + {1,1,M_BRANCH,L_0+L_1+L_2,0x6D00}, + // op_tst + {1,1,M_BASIC,L_1+L_2+L_4,0x4A00,A_DST2|D_EA|D_SZ}, + // op_ext + {1,1,M_BASIC,L_2+L_4,0x4880,A_DREG|D_EA|D_SZ3}, + // op_swap + {1,1,M_BASIC,L_4,0x4840,A_DREG|D_EA}, + // op_neg + {1,1,M_BASIC,L_1+L_2+L_4,0x4400,A_DST2|D_EA|D_SZ}, + // op_not + {1,1,M_BASIC,L_1+L_2+L_4,0x4600,A_DST2|D_EA|D_SZ}, + // op_cmp + {1,2,M_BASIC,L_1+L_2+L_4,0xB000,A_SRC2|D_EA|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC, L_2+L_4,0xB000,A_AREG|D_EA|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC, L_2+L_4,0xB0C0,A_SRC|D_EA|D_SZ2,A_AREG|D_Q}, +/* {1,2,M_BASIC, L_2 ,0xB100,A_SRC2|D_EA|D_SZ,A_AREG|D_Q}, + {1,2,M_BASIC, L_4,0xB1C0,A_SRC2|D_EA|D_SZ,A_AREG|D_Q},*/ + {1,2,M_BASIC,L_1+L_2+L_4,0x0C00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xB108,A_MEM0|D_LOW|D_SZ,A_MEM0|D_Q}, // hum; other modes than A_AINC will generate an internal error (#8451/8452) + // op_link + {1,2,M_BASIC,L_2,0x4E50,A_AREG|D_LOW,A_IMM|D_RAW}, + // op_unlk + {1,1,M_BASIC,L_2,0x4E58,A_AREG|D_LOW}, + // op_pea + {1,1,M_BASIC,L_0,0x4840,A_MEM|A_PCR|D_EA}, + // op_cmpi + {1,2,M_BASIC,L_1+L_2+L_4,0x0C00,A_IMM|D_RAW|D_SZ,A_DST2|D_EA}, + // op_dbra + {1,2,M_BRANCH,L_2,0x51C8,A_DREG|D_LOW}, + // op_asr + {1,2,M_BASIC,L_1+L_2+L_4,0xE000,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE020,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE0C0,A_MEM|D_EA}, + // op_bset + {1,2,M_BASIC,L_0+L_1,0x08C0,A_IMM|D_RAW2,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x08C0,A_IMM|D_RAW2,A_DREG|D_EA}, + {1,2,M_BASIC,L_0+L_1,0x01C0,A_DREG|D_Q,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x01C0,A_DREG|D_Q,A_DREG|D_EA}, + // op_bclr + {1,2,M_BASIC,L_0+L_1,0x0880,A_IMM|D_RAW2,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x0880,A_IMM|D_RAW2,A_DREG|D_EA}, + {1,2,M_BASIC,L_0+L_1,0x0180,A_DREG|D_Q,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x0180,A_DREG|D_Q,A_DREG|D_EA}, + // op_bchg + {1,2,M_BASIC,L_0+L_1,0x0840,A_IMM|D_RAW2,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x0840,A_IMM|D_RAW2,A_DREG|D_EA}, + {1,2,M_BASIC,L_0+L_1,0x0140,A_DREG|D_Q,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x0140,A_DREG|D_Q,A_DREG|D_EA}, +#ifdef ASM + /* ASM-only */ + // op_asl + {1,2,M_BASIC,L_1+L_2+L_4,0xE100,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE120,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE1C0,A_MEM|D_EA}, + // op_rol + {1,2,M_BASIC,L_1+L_2+L_4,0xE118,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE138,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE7C0,A_MEM|D_EA}, + // op_ror + {1,2,M_BASIC,L_1+L_2+L_4,0xE018,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE038,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE6C0,A_MEM|D_EA}, + // op_roxl + {1,2,M_BASIC,L_1+L_2+L_4,0xE110,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE130,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE5C0,A_MEM|D_EA}, + // op_roxr + {1,2,M_BASIC,L_1+L_2+L_4,0xE010,A_IMM|D_Q|D_SZ,A_DREG|D_EA}, + {1,2,M_BASIC,L_1+L_2+L_4,0xE030,A_DREG|D_Q|D_SZ,A_DREG|D_EA}, + {1,1,M_BASIC,L_2,0xE4C0,A_MEM|D_EA}, + // op_btst + {1,2,M_BASIC,L_0+L_1,0x0800,A_IMM|D_RAW2,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x0800,A_IMM|D_RAW2,A_DREG|D_EA}, + {1,2,M_BASIC,L_0+L_1,0x0100,A_DREG|D_Q,A_MEM|D_EA}, + {1,2,M_BASIC,L_0+L_4,0x0100,A_DREG|D_Q,A_DREG|D_EA}, + // op_exg + {1,2,M_BASIC,L_0+L_4,0xC140,A_DREG|D_LOW,A_DREG|D_Q}, + {1,2,M_BASIC,L_0+L_4,0xC148,A_AREG|D_LOW,A_AREG|D_Q}, + {1,2,M_BASIC,L_0+L_4,0xC188,A_AREG|D_LOW,A_DREG|D_Q}, + {1,2,M_BASIC,L_0+L_4,0xC188,A_DREG|D_Q,A_AREG|D_LOW}, + // op_dc + {1,1,M_DC,0,-1}, + // op_ds + {1,1,M_DC,0,0}, + // op_dcb + {1,2,M_DC,0,1}, + // op_bvs + {1,1,M_BRANCH,L_0+L_1+L_2,0x6900}, + // op_bvc + {1,1,M_BRANCH,L_0+L_1+L_2,0x6800}, + // op_bpl + {1,1,M_BRANCH,L_0+L_1+L_2,0x6A00}, + // op_bmi + {1,1,M_BRANCH,L_0+L_1+L_2,0x6B00}, + // op_trap + {1,1,M_BASIC,L_0,0x4E40,A_IMM|D_LOW}, + // op_negx + {1,1,M_BASIC,L_1+L_2+L_4,0x4000,A_DST2|D_EA|D_SZ}, + // op_addx + {1,2,M_BASIC,L_1+L_2+L_4,0xD100,A_DREG|D_LOW|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0xD108,A_ADEC|D_LOW|D_SZ,A_ADEC|D_Q}, + // op_subx + {1,2,M_BASIC,L_1+L_2+L_4,0x9100,A_DREG|D_LOW|D_SZ,A_DREG|D_Q}, + {1,2,M_BASIC,L_1+L_2+L_4,0x9108,A_ADEC|D_LOW|D_SZ,A_ADEC|D_Q}, + // op_chk + {1,2,M_BASIC,L_2,0x4180,A_SRC2|D_EA,A_DREG|D_Q}, + // op_even + {1,0,M_ALIGN,L_0,2}, + // op_dbeq + {1,2,M_BRANCH,L_2,0x57C8,A_DREG|D_LOW}, + // op_dbne + {1,2,M_BRANCH,L_2,0x56C8,A_DREG|D_LOW}, +#ifndef LIGHT_DBXX_AND_SXX + // op_dbhs + {1,2,M_BRANCH,L_2,0x54C8,A_DREG|D_LOW}, + // op_dbge + {1,2,M_BRANCH,L_2,0x5CC8,A_DREG|D_LOW}, + // op_dbhi + {1,2,M_BRANCH,L_2,0x52C8,A_DREG|D_LOW}, + // op_dbgt + {1,2,M_BRANCH,L_2,0x5EC8,A_DREG|D_LOW}, + // op_dbls + {1,2,M_BRANCH,L_2,0x53C8,A_DREG|D_LOW}, + // op_dble + {1,2,M_BRANCH,L_2,0x5FC8,A_DREG|D_LOW}, + // op_dblo + {1,2,M_BRANCH,L_2,0x55C8,A_DREG|D_LOW}, + // op_dblt + {1,2,M_BRANCH,L_2,0x5DC8,A_DREG|D_LOW}, + // op_dbvs + {1,2,M_BRANCH,L_2,0x59C8,A_DREG|D_LOW}, + // op_dbvc + {1,2,M_BRANCH,L_2,0x58C8,A_DREG|D_LOW}, + // op_dbpl + {1,2,M_BRANCH,L_2,0x5AC8,A_DREG|D_LOW}, + // op_dbmi + {1,2,M_BRANCH,L_2,0x5BC8,A_DREG|D_LOW}, + // op_st + {1,1,M_BASIC,L_1,0x50C0,A_DST2|D_EA}, + // op_sf + {1,1,M_BASIC,L_1,0x51C0,A_DST2|D_EA}, + // op_seq + {1,1,M_BASIC,L_1,0x57C0,A_DST2|D_EA}, + // op_sne + {1,1,M_BASIC,L_1,0x56C0,A_DST2|D_EA}, + // op_shs + {1,1,M_BASIC,L_1,0x54C0,A_DST2|D_EA}, + // op_sge + {1,1,M_BASIC,L_1,0x5CC0,A_DST2|D_EA}, + // op_shi + {1,1,M_BASIC,L_1,0x52C0,A_DST2|D_EA}, + // op_sgt + {1,1,M_BASIC,L_1,0x5EC0,A_DST2|D_EA}, + // op_sls + {1,1,M_BASIC,L_1,0x53C0,A_DST2|D_EA}, + // op_sle + {1,1,M_BASIC,L_1,0x5FC0,A_DST2|D_EA}, + // op_slo + {1,1,M_BASIC,L_1,0x55C0,A_DST2|D_EA}, + // op_slt + {1,1,M_BASIC,L_1,0x5DC0,A_DST2|D_EA}, + // op_svs + {1,1,M_BASIC,L_1,0x59C0,A_DST2|D_EA}, + // op_svc + {1,1,M_BASIC,L_1,0x58C0,A_DST2|D_EA}, + // op_spl + {1,1,M_BASIC,L_1,0x5AC0,A_DST2|D_EA}, + // op_smi + {1,1,M_BASIC,L_1,0x5BC0,A_DST2|D_EA}, + // op_tas + {1,1,M_BASIC,L_1,0x4AC0,A_DST2|D_EA}, +#endif +#endif +}; + +void wrt4(long x) { + if (odd) fatal("ALIGN"); + bin_chk(pos+=4); +#ifdef PC + bin[pos-4]=(unsigned char)(x>>24); + bin[pos-3]=(unsigned char)(x>>16); + bin[pos-2]=(unsigned char)(x>>8); + bin[pos-1]=(unsigned char)(x); +#else + *(long *)(bin+pos-4)=x; +#endif +#ifdef PC + if ((pos^odd)&1) + fatal("INT/ODD"); +#endif +} +void wrt2(short x) { + if (odd) fatal("ALIGN"); + bin_chk(pos+=2); +#ifdef PC + bin[pos-2]=(unsigned char)(x>>8); + bin[pos-1]=(unsigned char)(x); +#else + *(short *)(bin+pos-2)=x; +#endif +#ifdef PC + if ((pos^odd)&1) + fatal("INT/ODD"); +#endif +} +void wrt1(char x) { + bin_chk(pos+=1); +#ifdef PC + bin[pos-1]=(unsigned char)(x); +#else + *(char *)(bin+pos-1)=x; +#endif + odd=~odd; +#ifdef PC + if ((pos^odd)&1) + fatal("INT/ODD"); +#endif +} +void fill(int n) { + if (odd) wrt1(0); + bin_chk(pos+=n); + memset(bin+pos-n,0,n); + odd = -(n&1); +} +void move_pos(long diff) { /* caution : only works in overwrite mode */ + odd^=-(diff&1); + pos+=diff; +} +void rewrite(long size) { + bin_chk(pos+=size); + memcpy(bin+(pos-size),bin+(pos-2*size),size); + odd^=-(size&1); +#ifdef PC + if ((pos^odd)&1) + fatal("INT/ODD"); +#endif +} + +readonly int sz_table[]={0,0,0,0,0,2,2,2,0,0,2,2,2,2,4,0,0,0}; + +readonly struct enode zero={en_icon,0,0,{0},0,0}; +readonly struct amode am_null={am_direct,(struct enode *)&zero,0,0,0,0}; +#define ip_lab (((struct lbls *)ip)->lab) +void pass1() { + struct ocode *ip=scope_head; + OPCODE *op; + unsigned int vpos=pos; + while (ip) { + int opt,sz,n,f; + struct amode *ap; + int c=opi[ip->opcode],nm=opi[ip->opcode+1]-c; + int orig_len=ip->length; + int argnum_ok=0; +/* if (ip->opcode==_op_adj) { + sz=0; opt=0; c=-1; + goto ok; + }*/ + err_cur_line=ip->line; + if (!nm) { + if (ip->opcode!=op_label) + fatal("P1: UNIMPL"); + { + if (!local(ip_lab) && lab_src(ip_lab)) { + char *name=unres_name(ip_lab); + while (ip && ip->opcode==op_label) ip=ip->fwd; + if (ip) err_cur_line=ip->line-1; + else err_assembly=0; + uerrc2("label '%s' redefined",name); + } + lab_set(ip_lab,vpos); + ip->opcode=0; + sz=0; + goto ok_lab; + } + } + nm--; do { + opt=0; + op=(OPCODE *)&ops[c]; + if ((!(n=op->nargs) && ip->oper1) || (n==1 && (!ip->oper1 || ip->oper2)) + || (n==2 && !ip->oper2)) + goto nxt; + argnum_ok++; + ip->length=orig_len; + switch (op->model) { + case M_BASICSWAPPED: /* caution : assumes that it is the sole M_BASICSWAPPED */ + ap=ip->oper1; /* and that it is placed at the very end... */ + ip->oper1=ip->oper2; + ip->oper2=ap; + /* FALLTHROUGH */ + case M_BASIC: + if (!((f=op->lenf) & (1<length))) { + if (!ip->length) { + if (!(f & (1<<2))) { + if (!(f & (1<<4))) + ip->length=1; + else ip->length=4; + } else ip->length=2; + } else goto nxt; + } + sz=2; + ap=ip->oper1; + f=op->a1; + while (n--) { + int m=ap->mode; + if (!(f& + (mlength?(m==am_ainc?A_MEM0:A_ADEC):0) + ) + ) + : + (moffset->nodetype==en_labcon + || ap->offset->nodetype==en_nacon) && +#ifndef LARGE_MODEL + global(ap->offset->v.enlab) +#else + local(ap->offset->v.enlab) +#endif +#ifdef TWIN_COMPILE + && (!twinc_prev || + ((tclab=twinc_prev[0],tcoff=twinc_prev[1], + twinc_prev+=2, + tclab!=ap->offset->v.enlab||abs(tcoff-vpos)>=5000) + && (twinc_prev-=2,1))) +#endif + )) { + /*if (ap->offset->v.enlab==0xFFFF8032) + bkpt();*/ + m=am_pcrel; + } else { + get_offs(ap->offset,0); + if (is_long) + m=am_dirl; + else m=am_dirw; + } + ap = *(ap==ip->oper1 ? &ip->oper1 : &ip->oper2) = copy_addr(ap); + /* this is because the same operand might be either pcrel or + dirl, depending on the instruction/place of the operand */ + ap->mode=m; + } +#ifdef TWIN_COMPILE + } +#endif + if (f&D_RAW2) + sz+=2; + else if ((f&D_RAW) && m==am_immed) + sz+=(ip->length+1)&-2; + else if (!(f&(D_Q|D_LOW))) + sz+=(m==am_immed?(ip->length+1)&-2:sz_table[m]); + ap=ip->oper2; + f=op->a2; + } + break; + case M_BRANCH: + if (n==1) { // Bcc + if (ip->oper1->offset->nodetype!=en_labcon + && ip->oper1->offset->nodetype!=en_nacon) +// fatal("BRANCH"); + uerrc("invalid branch"); + n=ip->oper1->offset->v.enlab; + if (!global(n)) +// fatal("XT BRANCH"); + uerrc("invalid branch"); + if (ip->length==2) opt=0,sz=4; + else { + if ((f=lab_src(n))) { + f-=vpos; + opt=(f>129 || f<-126); // all branches are backwards so we needn't + // handle branches to next stmt in this pass + } else opt=1; + sz=2+(opt<<1); + } + } else { // DBcc + if ((ip->oper2->offset->nodetype!=en_labcon + && ip->oper2->offset->nodetype!=en_nacon) + || (ip->oper1->mode!=am_dreg)) +// fatal("DBRANCH"); + uerrc("invalid branch"); + n=ip->oper2->offset->v.enlab; + if (!global(n)) +// fatal("XT BRANCH"); + uerrc("invalid branch"); + sz=4; + } + break; +#ifdef ASM + case M_DC: + f=ip->length-2; + if (f<=0) f++; // f=log_2(ip->length) + if (ip->oper1->mode!=am_direct) +// fatal("DC"); + uerrc("invalid declaration"); + sz=1; + if (((short)op->bo)>=0) { + if (ip->oper1->offset->nodetype!=en_icon) + uerrc("invalid declaration"); + sz=ip->oper1->offset->v.i; + if (op->bo && ip->oper2->mode!=am_direct) + uerrc("invalid declaration"); + } + sz<<=f; + if (sz>=128) + uerrsys("too many elements in 'dc' instruction; use C arrays"); + break; + case M_ALIGN: + sz=0; + if (vpos&1) { + sz=1; + c=oi_dc; + ip->length=1; + ip->oper1=(struct amode *)&am_null; + } + break; + default: + fatal("P1"); + sz=0; + break; +#endif + } + goto ok; + nxt: + c++; + } while (nm--); + if (!argnum_ok) + uerrc2("instruction requires %d arguments",n); + uerrc("invalid address modes"); + return; +// fatal("P1: INVALID"); + ok: +#ifdef SIZE_STATS + if (!ip->opt) /* not from an asm() statement */ + c_compiler_sz+=sz; /* note this is approximative, but close to reality */ +#endif + ip->opt=opt; + ip->sz=sz; + ip->opcode=c; + ok_lab: + ip=ip->fwd; + vpos+=sz; + } +} + +void pass2() { + struct ocode *ip=scope_head; + unsigned int vpos=pos,opos=vpos,s; + OPCODE *op; + while (ip) { + if (ip->opcode>0) { + s=ip->sz; + if (ip->opt) { + op=(OPCODE *)&ops[ip->opcode]; + switch (op->model) { + case M_BASIC: case M_BASICSWAPPED: + break; + case M_BRANCH: { // this is necessarily a Bcc since ip->opt==1 + int n=ip->oper1->offset->v.enlab; + long f=qlab_src(n); + if (!f) break; // global label not found + if ((unsigned int)f>opos) // we HAVE TO compare with opos (since opos>=vpos) + f-=opos+2; // <- here, f is afterwards, so relative to old pos + else f-=vpos+2; + /* the case of the next stmt branch : + * PASS 1 : the label is unknown, so opt=1 and ip->sz=4 + * PASS 2 : qlab_src(n)-opos==4, so here, f==2 (rather than f==0) */ + if (f!=2 && f>=-128 && f<=127) + ip->sz=2; + else if (f>=-32768 && f<=32767) + ip->sz=4; + else err_cur_line=ip->line, uerrc("branch size can't fit in a word"); + } break; + } + } + opos+=s, vpos+=ip->sz; + } else if (!ip->opcode) {// op_label +/* if (vpos==0x2642) + printf("rjo");*/ + lab_set(ip_lab,vpos); + } +/* else { // _op_adj + + }*/ + ip=ip->fwd; + } +} + +int movem(short x) { + int n=0; + while (x) { + if (x<0) n++; + x+=x; + } + return n; +} + +void pass3() { + struct ocode *ip=scope_head; +#ifdef PC + unsigned int opos=pos; +#endif + OPCODE *op; + while (ip) { + int n,f; + struct amode *ap; + short code; + if (ip->opcode>0) { + err_cur_line=ip->line; + op=(OPCODE *)&ops[ip->opcode]; + n=op->nargs; + switch (op->model) { + case M_BASIC: case M_BASICSWAPPED: { + int ds=0,ds2=0; int len=ip->length; +#ifdef PC + long dc=0xdddddddd,dc2=0xdddddddd; +#else + long dc=dc,dc2=dc2; +#endif + unsigned int vpos=pos+2; + code=op->bo; + ap=ip->oper1; + f=op->a1; +#ifndef USE_LINK + if (n) + if (ap->preg==STACKPTR-8) { + if (ap->mode==am_ainc) { // for (a7)+,... + lc_stk-=len+(len&1); + } else if (ap->mode==am_adec) + lc_stk+=len+(len&1); // for clr -(a7) + } +#endif + while (n--) { + if ((f&D_SZ3)==D_SZ3) { + if (len==4) code|=0x40; + } else if (f&D_SZ) + code|=(len==2?0x40:(len==4?0x80:0x00)); + else if ((f&D_SZ2) && len==4) + code|=0x100; + if (f&D_EA) + switch (ap->mode) { + case am_areg: + case am_ind: + case am_ainc: + case am_adec: + code+=ap->mode<<3; + case am_dreg: + code+=ap->preg; + break; + case am_indx: +#ifndef USE_LINK + if (ap->preg==FRAMEPTR-8) { + if (uses_link) + ap->preg+=TRUE_FRAMEPTR-FRAMEPTR; + else { + ap->preg+=STACKPTR-FRAMEPTR; + ap->offset->v.i += lc_stk - (ap->offset->v.i>0 ? 4 : 0); + uses_lc_stk = 1; + } + } +#endif + code+=0x28+ap->preg; + ds=1; dc=get_word(ap->offset,vpos,1); + break; + case am_pcrel: + code+=0x3A; + ds=1; dc=get_pcword(ap->offset,vpos); // rel to vpos, not pos! + break; + case am_dirw: + code+=0x38; + ds=1; dc=get_word(ap->offset,vpos,1); + break; + case am_dirl: + code+=0x39; + ds=2; dc=get_long(ap->offset,vpos); + break; + case am_immed: + code+=0x3C; + ds=(1+len)>>1; + if (ds==1) dc=get_word(ap->offset,vpos,0); + else dc=get_long(ap->offset,vpos); + break; + case am_indx2: + code+=0x30+ap->preg; + ds=1; + dc=get_byte(ap->offset)+((short)ap->sreg<<12)+ + (ap->slen==4?0x0800:0x0000); + break; + case am_indx3: + code+=0x30+ap->preg; + ds=1; + dc=get_byte(ap->offset)+((short)ap->sreg<<12)+ + (ap->slen==4?0x8800:0x8000); + break; +#ifdef PC + default: + ierr(PASS3,1); +#endif + } + else if (f&D_EA2) + switch (ap->mode) { + case am_areg: + case am_ind: + case am_ainc: + case am_adec: + code+=ap->mode<<6; + case am_dreg: + code+=((short)ap->preg)<<9; + break; + case am_indx: +#ifndef USE_LINK + if (ap->preg==FRAMEPTR-8) { + if (uses_link) + ap->preg+=TRUE_FRAMEPTR-FRAMEPTR; + else { + ap->preg+=STACKPTR-FRAMEPTR; + ap->offset->v.i += lc_stk - (ap->offset->v.i>0 ? 4 : 0); + uses_lc_stk = 1; + } + } +#endif + code+=(0x28<<3)+((short)ap->preg<<9); + ds=1; dc=get_word(ap->offset,vpos,1); + break; +/* case am_pcrel: + code+=(0x38<<3)+(0x02<<9); + ds=1; dc=get_pcword(ap->offset,vpos); // rel to vpos, not pos! + break;*/ + case am_dirw: + code+=0x38<<3; + ds=1; dc=get_word(ap->offset,vpos,1); + break; + case am_dirl: + code+=(0x38<<3)+(0x01<<9); + ds=2; dc=get_long(ap->offset,vpos); + break; + case am_indx2: + code+=(0x30<<3)+(ap->preg<<9); + ds=1; + dc=get_byte(ap->offset)+((short)ap->sreg<<12)+ + (ap->slen==4?0x0800:0x0000); + break; + case am_indx3: + code+=(0x30<<3)+(ap->preg<<9); + ds=1; + dc=get_byte(ap->offset)+((short)ap->sreg<<12)+ + (ap->slen==4?0x8800:0x8000); + break; +#ifdef PC + default: + ierr(PASS3,2); +#endif + } + else if (f&D_Q) + switch (ap->mode) { + case am_areg: + case am_dreg: + case am_ainc: + case am_adec: + code+=((unsigned short)ap->preg)<<9; + break; + case am_immed: + code+=get_quick(ap->offset)<<9; + break; +#ifdef PC + default: + ierr(PASS3,3); +#endif + } + else if (f&D_LOW) + switch (ap->mode) { + case am_areg: + case am_dreg: + case am_adec: + case am_ainc: + code+=ap->preg; + break; + case am_immed: + code+=get_byte(ap->offset); + break; +#ifdef PC + default: + ierr(PASS3,4); +#endif + } + else if (f&D_RAW) + switch (ap->mode) { + case am_immed: + if (len==4) + ds=2,dc=get_long(ap->offset,vpos); + else + ds=1,dc=get_word(ap->offset,vpos,0); + break; + case am_mask1: + case am_mask2: + ds=1; dc=ap->offset->v.i; + break; +#ifdef PC + default: + ierr(PASS3,5); +#endif + } + else if (f&D_RAW2) + ds=1,dc=get_word(ap->offset,vpos,0); + ap=ip->oper2; + f=op->a2; + vpos+=ds<<1; + if (n) { + ds2=ds,dc2=dc,ds=0; +#ifndef USE_LINK + if (ap->preg==STACKPTR-8) { + if (ap->mode==am_adec) { // for ...,-(a7) + if (ip->oper1->mode==am_mask1) + lc_stk+=movem((short)ip->oper1->offset->v.i)<<(len>>1); + else lc_stk+=len+(len&1); + } + else if (ap->mode==am_ainc && ip->oper1->mode==am_mask2) + lc_stk-=movem((short)ip->oper1->offset->v.i)<<(len>>1); + } +#endif + } + } +#ifndef USE_LINK + if (code==0x4FEF // lea x(a7),a7 + || (code&0xF13F)==0x500F // addq.* #x,a7 + || (code&0xFEFF)==0xDEFC) // add.* #x,a7 + lc_stk-=ip->oper1->offset->v.i; + else if ((code&0xF13F)==0x510F // subq.* #x,a7 + || (code&0xFEFF)==0x9EFC) // sub.* #x,a7 + lc_stk+=ip->oper1->offset->v.i; + else if (((code&0xFFC0)==0x4840 && (code&0x0038/*!swap*/))) // pea + lc_stk+=4; +#endif + wrt2(code); + if (--ds2>=0) { + if (!ds2) wrt2((short)dc2); + else wrt4(dc2); + } + if (--ds>=0) { + if (!ds) wrt2((short)dc); + else wrt4(dc); + } + } break; + case M_BRANCH: { + unsigned int vpos=pos+2; + code=op->bo; + if (ip->oper2) // DBcc + n=ip->oper2->offset->v.enlab, code+=ip->oper1->preg; + else n=ip->oper1->offset->v.enlab; // Bcc + if ((f=qlab_src(n))) { + if (ip->sz==2) + wrt2(code|=(f-vpos)&0xFF); + else + wrt2(code),wrt2((short)(f-vpos)); + } else + wrt2(code),wrt2((short)-(short)vpos),lab_add_ref(n,vpos); + } break; + case M_DC: { + struct enode *ep=ip->oper1->offset; + n=1; + if (((short)op->bo)>=0) { + n=ip->oper1->offset->v.i; + if (op->bo) + ep=ip->oper2->offset; + else ep=(struct enode *)&zero; + } + f=ip->length-2; + while (n--) { + if (f<0) { + GV v; + get_value(ep,&v,0,0); + if (v.tr) + uerr(ERRA_INVALIDREL); + if (v.i>255 || v.i<-128) + uerrc("result can't fit in a byte"); + wrt1((char)v.i); + } else if (!f) wrt2(get_word(ep,pos,0)); + else wrt4(get_long(ep,pos)); + } + } break; + } +#ifdef PC + opos+=ip->sz; + if (pos!=opos) { +// printf("%d",oi_ds); + ierr(PASS3,6); + } +#endif + } +/* else if (ip->opcode) { // _op_adj + + }*/ + else if (!ip->opcode) { // op_label +//#ifdef PC +// if (pos!=qlab_src(ip_lab)) +// ierr(PASS3,7); +//#endif + if (pos!=qlab_src(ip_lab)) + uerrc2("label '%s' defined twice",unres_name(ip_lab)); + if (!local(ip_lab)) { + lab_set(ip_lab,0); // 'unset' it so there will be no error... + set_label(ip_lab,pos); + } + } + ip=ip->fwd; + } +} + +void scope_flush(void) { + err_assembly=1; + pass1(); + pass2(); + pass3(); + err_assembly=0; + if (uses_lc_stk && lc_stk) { + uwarn("stack displacement of %d: compiler bug?",(int)lc_stk); + iwarn(WARN_LC_STK,1); + } + scope_head = 0; + loc_tab = 0; +} + +void scope_init(void) { + if (scope_head) scope_flush(); + lc_stk = 0; + uses_lc_stk = 0; + nextlabel = 1; + loc_tab = 0; +} + +void local_clean(void) { /* remove local symbols from alsyms -- to be called just before rel_local */ + HTABLE *tab=&alsyms; + SYM *ttail,**prv; + struct htab *root; + int i; + if (!tab->hash) + ierr(TABLE_HASH,2); +#ifdef PC + if (tab->hash!=0x2489) + ierr(TABLE_HASH,1); +#endif + i=N_HASH; + while (i--) { + prv=&((root=&tab->h[i])->tail); + while ((ttail=*prv)) { + if (local(ttail->value.splab)) { +// *prv = ttail->prev; + if (ttail->next) ttail->next->prev = ttail->prev; + if (ttail->prev) ttail->prev->next = ttail->next; +// ttail->next = prv; + if (root->tail==ttail) root->tail=ttail->prev; + if (root->head==ttail) root->head=ttail->next; +/* if (!root->tail) + root->head=0;*/ + } + prv = &(ttail->prev); + } + } +} + +int label(char *s) { + int lab; SYM *sp; +/* if (!strcmp(s,"__L_plane") || !strcmp(s,"__D_plane")) + bkpt();*/ + if (!(sp=search(s,-1,&alsyms))) { + if (s[0]!='\\') + global_flag++; + sp=(SYM *)xalloc((int)sizeof(SYM),_SYM); + sp->name=strsave(s); + if (s[0]=='\\') + lab_src(sp->value.splab=lab=nxtlabel()); + else if (internal(s)) + lab_src(sp->value.splab=lab=nxtglabel()); + else + sp->value.splab=lab=extlabel--; + insert(sp,&alsyms); + if (s[0]!='\\') + global_flag--; + } else + lab=sp->value.splab; + debugf("label(%s)=%x\n",s,lab); +#ifdef PC +/* if (lab==0x806d) + bkpt();*/ + if (!*s) + return lab; +#endif + return lab; +} + +void set_label(int lab,unsigned int pos) { + /*if ((unsigned short)lab==0x8014) + bkpt();*/ + debugf("set_lab(%x,%x)\n",lab,pos); + if (lab_src(lab)) uerrc("label redefinition"); + if (global(lab)) { + lab_set(lab,pos); + if (!local(lab)) { + REF **rp,*r; + unsigned int p,*a; int n; + r=*(rp=glb_ref(lab)); + while (r) { + a=r->r; + n=N_REF; + while (n--) { + if (!(p=*a++)) + goto ref_done; +#ifdef PC + { int m=p&1; short a,olda; + p-=m; + a=(bin[p]<<8)+bin[p+1],olda=a; + if (m) { + if ((a-=pos)>0 && olda) fatal("PC RANGE 3"); + } else if ((a+=pos)<0 && olda) fatal("PC RANGE 2"); + bin[p]=(unsigned char)(a>>8); + bin[p+1]=(unsigned char)(a); + } +#else + if (p&1) { + short *z=(short *)(bin+(p&-2)); + if (*z && ((*z)-=pos)>0) + fatal("PC RANGE 3"); + else (*z)-=pos; + } else if ((*(short *)(bin+p)+=pos)<0 && *(short *)(bin+p)!=pos) + fatal("PC RANGE 2"); +#endif + } + r=r->nxt; + } + ref_done: + *rp=0; + } + } + else debugf(" --local\n"); +} + +void put_label(int lab) { +/* + * output a compiler generated label. + */ +#ifdef NO_OUT + return; +#endif + set_label(lab,pos); +} + +void g_strlab(char *s) { +/* + * generate a named label. + */ +#ifdef NO_OUT + return; +#endif + put_label(label(s)); +} + +void genbyte(int val) { +#ifdef NO_OUT + return; +#endif + wrt1((char)val); +} + +void genword(int val) { +#ifdef NO_OUT + return; +#endif + put_align2(); + wrt2((short)val); +} + +typedef struct _pc_bcd_s { + short exponent; + unsigned char mantissa[8]; +} _pc_bcd; +#ifndef NOFLOAT +void genfloat(double val) { +#ifndef BCDFLT + put_align2(); + wrt4(double2ffp(val)); +#else + BCD bcd; + double2bcd(val,&bcd); + wrt2(bcd.exponent); +#ifdef PC + { + int i; + for (i=0;itp->size; +#ifdef NO_OUT + return; +#endif +#ifdef PC +#define no_bss (nostub_mode || forbid_bss) +#else +#define no_bss nostub_mode +#endif + if (align!=1) put_align2(); + size=(size+1)&-2; // round size + if (sp->value.splab) { + if (no_bss) { /* that's OK in _nostub mode :) */ + if (lab_src(sp->value.splab)) + return; + } else + uerrc2("BSS redeclaration of '%s' : use 'extern' for prototyping",sp->name); + } else if (no_bss) { + if (sp->storage_class==sc_static) + sp->value.splab=nxtglabel(); + else + sp->value.splab=label(sp->name); + } + if (no_bss) { + put_label(sp->value.splab); + fill(size); + } else { + *(long *)xt_find(sp->value.splab=extlabel--)=lc_bss|0x80000000; // DIRTY, but no hidden + lc_bss+=size; // bug possible + } // (cf xalloc) +#if 0 + remain = size % AL_DEFAULT; + if (remain != 0) + size = size + AL_DEFAULT - remain; + if (sp->storage_class == sc_static) { + fprintf(output, "L%ld:" tabs "ds.b %ld\n", sp->value.i, size); + lc_bss += sp->tp->size; + } else + fprintf(output, "L%d:" tabs "ds.b %ld\n", label(sp->name),size); +#endif +#undef no_bss +} + +void dumplits() { +/* + * dump the string literal pool. + */ + char *cp; + int len; +/* + * The ACK assembler may produce a .text section of an uneven length. + * This will eventually bomb the linker when it tries to relocate + * something in a following (.data) section, which then is misaligned + * as a whole in memory (perhaps this is just a bug in the linker). + * + * To avoid this (it can only happen if the string pool is the last + * thing dumped to the assembler file) we count the total number of + * bytes in the string pool and emit a zero filler byte if that + * number was uneven. + * This is perhaps an ugly hack, but in virtually all of the cases + * this filler byte is inserted anyway by the assembler when + * doing the alignment necessary for the next function body. + */ +// long count=0; + + while (strtab != 0) { + cseg(); + nl(); + put_label((unsigned int) strtab->label); + cp = strtab->str; + len = strtab->len; + //count += (len+1); + while (len--) + wrt1(*cp++); + wrt1(0); + strtab = strtab->next; + } + put_align2(); +} + + +void put_align2(void) { +/* align the following data to 2 */ + if (odd) wrt1(0); +} +/*put_align(align) + int align; +// align the following data +{ + switch (align) { + case 1: + break; + case 2: + if (odd) wrt1(0); + } +}*/ + +#ifdef LISTING +void put_external(char *s) { +/* put the definition of an external name in the ouput file */ + +} +void put_global(char *s) { +/* put the definition of a global name in the output file */ + +} +#endif + +/*cseg() +{ + if (curseg != codeseg) { + nl(); +#ifdef PC + fputs(tabs ".text\n", output); +#endif + curseg = codeseg; + } +}*/ +/*dseg() +{ + if (curseg != dataseg) { + nl(); +#ifdef PC + fputs(tabs ".data\n", output); +#endif + curseg = dataseg; + } +}*/ + +int radix16(char c) { + if (isdigit(c)) + return c - '0'; +/* if (c >= 'a' && c <= 'z') + return c - 'a' + 10;*/ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return -1; +} +int hexatoi(char *s) { + int x=0; + if (strlen(s)>3) return -1; + while (*s) { + int y=radix16(*s++); + if (y<0) return -1; + x<<=4; x+=y; + } + return x; +} + +int internal(char *s) { + int n=0; + char c,old=0,*p; + if (*s == '.') + return 1; + p=s; + while ((c=*p++)) { + if (n==10) { + if ((( +#ifdef FLINE_RC + !fline_rc && +#endif + !strncmp(s,"_ROM_CALL_",10))) +#ifdef RAM_CALLS + || !strncmp(s,"_RAM_CALL_",10) +#endif + ) { + int f=hexatoi(p-1); + if (f<0) + goto cont; + *xt_find(extlabel)=&(func_search( +#ifdef RAM_CALLS + s[2]=='O' ? &rom_funcs : &ram_funcs +#else + &rom_funcs +#endif + ,f))->rt; + return 0; + } + } + if (n==export_pfx_len) { + if (!strncmp(s,export_pfx,n)) { + int f=hexatoi(p); + if (f<0) + goto cont3; + *exp_find(f)=glblabel; + return 1; + } + } + if (c=='_' && n && old=='_' && *p=='0') { + SYM *sp; + int f=hexatoi(p+1); + if (f<0) + goto cont2; + p[-2]=0; + if (!(sp=search(s,-1,(HTABLE *)&libsyms))) { + global_flag++; + sp=(SYM *)xalloc((int)sizeof(SYM),_SYM); + sp->name=strsave(s); + insert(sp,(HTABLE *)&libsyms); + global_flag--; + } + *xt_find(extlabel)=&(func_search((FUNC **)&sp->value.i,f))->rt; + p[-2]='_'; + return 0; + } + cont: + cont2: + cont3: + old=c; n++; + } + return 1; +} + +#ifdef PCH +unsigned char *_end_of(short *p) { /* works endian-independently */ + while (*p++); + return (unsigned char *)p; +} +unsigned char *_end_of2(short *p) { /* works endian-independently */ + while (*p++ || *p); + return (unsigned char *)(p+1); +} +#define end_of(p) _end_of((short *)(p)) +#define end_of2(p) _end_of2((short *)(p)) + + +#ifndef isidch +#ifdef PC +static int isidch(char c) { + return (c>='0'&&c<='9') || (c>='A'&&c<='Z') || (c>='a'&&c<='z') + || c == '_' || c == '$'; +} +#else +#define isidch(___c) ({register short __c=(___c); \ +(__c>='0'&&__c<='9') || (__c>='A'&&__c<='Z') || (__c>='a'&&__c<='z') || __c=='_' || __c=='$';}) +#endif +#endif + +int pchsearch(char *id,int mode); +#define lscan(x) pchsearch(x,PCHS_ADD) +#define lexpand(x) (x) +/*#define lscan (void)lexpand +void macro_expansion(char *in,char *inbound); +char lexp_buf[100]; +char *lexpand(char *s) { + char c,*p=lexp_buf; + strcpy(p,s); + macro_expansion(p,&lexp_buf[100]); + if (*p>='0' && *p<='9') + return s; + while ((c=*p++)) + if (!isidch(c)) return s; + return lexp_buf; +}*/ + +#ifdef PC +#define g16(p) (p+=2,(p[-2]<<8)+p[-1]) +#define r16(o) ((ext[o]<<8)+ext[o+1]) +#define align(strp) if ((strp-ext)&1) strp++ +#else +#define g16(p) (*((int *)p)++) +#define r16(o) (*(int *)(ext+o)) +#define align(strp) if (((short)((long)strp))&1) strp++ +#endif +void extscan(unsigned char *ext) { + int codeOff=r16(0); + unsigned char *offp=ext+codeOff,*strp; + /* reloc table */ + offp=end_of(offp); + /* export table */ + strp=end_of(offp); + while (g16(offp)) + while (*strp++); + align(strp); + /* import table */ + offp=strp; strp=end_of2(offp); + while (*(short *)offp) { + lscan(strp); + offp=end_of(offp); + while (*strp++); + } +} + +#undef off // for TI-GCC :D +#ifdef PC +#define add_offs(val,offs) do { \ + short a=bin[offs+0]<<8; \ + a+=bin[offs+1]; \ + a+=val; \ + bin[offs+0]=(unsigned char)(a>>8); \ + bin[offs+1]=(unsigned char)(a); \ + } while (0) +#else +#define add_offs(val,offs) (*(short *)(bin+offs)+=val) +#endif + +void extload(unsigned char *ext) { + int codeOff=r16(0); unsigned int wriOff; + SYM *sp; + if (odd) wrt1(0); +/*#ifdef PC + if (codeOff>=0x2000) + printf("gfio"); +#endif*/ + /* In the following case, either the .ext has already been loaded, either + * there is a conflict, in which case the error will arise at the end + * (what's more, it allows for overriding of the default functions) */ + sp=search(end_of(end_of(ext+codeOff)),-1,&alsyms); + if (sp && lab_src(sp->value.splab)) + return; + wriOff=pos-2; /* since offsets are based on ext::$00, not on ext::$02=code */ + bin_chk(pos+=codeOff-2); + memcpy(bin+pos-codeOff+2,ext+2,codeOff-2); + { + /* reloc table */ + unsigned short off; unsigned char *offp=ext+codeOff; + while ((off=g16(offp))) { + rt_add_ref(&reloc_tab,off+wriOff); + add_offs(wriOff+2,off+wriOff+2); + } + { + /* export table */ + unsigned char *strp=end_of(offp); + while ((off=g16(offp))) { + set_label(label(strp),off+wriOff); + while (*strp++); + } + align(strp); + /* import table */ + offp=strp; strp=end_of2(offp); + while (*(short *)offp) { + int n=label(lexpand(strp)); unsigned int p=lab_src(n); + while ((off=g16(offp))) { + off+=wriOff; + if (p) { +#ifdef PC + unsigned short a=bin[off+2]<<8; + a+=bin[off+3]; + a+=p; + bin[off+2]=(unsigned char)(a>>8); + bin[off+3]=(unsigned char)(a); +#else + *(short *)(bin+off+2)+=p; +#endif + /* if (ip->sz==2) + wrt2(code|=(f-vpos)&0xFF); + else wrt2(code),wrt2((short)(f-vpos));*/ + } else + lab_add_ref(n,off+2); + rt_add_ref(&reloc_tab,off); + } + while (*strp++); + } + } + } +} +#endif + +#endif /* MC680X0 */ +// vim:ts=4:sw=4 diff --git a/gtc/src/out68k_exe.h b/gtc/src/out68k_exe.h new file mode 100644 index 0000000..87e2a1c --- /dev/null +++ b/gtc/src/out68k_exe.h @@ -0,0 +1,71 @@ +/* + * GTools C compiler + * ================= + * source file : + * EXE loader + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define exeloadersize_bss (-1) +readonly unsigned char exeloader_bss[1]; +#define exeloadersize_nobss sizeof(exeloader_nobss) +readonly unsigned char exeloader_nobss[]={ + 0x4f,0xef,0x00,0x30,0x4e,0x75,0x20,0x78,0x00,0xc8,0x0c,0xa0,0x54,0x8f,0x4e,0x75, + 0x66,0xf8,0x42,0x67,0x2f,0x08,0x48,0xe7,0x1f,0x3e,0x47,0xf9,0x00,0x00,0x00,0x00, + 0x7a,0xf2,0xda,0x8b,0x24,0x78,0x00,0xc8,0x76,0x00,0x36,0x2b,0x00,0x0c,0x2f,0x13, + 0x20,0x6a,0x02,0x48,0x4e,0x90,0x58,0x8f,0x3f,0x00,0x67,0xc4,0x20,0x6a,0x02,0x58, + 0x4e,0x90,0x3e,0x1f,0x28,0x48,0x22,0x4c,0xd3,0xd3,0x93,0xc3,0x2c,0x09,0x41,0xeb, + 0x00,0x08,0x4e,0xba,0x01,0x2c,0x20,0x46,0x22,0x4c,0x70,0x00,0x30,0x23,0x47,0xf3, + 0x08,0x0a,0x61,0x00,0x00,0x9e,0x3f,0x47,0x00,0x2c,0x48,0x54,0x3f,0x3c,0x00,0x0a, + 0x42,0xa7,0x20,0x6a,0x01,0xb0,0x4e,0x90,0x5c,0x8f,0x26,0x08,0x78,0x00,0x08,0x28, + 0x00,0x02,0x00,0x0a,0x67,0x10,0x3f,0x28,0x00,0x0c,0x20,0x6a,0x02,0x58,0x4e,0x90, + 0x54,0x8f,0xba,0x88,0x67,0x0a,0x20,0x6a,0x01,0xb4,0x4e,0x90,0x26,0x08,0x66,0xde, + 0x48,0xe7,0x1f,0x3e,0x48,0x7a,0x00,0x52,0x20,0x78,0x00,0xc8,0x0c,0xa0,0x00,0x00, + 0x03,0xe8,0x65,0x48,0x26,0x6f,0x00,0x2c,0x20,0x08,0xe1,0x98,0x6b,0x12,0x0c,0x57, + 0x00,0x04,0x64,0x38,0x26,0x7c,0x00,0x03,0xe0,0x00,0x58,0x57,0x58,0x6f,0x00,0x2c, + 0xef,0x98,0x72,0x70,0xc2,0x80,0x52,0x81,0x48,0x41,0xe3,0x99,0x24,0x17,0x2f,0x01, + 0x2f,0x01,0x4f,0xef,0xff,0xf4,0x4e,0x4c,0x46,0xfc,0x27,0x00,0x2f,0x02,0x42,0x67, + 0x76,0x0f,0x20,0x78,0x00,0xac,0x4e,0xd0,0x4f,0xef,0x00,0x14,0x4c,0xdf,0x7c,0xf9, + 0x4e,0x75,0x48,0xe7,0x18,0x1c,0x72,0x00,0x70,0x00,0x10,0x1b,0x67,0x00,0x00,0x6c, + 0x6a,0x06,0xd0,0x00,0xef,0x48,0x10,0x1b,0x55,0x40,0x65,0x2e,0x60,0x02,0x32,0xd8, + 0x38,0x10,0x76,0xc0,0x86,0x44,0x5c,0x43,0x67,0x0e,0xc8,0x7c,0xf0,0xff,0xb8,0x7c, + 0x60,0x00,0x57,0xc8,0xff,0xea,0x66,0x10,0x53,0x40,0x65,0x0c,0x32,0xd8,0x36,0x09, + 0x96,0x4c,0x97,0x50,0x51,0xc8,0xff,0xd8,0x32,0xd8,0x51,0xc9,0x00,0x06,0x58,0x41, + 0x14,0x1b,0x4a,0x13,0x67,0x24,0xd4,0x02,0x65,0x0e,0x42,0x59,0x32,0xd8,0x20,0x0c, + 0xd4,0x02,0xd1,0xa9,0xff,0xfc,0x60,0xa0,0xd4,0x02,0x30,0x18,0x6b,0x04,0x32,0xfc, + 0x4e,0xb9,0xe5,0x48,0x22,0xf2,0x00,0x00,0x60,0x8e,0x4c,0xdf,0x38,0x18,0x4e,0x75, + 0x48,0xe7,0x1f,0x3e,0x7a,0xff,0x42,0x05,0x47,0xfa,0x01,0x70,0x50,0x88,0x70,0x00, + 0x10,0x18,0x38,0x00,0x72,0x00,0x12,0x18,0x3c,0x41,0xd0,0x40,0x36,0x33,0x00,0x02, + 0x70,0x08,0x90,0x44,0x38,0x40,0x24,0x48,0x12,0x18,0xd2,0x41,0x4b,0xf3,0x10,0x02, + 0x70,0x00,0x10,0x18,0xd0,0xc0,0x7e,0x00,0x9e,0x44,0x6a,0x08,0x50,0x47,0x16,0x86, + 0x3c,0x13,0x1c,0x18,0x32,0x06,0xee,0x69,0xc2,0x43,0xb2,0x4e,0x67,0x14,0x9e,0x4c, + 0x6a,0x08,0x50,0x47,0x16,0x86,0x3c,0x13,0x1c,0x18,0x32,0x06,0xee,0x69,0x12,0xc1, + 0x60,0xd6,0x61,0x4e,0x4a,0x41,0x67,0x00,0x00,0x8e,0x30,0x02,0x61,0x44,0x0c,0x42, + 0x00,0xff,0x66,0x06,0x4c,0xdf,0x7c,0xf8,0x4e,0x75,0x53,0x42,0x12,0x12,0x67,0x08, + 0xe3,0x6a,0x61,0x60,0xc2,0x55,0x84,0x41,0x16,0x82,0x32,0x13,0x74,0xff,0xb3,0x42, + 0x61,0x58,0x14,0x01,0x47,0xf1,0x28,0x00,0x12,0xdb,0x51,0xc8,0xff,0xfc,0x47,0xfa, + 0x00,0xda,0x60,0x94,0x61,0x44,0x82,0x45,0x12,0xf1,0x10,0x00,0x12,0xf1,0x10,0x00, + 0x60,0x86,0x72,0xff,0x51,0xcf,0x00,0x0a,0x50,0x47,0x16,0x86,0x3c,0x13,0x1c,0x18, + 0x52,0x41,0x0f,0x06,0x57,0xcf,0xff,0xfa,0x66,0xee,0x9e,0x41,0x6a,0x08,0x50,0x47, + 0x16,0x86,0x3c,0x13,0x1c,0x18,0x34,0x06,0xee,0x6a,0x03,0xc2,0xd2,0x41,0xc4,0x73, + 0x10,0x04,0x4e,0x75,0x9e,0x41,0x6a,0x08,0x50,0x47,0x16,0x86,0x3c,0x13,0x1c,0x18, + 0x32,0x06,0xee,0x69,0x4e,0x75,0x51,0xcf,0x00,0x0a,0x50,0x47,0x16,0x86,0x3c,0x13, + 0x1c,0x18,0x0f,0x06,0x67,0x9e,0x51,0xcf,0x00,0x0a,0x50,0x47,0x16,0x86,0x3c,0x13, + 0x1c,0x18,0x0f,0x06,0x66,0x20,0x32,0x04,0x61,0xca,0xc2,0x43,0x30,0x0e,0x3c,0x41, + 0x32,0x0c,0xe3,0x68,0x61,0xbe,0x34,0x0c,0xd4,0x42,0xc2,0x73,0x20,0x02,0x80,0x41, + 0x12,0xc0,0x60,0x00,0xff,0x04,0x61,0x00,0xff,0x7a,0x30,0x02,0x0c,0x40,0x00,0x80, + 0x6d,0x10,0x72,0x01,0x61,0x9e,0x10,0x01,0x61,0x00,0xff,0x68,0x53,0x02,0xe1,0x4a, + 0x80,0x42,0x61,0x00,0xff,0x5e,0x04,0x42,0x00,0x20,0x6a,0x06,0x14,0x32,0x20,0x21, + 0x60,0x0e,0xe7,0x4a,0x72,0x03,0x61,0x00,0xff,0x7c,0x02,0x41,0x00,0x07,0x84,0x41, + 0x12,0xc2,0x51,0xc8,0xff,0xfc,0x60,0x00,0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x01, + 0x00,0x03,0x00,0x07,0x00,0x0f,0x00,0x1f,0x00,0x3f,0x00,0x7f,0x00,0xff,0x01,0xff, + 0x03,0xff,0x07,0xff,0x0f,0xff,0x1f,0xff,0x3f,0xff,0x7f,0xff,0x00,0x00,0x00,0x0c, + 0x00,0x1c,0xf3, +}; diff --git a/gtc/src/pch.h b/gtc/src/pch.h new file mode 100644 index 0000000..977beb3 --- /dev/null +++ b/gtc/src/pch.h @@ -0,0 +1,53 @@ +/* + * GTools C compiler + * ================= + * source file : + * PCH management definitions + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef PCH_H +#define PCH_H + +typedef struct { + TI_LONG magic; + TI_SHORT h_off; // offset to .H section + TI_SHORT ext_off; // offset to .EXT table (int ext_table[nExt]) + TI_SHORT dic_off; // offset to dictionnary ((char[]) sPk_table[]) + TI_SHORT nID; +} PCH_HEAD; + +#define PCH_HEAD_SIZE 12 + +#define PCHID_MASK 0xFFF +#define PCHID_MACRO 0x8000 +#define PCHID_VAMAC 0x4000 +#define PCHID_PACKED 0x2000 + +#ifndef PC +char *__attribute__((stkparm)) sUnpack(char *in,char *out,char *dic); +#else +char *sUnpack(char *in,char *out,char *dic); +#endif + +/* GTC-only */ +extern FILE *pchfile[]; +extern char *pchdata[]; +extern char *pchtab[]; +extern char pchname[][15]; +extern char pchrequired[]; +extern int pchnum; +#define pchhead ((PCH_HEAD **)pchdata) + +/* PchMaker-only */ +extern int def_is_packed; + +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/peep68k.c b/gtc/src/peep68k.c new file mode 100644 index 0000000..4566ae1 --- /dev/null +++ b/gtc/src/peep68k.c @@ -0,0 +1,1291 @@ +/* + * GTools C compiler + * ================= + * source file : + * peephole optimizations + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#define NEWLAB +//#define NO_PEEP + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifndef NOFLOAT +#include "ffplib.h" +#endif + +#ifdef MC680X0 + +extern struct enode *regexp[REGEXP_SIZE]; +struct ocode *_peep_head CGLOB; +extern struct ocode *scope_head; +#ifdef SPEED_OPT +int speed_opt_value CGLOB; +#endif +#ifndef VCG +struct ocode *peep_head CGLOB; +#else +struct ocode *vcg_peep_head[VCG_MAX+1] CGLOBL; +struct ocode *vcg_peep_tail[VCG_MAX+1] CGLOBL; +int vcg_lvl CGLOB; +#define peep_head vcg_peep_head[vcg_lvl] +#define peep_tail vcg_peep_tail[vcg_lvl] +#endif +xstatic struct ocode *next_ip CGLOB; +xstatic struct ocode *last_param_pop CGLOB; + +#define getop1(__ip) (__ip->oper1->offset->v.i) +#define getoplab(__ip) (__ip->oper1->offset->v.enlab) +#define getop2(__ip) (__ip->oper2->offset->v.i) +#ifdef NEWLAB +#define getlab(__ip) (((struct lbls *)__ip)->lab) +#else +#define getlab(__ip) (__ip->oper1->offset->v.i) +#endif +/*static enum(e_op) revcond[] = { op_bne, op_beq, op_bge, op_bgt, op_ble, op_blt, + op_bls, op_blo, op_bhs, op_bhi };*/ +xstatic readonly enum(e_op) revcond[] = + { + op_bne, op_beq, op_blo, op_blt, op_bls, op_ble, op_bhi, op_bgt, op_bhs, op_bge + }; + +void add_peep(struct ocode *new_ocode); +void opt3(void); + +void g_code(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2) { +/* + * generate a code sequence into the peep list. + */ + struct ocode *new_ocode; + new_ocode = (struct ocode *) xalloc((int) sizeof(struct ocode), OCODE+G_CODE); + new_ocode->opcode = op; + new_ocode->length = len; + if ((unsigned int)len>4 || len==3) + ierr(G_CODE,1); + new_ocode->oper1 = ap1; + new_ocode->oper2 = ap2; +#ifdef PC +/* if (op>=op_add && op<=op_subq && ap1->mode>am_areg && ap2->mode>am_areg + && ap1->mode!=am_immed) + fatal("INVALID INSTRUCTION"); + if ((long)new_ocode==0x7a6314) + bkpt();*/ +/* if (lineid==1157) + bkpt();*/ +#endif +#ifdef DB_POSSIBLE + new_ocode->line=lineid; +#endif + add_peep(new_ocode); +} + +void g_coder(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2) { +/* + * generate a code sequence and put it in front of the list + */ + struct ocode *new_ocode; + new_ocode = (struct ocode *) xalloc((int) sizeof(struct ocode), OCODE+G_CODE); + new_ocode->opcode = op; + new_ocode->length = len; + new_ocode->oper1 = ap1; + new_ocode->oper2 = ap2; +#ifdef DB_POSSIBLE + new_ocode->line=lineid; +#endif + if (peep_head == 0) { + /* must use add_peep to take care of peep_tail */ + add_peep(new_ocode); + } else { + new_ocode->back = 0; + new_ocode->fwd = peep_head; + peep_head->back = new_ocode; + peep_head = new_ocode; + /* peep_tail does not change */ + } +} + +/* should be in add_peep(), but SConvert would put it in the text */ +/* segment, preventing it from being modified */ +#ifndef VCG +xstatic struct ocode *peep_tail CGLOB; +#endif + +void add_peep(struct ocode *new_ocode) { +/* + * add the ocode pointed to by new to the peep list. + */ + if (peep_head == 0) { + peep_head = peep_tail = new_ocode; + } else { + new_ocode->back = peep_tail; + peep_tail->fwd = new_ocode; + peep_tail = new_ocode; + } +#ifndef NOFLOAT + if (new_ocode->opcode==op_jsr && new_ocode->oper1->mode==en_nacon) { + struct enode *ep=new_ocode->oper1->offset; + char *s=ep->v.ensp; + if (!strcmp("iround",s) || !strcmp("uround",s) || !strcmp("ifloor",s)) { + int lab=nxtlabel(); +#ifdef AS + ep->v.enlab=label( +#endif + ep->v.ensp=strsave(s[0]=='i'?str(ffpftol):str(ffpftou)) +#ifdef AS + ) +#endif + ; + g_code(s[1]=='r'?op_bhs:op_bge, 1, mk_label(lab), NIL_AMODE); + g_code(s[1]=='r'?op_addq:op_subq, 4, mk_immed(1), + (struct amode *) xalloc((int) sizeof(struct amode), AMODE)); + #ifdef NO_CALLOC + #error Above line bugs. + #endif + g_label(lab); + } + } +#endif +} + +extern unsigned int pos; +void g_label(unsigned int labno) { +/* + * add a compiler-generated label to the peep list. + */ +#ifdef NEWLAB + struct lbls *new_ocode; +/* if (pos==0x25D2 && labno==1) + printf("ghio");*/ + new_ocode = (struct lbls *) xalloc((int) sizeof(struct lbls), OCODE+G_LABEL); + new_ocode->opcode = op_label; + new_ocode->lab = labno; + add_peep((struct ocode *)new_ocode); +#else + struct ocode *new_ocode; + new_ocode = (struct ocode *) xalloc((int) sizeof(struct ocode), OCODE+G_LABEL); + new_ocode->opcode = op_label; + new_ocode->oper1 = mk_immed((long) labno); + add_peep(new_ocode); +#endif +} + +void flush_peep() { +/* + * output all code and labels in the peep list. + */ +#ifndef AS + register struct ocode *ip; + register int line; +#endif +#ifdef SHOWSTEP + printf("\npeep"); +#endif + opt3(); /* do the peephole optimizations */ +#ifdef SHOWSTEP + printf(" ok "); + printf("\nflush"); +#endif + _peep_head=peep_head; +#ifndef AS + ip = peep_head; + line = -1; + if (DEBUG && func_sp) + fprintf(output,"; function '%s'\n",func_sp->name); + while (ip != 0) { + if (ip->opcode == op_label) + put_label((unsigned int) getlab(ip)); + else { + #ifdef DB_POSSIBLE + if (DEBUG && line!=ip->line) + fprintf(output,"; line %d\n",line=ip->line); + #endif + put_code(ip->opcode, ip->length, ip->oper1, ip->oper2); + } + ip = ip->fwd; + } + if (DEBUG) + fprintf(output,"; end of function\n"); +#else + scope_head = peep_head; +#endif + peep_head = 0; +#ifdef SHOWSTEP + printf(" ok "); +#endif +} + +static void peep_delete(struct ocode *ip) { +/* + * delete an instruction referenced by ip + */ + if (ip == 0) + ierr(PEEP_DELETE,1); + + if (ip->back) { + if ((ip->back->fwd = ip->fwd) != 0) + ip->fwd->back = ip->back; + next_ip = ip->back; + } else { + if ((peep_head = ip->fwd) != 0) + peep_head->back = 0; + next_ip = peep_head; + } +} + +static void peep_pea(struct ocode *ip) { +/* + * changes lea ,An + pea (An) to pea + * The value of An is not needed (An is scratch register) + * CAVEAT code generator modifier! + */ + struct ocode *prev; + if (ip->oper1->mode != am_ind) + return; + if ((prev = ip->back) == 0) + return; + if (prev->opcode == op_lea && prev->oper2->preg == ip->oper1->preg + && ip->oper1->preg <= MAX_ADDR) { + prev->opcode = op_pea; + prev->oper2 = 0; + peep_delete(ip); + } +} + +static void peep_lea(struct ocode *ip) { +/* + * changes lea ,An + move.l An,Am to lea ,Am + * -- the value of An is not needed (An scratch, Am typically tempref) + * and lea ,An + move.* (An),An to move.* ,An + * CAVEAT code generator modifier! + */ + struct ocode *next; + reg_t reg; + restart: + if ((next = ip->fwd) == 0 +#if defined(AS) && defined(ASM) + || next->opt +#endif + ) + return; + if (next->opcode == op_move && ip->oper2->preg <= MAX_ADDR && + next->oper1->mode == am_areg && next->oper1->preg == ip->oper2->preg + && next->oper2->mode == am_areg && next->oper2->preg > MAX_ADDR) { + ip->oper2 = next->oper2; + peep_delete(next); + goto restart; + } + /* lea ,An + move.* (An),An => move.* ,An */ + if (next->opcode == op_move && next->oper1->mode == am_ind) + if (((reg=next->oper1->preg) == ip->oper2->preg) && next->oper2->mode == am_areg && + (reg==next->oper2->preg)) { + ip->opcode = op_move; + ip->length = next->length; + peep_delete(next); + } +} + +static void peep_move(struct ocode *ip) { +/* + * peephole optimization for move instructions. + * makes quick immediates when possible (redundant for most assemblers). + * changes move #0 to clr except on address registers + * changes move #0 to address registers to sub An,An + * changes long moves to address registers to short when possible. + * changes move immediate/areg to stack to pea. + * changes move immediate to An to lea. + * deletes move , (The code generator does not know that this sets + * the flags, and it is necessary for peep_and + * to work correctly if ea is am_dreg) + */ + struct enode *ep; +#ifdef ADVANCED_MEMORY_MOVE + struct ocode *next; +#endif + + if (equal_address(ip->oper1, ip->oper2) && +/* + * move.w An,An changes the contents of An through sign extension + */ + (ip->oper1->mode != am_areg || ip->length != 2)) { + peep_delete(ip); + return; + } + if ((ip->oper1->mode == am_areg || ip->oper1->mode == am_immed) + && ip->oper2->mode == am_adec && ip->oper2->preg == 7 + && ip->length == 4) { + ip->opcode = op_pea; + ip->length = 0; + ip->oper1 = copy_addr(ip->oper1); + am_doderef(ip->oper1->mode); + ip->oper2 = 0; + return; + } +//#if 0 +#ifdef ADVANCED_TEMP_REGS +#ifndef INFINITE_REGISTERS + if (ip->oper1->mode==am_dreg && ip->oper1->preg<=MAX_DATA + && ip->oper2->mode==am_dreg) { + struct ocode *ip_save=ip; + reg_t a=ip->oper1->preg,b=ip->oper2->preg,s=ip->length; + struct amode *ap,*destap=ip->oper2; + /* BUGGY: we should check if da isn't used afterwards... + * Currently, g_assign does in such way that it returns Db + * rather than Da, so it should work fine in most cases, + * but it might fail eg with custom asm statements */ + ip=ip->back; + while (ip) { + switch (ip->opcode) { + case op_label: + case op_jsr: + case op_bxx: + case op_dbxx: + case op_dc: // this might mean op_jsr... + return; + case op_ext: + if (ip->oper1->mode==am_dreg && ip->oper1->preg==a) { + s=ip->length>>1; + break; + } + if ((ap=ip->oper1) && ap->mode==am_dreg && ap->preg==b) { +#ifdef PC + if (ip->length && ip->length<=s) + fatal("OP DISCARDED BY ASSIGNMENT"); + else +#endif + return; + } + break; + case op_clr: + ap=ip->oper1; + goto check_ok; + case op_move: + case op_moveq: + case op_lea: + ap=ip->oper2; + check_ok: + if (ap->mode==am_dreg && ap->preg==a) { + if (ip->length && ip->lengthoper1) && ((ap->mode==am_dreg && ap->preg==b) || + (ap->mode==am_indx2 && ap->sreg==b))) + return; + if ((ap=ip->oper2) && ap->mode==am_indx2 && ap->sreg==b) + return; + if ((ap=ip->oper2) && ap->mode==am_dreg && ap->preg==b) { +#ifdef PC + if (ip->length && ip->length<=s) + fatal("OP DISCARDED BY ASSIGNMENT"); + else +#endif + return; + } + } + ip=ip->back; + } + ierr(UNINIT_TEMP,1); + ok_atr: + next_ip=ip; + ip=ip_save; + while (ip!=next_ip) { + if (ip->oper1 && ip->oper1->mode==am_dreg && ip->oper1->preg==a) + ip->oper1=destap; + if (ip->oper2 && ip->oper2->mode==am_dreg && ip->oper2->preg==a) + ip->oper2=destap; + ip=ip->back; + } + if (ip->opcode==op_clr) + ip->oper1=destap; + else ip->oper2=destap; + return; + } +#endif +#endif +#ifdef ADVANCED_MEMORY_MOVE + /* try to use post-increment where possible */ + /* (might be improved to allow for interstitial instructions, but + beware of modifications of _any_ of _both_ indexing registers...) */ + if (ip->oper2->mode == am_indx && (next=ip->fwd) && next->opcode==op_move + && next->oper2->mode == am_indx && next->oper2->preg == ip->oper2->preg + && next->oper2->offset->v.i-ip->oper2->offset->v.i==ip->length) { + int reg=-1; +#ifndef INFINITE_REGISTERS + if (arsearch(0,ip)) + reg=8; + else if (arsearch(1,ip)) + reg=9; +#endif + if (reg IS_VALID) { + struct ocode *load = xalloc(sizeof(struct ocode),OCODE); + long offs; struct amode *ap; + load->opcode=op_lea; + load->oper1=ip->oper2; + load->oper2=mk_reg(reg); + load->line=ip->line; + load->back=ip->back; + load->fwd=ip; + load->back->fwd=load; + ip->back=load; + next=ip; + reg=ip->oper2->preg; + offs=ip->oper2->offset->v.i; + ap=mk_reg(reg); ap->mode=am_ainc; + do { + next->oper2=ap; + offs+=next->length; + next=next->fwd; + } while (next->opcode==op_move && next->oper2->preg==reg + && next->oper2->mode==am_indx + && next->oper2->offset->v.i==offs); + } + } +#endif + if (ip->oper1->mode != am_immed) + return; +#ifdef ADVANCED_MEMORY_MOVE + /* optimize contiguous -(an)/(an)+ assignments */ + restart_advmove: + if (am_is_increment(ip->oper2->mode) && ip->length<=2 && (next=ip->fwd) + && next->opcode==op_move && ip->oper1->offset->nodetype==en_icon + && next->oper1->mode == am_immed && next->oper2->mode==ip->oper2->mode + && next->length==ip->length + && next->oper1->offset->nodetype==en_icon) { + unsigned short a,b; /* very important *not* to be long's !!! */ + a=(unsigned short)ip->oper1->offset->v.i,b=(unsigned short)next->oper1->offset->v.i; + if (ip->oper2->mode==am_adec) + b=a,a=(unsigned short)next->oper1->offset->v.i; + ip->oper1=copy_addr(ip->oper1); + ip->oper1->offset = + mk_icon((ip->length==2?((long)a<<16)|b:(long)(unsigned short)((a<<8)|(unsigned char)b))); + ip->length<<=1; + peep_delete(next); + if (ip->back->opcode==op_move) { + next_ip=ip->back; + return; + } else goto restart_advmove; + /* + move.b #0,(a0)+ <- + move.b #0,(a0)+ + move.b #0,(a0)+ + move.b #0,(a0)+ + -> + move.w #0,(a0)+ <- + move.b #0,(a0)+ + move.b #0,(a0)+ + -> + clr.w (a0)+ + move.b #0,(a0)+ <- + move.b #0,(a0)+ + -> + clr.w (a0)+ <- + move.w #0,(a0)+ + -> + clr.w (a0)+ <- + move.w #0,(a0)+ + -> + move.l #0,(a0)+ <- + -> + clr.l (a0)+ <- + */ + } +#endif + + ep = ip->oper1->offset; + if (ip->oper2->mode == am_areg && ep->nodetype == en_icon) { + if (ep->v.i == 0) { + ip->length = 4; + ip->opcode = op_sub; + ip->oper1 = ip->oper2; + } else if (-32768 <= ep->v.i && ep->v.i <= 32767) + ip->length = 2; + return; + } + if (ip->oper2->mode == am_dreg && ep->nodetype == en_icon + && -128 <= ep->v.i && ep->v.i <= 127) { + ip->opcode = op_moveq; + ip->length = 0; + return; + } + if (ep->nodetype == en_icon && ep->v.i == 0) { + ip->opcode = op_clr; + ip->oper1 = ip->oper2; + ip->oper2 = 0; + return; + } + if (ip->oper2->mode == am_areg && ip->length == 4) { + next_ip = ip; + ip->opcode = op_lea; + ip->length = 0; + ip->oper1 = copy_addr(ip->oper1); + ip->oper1->mode = am_direct; + return; + } +} + +int equal_address(struct amode *ap1, struct amode *ap2) { +/* + * compare two address nodes and return true if they are equivalent. + */ + if (ap1 == 0 || ap2 == 0) + return 0; + if (ap1->mode != ap2->mode) + return 0; + switch (ap1->mode) { + case am_areg: + case am_dreg: + case am_ind: + return ap1->preg == ap2->preg; + case am_indx: + return ap1->preg == ap2->preg && + ap1->offset->nodetype == en_icon && + ap2->offset->nodetype == en_icon && + ap1->offset->v.i == ap2->offset->v.i; + case am_indx2: + case am_indx3: + return + ap1->preg == ap2->preg && + ap1->sreg == ap2->sreg && + ap1->slen == ap2->slen && + ap1->offset->nodetype == en_icon && + ap2->offset->nodetype == en_icon && + ap1->offset->v.i == ap2->offset->v.i; + } + return 0; +} + +static void peep_movem(struct ocode *ip) { +/* + * peephole optimization for movem instructions. movem instructions are used + * to save registers on the stack. if 1 or 2 registers are being saved we + * can convert the movem to move instructions. + */ + int i,mask,n,t,a,b=0; + struct ocode *root; + +#ifdef PC + a=1234; /* prevent a warning from being output - we can afford this on PC :) */ +#endif + + if (ip->oper1->mode == am_mask1) + mask = getop1(ip); + else mask = getop2(ip); + + t=1,n=2,i=16; + while (i--) { + if (mask & t) { + b=a,a=i; + if (--n<0) return; + } + t<<=1; + } + root=ip; + ip->opcode = op_move; + if ((i=1-n)) { + struct ocode *new_ocode = (struct ocode *) + xalloc((int) sizeof(struct ocode), OCODE); + new_ocode->opcode = op_move; + new_ocode->length = ip->length; + new_ocode->oper1 = copy_addr(ip->oper1); + new_ocode->oper2 = copy_addr(ip->oper2); +#ifdef DB_POSSIBLE + new_ocode->line=ip->line; +#endif + new_ocode->back = ip; + if ((new_ocode->fwd=ip->fwd)) + ip->fwd->back=new_ocode; + ip->fwd=new_ocode; + } + do { + if (ip->oper1->mode == am_mask1) { + if ((ip->oper1->preg = a) >= 8) { + ip->oper1->mode = am_areg; + ip->oper1->preg -= 8; +#ifdef INFINITE_REGISTERS + ip->oper1->preg += TAREGBASE-AREGBASE; +#endif + } else { + ip->oper1->mode = am_dreg; +#ifdef INFINITE_REGISTERS + ip->oper1->preg += TDREGBASE; +#endif + } + } else { + if ((ip->oper2->preg = 15 - a) >= 8) { + ip->oper2->mode = am_areg; + ip->oper2->preg -= 8; +#ifdef INFINITE_REGISTERS + ip->oper2->preg += TAREGBASE-AREGBASE; +#endif + } else { + ip->oper2->mode = am_dreg; +#ifdef INFINITE_REGISTERS + ip->oper2->preg += TDREGBASE; +#endif + } + } + ip=ip->fwd; + a=b; + } while (i--); + next_ip=root; /* optimize move.l An,-(a7) => pea (An) */ +} + +int drsearch(int r,struct ocode *ip) { + while ((ip=ip->fwd)) { + struct amode *ap=ip->oper1; + int n=0; + do { + switch (ap->mode) { + case am_dreg: + if (ap->preg==r) + return n && op_destroy(ip->opcode); + case am_areg: + case am_ind: case am_adec: case am_ainc: case am_indx: + case am_indx3: + break; + case am_indx2: + if (ap->sreg==r) + return 0; + break; + } + n++; + } while ((ap=ip->oper2)); + } + return 1; +} + +int arsearch(int r,struct ocode *ip) { + struct amode *ap; int n,z; +// printf("$%d",r); + z=0; + while ((ip=ip->fwd) && ip->opcode!=op_rts) { + if (ip->opcode==op_label) continue; +#ifdef INFINITE_REGISTERS + if (ip->opcode==_op_cleanup_for_external_call) continue; +#endif + z++; + ap=ip->oper1; + n=0; + do { + switch (ap->mode) { + case am_areg: + if (ap->preg==r) { +// printf("*%d ",z); + return n && op_destroy(ip->opcode); + } + case am_dreg: + break; + case am_indx3: + if (ap->sreg==r) { +// printf("-%d ",z); + return 0; + } + /* FALL THROUGH */ + case am_ind: case am_adec: case am_ainc: case am_indx: + case am_indx2: + if (ap->preg==r) { +// printf("-%d ",z); + return 0; + } + break; + } + n++; + } while ((ap=ip->oper2) && n==1); + } +// printf("/%d ",z); + return 1; +} + +static void peep_addsub(struct ocode *ip, enum (e_op) op) { +/* + * peephole optimization for add/sub instructions. +A* changes add/sub.* Rn,An; move (An),X to move 0(An,+/- Rn.*),X +A* changes add/sub.* Rn,An; move x(An),X to move x(An,+/- Rn.*),X +A* changes add/sub #x,An; move 0(An,Rn.*),X to move x(An,+/- Rn.*),X + * makes quick immediates out of small constants (redundant for most as's). + * change add/sub immediate to address registers to lea where possible +A* and try to avoid operand volatilizing when doing so + */ + struct enode *ep; + struct ocode *next=ip->fwd; +#ifdef ADV_OPT + int reg; + if (next +#ifdef AS + && !next->opt +#endif + && next->opcode==op_move + && ip->oper2->mode==am_areg && (reg=ip->oper2->preg)==next->oper1->preg + && arsearch(reg,next)) { + int sub=op-op_add,ok=0,sz=ip->length,sreg=ip->oper1->preg; + long offs=next->oper1->offset?getop1(next):0; +/* infunc("InitLevel") + bkpt();*/ + ok=next->oper1->mode; + if (ip->oper1->mode==am_dreg || ip->oper1->mode==am_areg) { + if (ok==am_ind) + offs=0; + else if (ok!=am_indx) + ok=0; + /* if we do the conversion, select am_indx2/3 appropriately */ + if (ok) + ok=ip->oper1->mode-am_dreg+am_indx2; + } else if (ip->oper1->mode==am_immed) { + sz=next->oper1->slen; + sreg=next->oper1->sreg; + offs=getop1(ip); + if (sub) offs=-offs; + sub=0; + if (ok==am_indx3) + sreg+=AREGBASE; + else if (ok!=am_indx3) + ok=0; + } else ok=0; + if (ok && offs>=-128 && offs<128) { + if (sub) ip->opcode=op_neg,ip->oper2=NULL; + else peep_delete(ip); + next->oper1=copy_addr(next->oper1); + next->oper1->mode=ok; + next->oper1->slen=sz; + next->oper1->sreg=sreg; + next->oper1->offset=mk_icon(offs); + return; + } + } +#endif + if (ip->oper2->preg == STACKPTR-AREGBASE && ip->length == 2) { /* alloca... */ + last_param_pop = NULL; + } + if (ip->oper1->mode == am_immed) { + ep = ip->oper1->offset; + if (ip->oper2->mode != am_areg) + ip->opcode = op+op_addi-op_add; + if (ep->nodetype != en_icon) + return; +#ifdef POP_OPT + if (ip->oper2->preg == STACKPTR-AREGBASE && + ip->oper2->mode == am_areg && ip->length == 4) { /* parameter popping */ + if (last_param_pop) + ep->v.i+=getop1(last_param_pop), peep_delete(last_param_pop); + last_param_pop = ip; + } +#endif +/* if (!ep->v.i) { // unnecessary + peep_delete(ip); + return; + }*/ + if (1 <= ep->v.i && ep->v.i <= 8) { + ip->opcode = op+op_addq-op_add; + return; + } + if (-8 <= ep->v.i && ep->v.i <= -1) { + ip->opcode = op==op_add?op_subq:op_addq; + ep->v.i = -ep->v.i; + return; + } + if (ip->oper2->mode == am_areg && isshort(ep)) { + ip->oper1 = copy_addr(ip->oper1); + ip->oper1->mode = am_indx; + ip->oper1->preg = ip->oper2->preg; + if (op==op_sub) ip->oper1->offset=mk_icon(-getop1(ip)); + ip->length = 0; + ip->opcode = op_lea; + next_ip = ip; +#ifdef ADV_OPT + if (ip->back && ip->back->opcode==op_move && ip->back->oper2->mode==am_areg + && ip->back->oper2->preg==ip->oper1->preg + && ip->back->oper1->mode==am_areg + && arsearch(ip->oper1->preg,ip)) + ip->oper1->preg=ip->back->oper1->preg, peep_delete(ip->back); +#endif + return; + } + } +} + +static void peep_and(struct ocode *ip) { +/* + * conversion of unsigned data types often yields statements like + * move.b source,d0 + andi.l #255,d0 + * which should be converted to + * clr.l d0 + move.b source,d0 + * deletes and #-1 + */ + struct ocode *prev; + int size; + long arg; + if (ip->oper1->mode != am_immed || + ip->oper1->offset->nodetype != en_icon) + return; + arg = getop1(ip); + /* + * and #-1 does only set flags, which the code generator does not know + */ + if (arg == -1) { + peep_delete(ip); + return; + } + if (ip->oper1->mode != am_immed || + (arg != 255 && arg != 65535)) + return; + + size = (arg == 255) ? 1 : 2; + + /* move.b ,dn; and.* #$FF,dn condition que != x(An,Dn) */ + /* move.w ,dn; and.* #$FFFF,dn condition que != x(An,Dn) */ + if ((prev = ip->back) == 0 || prev->length != size + || prev->opcode != op_move + || ip->oper2->mode != am_dreg || prev->oper2->mode != am_dreg + || ip->oper2->preg != prev->oper2->preg + || (prev->oper1->mode == am_indx2 && + prev->oper1->sreg == prev->oper2->preg)) + return; + + prev->length = ip->length; + ip->length = size; + prev->opcode = op_clr; + ip->opcode = op_move; + ip->oper1 = prev->oper1; + prev->oper1 = prev->oper2; + prev->oper2 = 0; + + next_ip = prev; +} + +static void peep_clr(struct ocode *ip) { +/* + * removes consecutive clr-statements + * + */ + struct ocode *prev; + + if ((prev = ip->back) == 0 || prev->opcode != op_clr || + !equal_address(ip->oper1, prev->oper1)) + return; + + if (prev->length < ip->length) + prev->length = ip->length; + + peep_delete(ip); +} + +static void peep_cmp(struct ocode *ip) { +/* + * peephole optimization for compare instructions. + * changes compare #0 to tst + * + */ + struct enode *ep; + if (ip->oper1->mode != am_immed) + return; + ep = ip->oper1->offset; + if (ip->oper2->mode == am_areg) + /* cmpa.w extents the first argument automatically */ + { + if (isshort(ep)) + ip->length = 2; + return; + } + ip->opcode = op_cmpi; + if (ep->nodetype != en_icon || ep->v.i != 0) + return; + ip->oper1 = ip->oper2; + ip->oper2 = 0; + ip->opcode = op_tst; + next_ip = ip; +} + +static void peep_tst(struct ocode *ip) { +/* + * deletes a tst instruction if the flags are already set. + */ + struct ocode *prev,*next; + enum(e_op) op; + prev = ip->back; + if (prev == 0) + return; +/* + * All the following cases used to be checked with an obscure + * if-statement. There was an error in it that caused prev->oper2->mode + * to be referenced even if prev->opcode is op_clr. (This yields a NIL- + * pointer reference. + * I threw all this stuff away and replaced it by this case-statement. + * This is much more readable. + */ + switch (prev->opcode) { + case op_label: + case op_dc: + case _op_asm: + case _op_adj: +/* + * List all pseudo-instructions here. Of course, they do not do + * anything. + */ + return; + + case op_move: +/* + * A move TO an address register does not set the flags + */ + if (prev->oper2->mode == am_areg) + return; + case op_moveq: + case op_clr: + case op_ext: +/* + * All other move and clr instructions set the flags according to + * the moved operand, which is prev->oper1 + */ + if (equal_address(prev->oper1, ip->oper1)) + break; + if (equal_address(prev->oper2, ip->oper1)) + break; + return; + case op_btst: case op_bset: case op_bclr: case op_bchg: + case op_cmp: + /* these instructions affect the flags in a non-standard way */ + case op_swap:/*[longword test]*/ + /* FALL THROUGH */ + case op_exg: + /* these instructions don't affect the flags */ + return; + default: +/* + * All instructions that have a target set the flags according to the + * target (prev->oper2) + * Note that equal_address may be called with a NIL pointer -> OK for clr + */ + next = ip->fwd; + if (next && ((op=next->opcode)==op_beq || op==op_bne) + && !(next->fwd && (op=next->fwd->opcode)>=_op_bcond_min && op<=_op_bxx_max)) + if (equal_address(prev->oper2, ip->oper1)) + break; + return; + } +/* + * We come here if the flags are already set, thus the tst + * instruction can be deleted. + */ + if (ip->length==prev->length) + peep_delete(ip); +} + +static void peep_uctran(struct ocode *ip) { +/* + * peephole optimization for unconditional transfers. deletes instructions + * which have no path. applies to bra, jmp, and rts instructions. + */ + while (ip->fwd != 0 && ip->fwd->opcode != op_label) + peep_delete(ip->fwd); + next_ip=ip->fwd; +} + +static void peep_bxx(struct ocode *ip) { +/* + * optimizes conditional branch over a bra. + */ + struct ocode *next = ip->fwd; + if (next && next->opcode == op_bra) { + /* peep_uctran increases the 'hit' probability */ + peep_uctran(next); + while ((next = next->fwd) && next->opcode == op_label) + if (getoplab(ip) == getlab(next)) { + /* bxx \lab | bra \out | ... | \lab: + * => (peep_uctran) + * bxx \lab | bra \out | \lab: + * => + * byy \out | \lab: + */ + ip->fwd->opcode = revcond[(int)ip->opcode - (int)_op_bcond_min]; + ip=ip->fwd; + peep_delete(ip->back); + break; + } + } + if (ip->opcode==op_bhs && ip->back && ip->back->opcode==op_subq + && ip->back->oper1->offset->v.i==1 /* since oper1->mode is am_immed->en_icon */ + && ip->back->oper2->mode==am_dreg) + ip->opcode=op_dbra, + ip->oper2=ip->oper1, + ip->oper1=ip->back->oper2, + peep_delete(ip->back); +} + +static void peep_label(struct ocode *ip) { +/* + * if a label is followed by a branch to another label, the + * branch statement can be deleted when the label is moved + */ + struct ocode *prev, *next, *target; + long label; + last_param_pop = NULL; // reset function parameter popping optimization + prev = ip->back; + + if ((next = ip->fwd) == 0 || next->opcode != op_bra || next->oper1->offset->nodetype!=en_labcon) + return; + /* + * To make this fast, assume that the label number is really + * getoplab(next) + */ + label = getoplab(next); + if (label == getlab(ip)) + return; + target = peep_head; + /* + * look for the label + */ + while (target != 0) { + if (target->opcode == op_label + && getlab(target) == label) + break; + target = target->fwd; + } + /* we should have found it */ + if (target == 0) { +#ifdef VCG + if (vcg_lvl==VCG_MAX) +#endif + iwarn(PEEP_LABEL,1); + return; + } + /* move label */ + peep_delete(ip); + ip->fwd = target->fwd; + ip->back = target; + target->fwd = ip; + if (ip->fwd != 0) + ip->fwd->back = ip; + /* possibly remove branches */ + /* in fact, prev is always != 0 if peep_delete has succeeded */ + if (prev != 0) { + if (prev->opcode == op_bra || prev->opcode == op_jmp + || prev->opcode == op_rts) + peep_uctran(prev); + else if (prev->opcode == op_label) + next_ip=prev; /* so that peep_label will be called once again (this label + * might be aliased by other ones) */ + } +} + +void opt3(void) { +/* + * peephole optimizer. This routine calls the instruction specific + * optimization routines above for each instruction in the peep list. + */ +//#define NO_PEEP +#ifndef NO_PEEP + struct ocode *ip; + enum(e_op) instr; + next_ip = peep_head; + if (!opt_option) + return; + instr=-1; + last_param_pop = NULL; + while (next_ip != 0) { +/* if (ip->opcode==instr) + if (!(ip = ip->fwd)) break; + instr=ip->opcode;*/ + ip = next_ip; + next_ip = ip->fwd; +#ifdef AS + if (ip->opcode!=op_label && ip->opt) + continue; +#endif + switch (ip->opcode) { + case op_move: + peep_move(ip); + break; + case op_movem: + peep_movem(ip); + break; + case op_pea: + peep_pea(ip); + break; + case op_lea: + peep_lea(ip); + break; + case op_ext: { /* ext.l Dn ; add/sub Dn,Am (where Dn is a word) */ + struct ocode *nxt=ip->fwd; reg_t reg; + if (!nxt || (nxt->opcode!=op_add && nxt->opcode!=op_sub) +#if defined(AS) && defined(ASM) + || nxt->opt +#endif + || ip->length!=4 || nxt->oper1->mode!=am_dreg + || (reg=nxt->oper1->preg)!=ip->oper1->preg + || nxt->oper2->mode!=am_areg + || (reg>MAX_DATA && regexp[reg_t_to_regexp(reg)]->esize==4)) + break; + peep_delete(ip); + nxt->length=2; + } break; + case op_add: + case op_sub: + peep_addsub(ip,ip->opcode); + //peep_add/peep_sub(ip); + break; + case op_and: + peep_and(ip); + break; + case op_clr: + peep_clr(ip); + break; + case op_cmp: + peep_cmp(ip); + break; + case op_tst: + peep_tst(ip); + break; + case op_beq: + case op_bne: + case op_bgt: + case op_bge: + case op_blt: + case op_ble: + case op_blo: + case op_bls: + case op_bhi: + case op_bhs: + peep_bxx(ip); + /* FALL THROUGH */ + last_param_pop = NULL; // reset function parameter popping optimization + break; + case op_dbxx: + last_param_pop = NULL; // reset function parameter popping optimization + break; + case op_bra: + last_param_pop = NULL; // reset function parameter popping optimization + peep_uctran(ip); + /* delete branches to the following statement */ + { + struct ocode *p = ip->fwd; + long label = getoplab(ip); + while (p != 0 && p->opcode == op_label) { + if (getlab(p) == label) { + peep_delete(ip); + ip = 0; + break; + } + p = p->fwd; + } + } + if (!ip) + break; +#ifdef SPEED_OPT + if (next_ip && speed_opt_value>0) { /* then it's necessarily a label, due to peep_uctran */ + int i,lab=getoplab(ip); + struct ocode *p=peep_head,*s,*e; + do { + if (p->opcode==op_label && getlab(p)==lab) break; + } while ((p=p->fwd)); + if (!p) break; + s=p; + lab=getlab(next_ip); + i=speed_opt_value; + /* NOTE : we ought never stop copying on a 'bra', but rather go on */ + do { + if (!(p=p->fwd)) goto bad; + if (p->opcode==op_label) i++; /* don't count it as an instruction */ + else if (p->opcode>=_op_bcond_min && p->opcode<=_op_bxx_max + && getoplab(p)==lab) { + break; + } else if (p->opcode==op_bra || p->opcode==op_jmp || p->opcode==op_rts) + break; +#ifndef ALLOW_TWIN_STACK_OPS + else { + struct amode *ap=p->oper1; + if (ap && ap->mode==am_ainc && ap->preg==7) + goto bad; + ap=p->oper2; + if (ap && (ap->mode==am_areg || ap->mode==am_adec) && ap->preg==7) + goto bad; + } +#endif + } while (i--); + if (i>=0) { + struct ocode *prv,*nxt; + e=p; + p=s; + prv=ip->back; + next_ip=prv; + nxt=ip->fwd; + peep_delete(ip); + do { + p=p->fwd; + if (p->opcode!=op_label) { + struct ocode *n=(struct ocode *) + xalloc(sizeof(struct ocode), OCODE); + *n=*p; + if (p==e && p->opcode>op_bra) { /* we assume that op_jmpfwd,*nl; + int dlab; + if (pn->opcode==op_label) dlab=getlab(pn); + else { + dlab=nxtlabel(); + #ifdef NEWLAB + nl = (struct ocode *) xalloc((int) sizeof(struct lbls), OCODE); + nl->opcode = op_label; + ((struct lbls *)nl)->lab = dlab; + #else + nl = (struct ocode *) xalloc((int) sizeof(struct ocode), OCODE); + nl->opcode = op_label; + nl->oper1 = mk_immed((long)dlab); + #endif + p->fwd=nl; + nl->back=p; + nl->fwd=pn; + pn->back=nl; + } + n->opcode=revcond[p->opcode-_op_bcond_min]; + n->oper1=mk_label(dlab); + } + n->back=prv; + prv->fwd=n; + prv=n; + } + } while (p!=e); + prv->fwd=nxt; + nxt->back=prv; + next_ip=next_ip->fwd; + } + } +bad: +#endif + break; + case op_jmp: + case op_rts: + last_param_pop = NULL; // reset function parameter popping optimization + peep_uctran(ip); + break; + case op_label: + peep_label(ip); + break; + case _op_adj: + peep_delete(ip); + /* FALL THROUGH */ + case _op_asm: + last_param_pop = NULL; // reset function parameter popping optimization + break; + } + } +#endif +} +#ifdef VCG +#include "vcg.c" +#endif + +#endif /* MC680X0 */ +// vim:ts=4:sw=4 diff --git a/gtc/src/preproc.c b/gtc/src/preproc.c new file mode 100644 index 0000000..85e5871 --- /dev/null +++ b/gtc/src/preproc.c @@ -0,0 +1,572 @@ +/* + * GTools C compiler + * ================= + * source file : + * preprocessor + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#define USE_MEMMGT +#include "cglbdec.h" +#ifdef PCH +#include "pch.h" +#endif + +extern char *curname; +extern char *lptr; +char *inclname[10]; +FILE *inclfile[10]; +int inclifreldepth[10]; +int incldepth CGLOB; +#ifdef PCH +FILE *pchfile[20]; +char *pchdata[20] CGLOBL; +char *pchtab[20]; +#ifdef REQ_MGT +char pchname[20][15]; +char pchrequired[20]; +#endif +int pchnum CGLOB; +#endif +int inclline[10]; +int lineno CGLOB; +int lineid CGLOB; +int prevlineid CGLOB; +int flags CGLOB; +#ifdef PC +int verbose CGLOB; +#endif +#ifdef PC +int verbosity CGLOB; +#endif +int ifdepth CGLOB; +int ifreldepth CGLOB; +int ifcount[MAX_IF_DEPTH]; +int ifval[MAX_IF_DEPTH]; +int ifhas[MAX_IF_DEPTH]; +int ifskip CGLOB, ifsd CGLOB; + +HTABLE defsyms CGLOBL; + +extern int getline(int f); + +extern TYP *expression(); +extern unsigned char id_are_zero; + +int doinclude( +#ifdef PCH + int pch +#endif + ); + +extern enum(e_sym) forbid; +xstatic int pp_old_forbid CGLOB; +xstatic int pp_old_crc CGLOB; +xstatic char pp_old_id[MAX_ID_LEN+1]; + +/*static int mem_if=0,mem_def=0; +#define MEM_USE(x,s) mem_##x-=glbmem; s mem_##x+=glbmem;*/ + +int ppquit() { + if (pp_old_forbid IS_VALID) { + forbid=pp_old_forbid; + if (pp_old_forbid==id) memcpy(lastid,pp_old_id,MAX_ID_LEN+1), lastcrc=pp_old_crc; + } +#ifdef MACRO_PPDIR + if (*lptr) lptr=strchr(lptr,'\n')+1; + if (!*lptr) return getline(incldepth == 0); + else return 0; +#else + return getline(incldepth == 0); +#endif +} + +#if 0 +char *strend(char *s) { + while (*s++); + return s-1; +} +#endif + +int preprocess() { + if ((pp_old_forbid=forbid)==id) memcpy(pp_old_id,lastid,MAX_ID_LEN+1), pp_old_crc=lastcrc, + forbid=-1; + ++lptr; // skip '#' + lastch = ' '; + getch(); + getsym(); /* get first word on line */ + if(lastst != id && lastst != kw_if && lastst != kw_else) { + uerrc("preprocessor command expected"); + return ppquit(); + } +/* if (!strcmp(curname,"compat.h") && lineno>=23) + bkpt();*/ +/* if (!strcmp(curname,"messages.c") && lineno>=0) + bkpt();*/ + if (lastst == kw_if /*!strcmp(lastid,"if")*/ || !strcmp(lastid,"elif")) { + struct enode *ep; TYP *tp; enum(e_bt) typ; + int v=lastst==kw_if; + if (!v) ifskip=ifhas[ifdepth]; + if (ifskip) return doif(-1,v); +#ifndef MACRO_PPDIR + strcpy(lptr," ] "); // so that getsym() in the new expression will + getsym(); // not read any new line +#else + { + char *q=strchr(lptr,'\n'); + memmove(q+3,q,strlen(q)+1); + memcpy(q," ] ",3); + getsym(); + } +#endif + tmp_use(); + id_are_zero++; + tp=expression(&ep); + id_are_zero--; + if (!tp || lastst!=closebr) error(ERR_EXPREXPECT); + else if ((typ=tp->type)==bt_void || typ==bt_pointer) error(ERR_INTEGER); + else { + opt0(&ep); + if (ep->nodetype!=en_icon) error(ERR_CONSTEXPECT); + else { int w=doif(ep->v.i!=0,v); tmp_free(); return w; } + } + tmp_free(); + return ppquit(); + } else if (!strcmp(lastid,"ifdef") || !strcmp(lastid,"ifndef")) { + int v=lastid[2]!='d'; + if (ifskip) return doif(-1,1); + skipspace(); + if ((lastch>='A'&&lastch<='Z') || (lastch>='a'&&lastch<='z') + || lastch=='_' || lastch=='$') { + getidstr(); + return doif(v ^ !!search(lastid,lastcrc,&defsyms),1); + } else error(ERR_IDEXPECT); + return ppquit(); + } else if (lastst == kw_else/*!strcmp(lastid,"else")*/) { + if (!ifreldepth) uerrc("'#else' unexpected"); + else if (!ifskip || ifdepth<=ifsd) { + if (--ifcount[ifdepth]!=0) uerrc("'#else' unexpected"); + else ifskip = ifval[ifdepth]; + } + return ppquit(); + } else if (!strcmp(lastid,"endif")) { + if (!ifreldepth) uerrc("'#endif' unexpected"); + else { + ifdepth--, ifreldepth--; + if (ifdepthbase); +#endif + progr_readtonow=0; +} +#endif +int doinclude( +#ifdef PCH + int pch +#endif + ) { + int rv; char c; + strcat(lptr," "); + skipspace(); + if ((c=lastch-'"') && c!='<'-'"') + goto incl_err; + getch(); + if (!((lastch>='A'&&lastch<='Z') || (lastch>='a'&&lastch<='z') + || lastch=='_' || lastch=='$' || lastch=='\\')) + goto incl_err; + getidstr(); /* get file to include, without extension */ +#ifdef PCH + if (!pch) { +#endif + inclline[incldepth] = lineno; + inclifreldepth[incldepth] = ifreldepth; +#ifdef GTDEV + inclread[incldepth] = progr_readtonow; + inclcoeff[incldepth] = progr_coeff; +#endif + inclname[incldepth] = curname; + inclfile[incldepth++] = input; /* push current input file */ + restart_h: + input = xfopen(lastid,"r",c); + if (!input) { + char *tigcclib_aliases = "all\0alloc\0args\0asmtypes\0assert\0bascmd\0basfunc\0basop\0cert\0compat\0ctype\0default\0dialogs\0dll\0error\0estack\0events\0files\0flash\0float\0gdraw\0graph\0graphing\0gray\0homescr\0intr\0kbd\0limits\0link\0math\0mem\0menus\0nostub\0peekpoke\0printf\0romsymb\0rsa\0setjmp\0sprites\0statline\0stdarg\0stddef\0stdio\0stdlib\0string\0system\0textedit\0timath\0unknown\0values\0vat\0version\0wingraph\0"; + while (*tigcclib_aliases) + if ( + #ifdef PC + !strncmp(lastid,tigcclib_aliases,strlen(tigcclib_aliases)) && !strcmp(lastid+strlen(tigcclib_aliases),".h") + #else + !strcmp(lastid,tigcclib_aliases) + #endif + ) { + #ifdef PC + strcpy(lastid,"tigcclib.h"); + #else + strcpy(lastid,"tigcclib"); + #endif + goto restart_h; + } else { + while (*tigcclib_aliases++); + } +// input = inclfile[--incldepth]; + uerr(ERR_CANTOPEN,lastid); +// _exit(18); + } + ifreldepth = 0; +#ifdef GTDEV + progr_initforcurfile(); +#endif + global_flag++; + curname = strsave(lastid); + global_flag--; +#ifdef PCH + } else { + char b[30]; +#ifdef REQ_MGT + int i=pchnum; + while (i--) + if (!strcmp(lastid,pchname[i])) + goto done; +#endif +#ifdef PC + sprintf(b,"%s.pch",lastid); +#else + sprintf(b,"zheader\\%s",lastid); +#endif + if (!(pchfile[pchnum] = xfopen(b, "rb", c))) { + if (pch<0) + goto done; + uerr(ERR_CANTOPEN,b); +// _exit(18); + } +#ifdef REQ_MGT + strcpy(pchname[pchnum],lastid); + pchrequired[pchnum]=0; +#endif +#ifdef PC + pchdata[pchnum] = malloc(150000); + fread(pchdata[pchnum],1,150000,pchfile[pchnum]); + if (w2ul(pchhead[pchnum]->magic)!= + ((long)'P'<<24)+((long)'C'<<16)+((long)'H'<<8) + || !(pchtab[pchnum] = malloc(w2us(pchhead[pchnum]->nID)))) { + fclose(pchfile[pchnum]); + goto incl_err; + } +#define w2s(x) ((short)w2us(x)) +#else + if (w2ul(((PCH_HEAD *)(pchdata[pchnum] = *(char **)(pchfile[pchnum])))->magic)!= + ((long)'P'<<24)+((long)'C'<<16)+((long)'H'<<8) + || !(pchtab[pchnum] = malloc((short)pchhead[pchnum]->nID))) { + fclose(pchfile[pchnum]); + goto incl_err; + } +#define w2s(x) ((short)(x)) +#endif + memset(pchtab[pchnum],0,w2s(pchhead[pchnum]->nID)); + pchnum++; + } +#endif +done: + if (lastch=='.') getch(),getidstr(); + c=c?'>':'"'; + if (lastch!=c) + uerr(ERR_PUNCT,c); + rv = getline(incldepth == 1); +#ifdef PCH + if (!pch) +#endif + lineno = 1; /* dont list include files */ + return rv; +incl_err: + error(ERR_INCLFILE); + return ppquit(); +} + +char *litlate(char *s); +extern int getch_noppdir; +int dodefine(int mode) { // 1: #define, -1 : #macro, 0 : #undef + SYM *sp,*ds; + int n=0,flags=0; +/* getsym();*/ + skipspace(); + if ((lastch>='A'&&lastch<='Z') || (lastch>='a'&&lastch<='z') + || lastch=='_' || lastch=='$') { + getidstr(); /* get past #define */ + } else { + error(ERR_DEFINE); + return ppquit(); + } + if (!mode) { + if (!symremove(lastid,&defsyms)) /* if we didn't unload anything, let's */ + pchsearch(lastid,PCHS_UNLOAD); /* try and unload the symbol */ + return ppquit(); + } +#ifdef AS + if (!strcmp(lastid,"NOSTUB")) + nostub_mode=1; +#endif +#ifdef ASM + if (asm_isreserved()) + flags|=PPSYM_ASM_KEYWORD; + if (asm_flag) + flags|=PPSYM_DEFINED_IN_ASM; +#endif + ++global_flag; /* always do #define as globals */ + sp = (SYM *)xalloc((int)sizeof(SYM), _SYM+DODEFINE); + sp->name = strsave(lastid); + sp->storage_class = sc_define; + if (lastch=='(') { + TABLE *tp; +/* if (lineid==0x1A) + bkpt();*/ + sp->tp=(TYP *)(tp=(TABLE *)xalloc((int)sizeof(TABLE), _TABLE+DODEFINE)); +#ifdef NO_CALLOC + tp->hash=0; + tp->head=tp->tail=NULL; +#endif + getsym(); + getsym(); + if (lastst!=closepa) { + while (1) { + SYM *arg; + n++; + if (lastst!=id) error(ERR_IDEXPECT); + else { + arg=(SYM *)xalloc((int)sizeof(SYM), _SYM+DODEFINE); + arg->name=strsave(lastid); +#ifdef NO_CALLOC + arg->tp=NULL; +#endif + insert(arg,(HTABLE *)tp); + } + getsym(); + if (lastst!=comma) break; + getsym(); + } + if (lastst==dots) { sp->storage_class = sc_vamac; getsym(); } + if (lastst!=closepa) needpunc(closepa); + } + if (!isspace(lastch)) // undo last getch()... + lptr--; +#ifdef NO_CALLOC + } else { + sp->tp=NULL; +#endif + } +#ifdef MACRO_PPDIR + if (mode<0) { + char *s=(char *)alloca(500),*p=s; + int n=499; + getch_noppdir++; + do { + if (getch()<0) error(ERR_DEFINE); + *p++=(/*lastch=='\n'?'\r':*/lastch); + } while (n-- && (lastch!='#' || *lptr!='e' || strncmp(lptr+1,"ndm",3))); + getch_noppdir--; + if (n<=0) error(ERR_DEFINE); + p-=2; // remove '\n' '#' + *p++=0; + n = p-s; + p = (char *)xalloc(n, STR); + memcpy(p,s,n); + sp->value.s=p; + } else +#endif + if (strlen(lptr)>1500) + uerrsys("definition too long (1500 characters max)"); + if (!(sp->value.s = litlate(lptr))) + uerrc("unbalanced quotes in #define"); +#ifdef FLINE_RC + if (!strcmp(sp->name,"USE_FLINE_ROM_CALLS")) + fline_rc=1; +#endif + if ((ds=search(sp->name,-1,&defsyms))) { + if (strcmp(sp->value.s,ds->value.s)) + uwarn("redefinition of macro '%s'",sp->name); + symremove(sp->name,&defsyms); + } + insert(sp,&defsyms); + sp->used=n+flags; + --global_flag; + return ppquit(); +} + +// x = result of the test (1 : true, 0 : false, -1 : ignore all branches) +// c = is it a #if ? (rather than a #elif) +int doif(int x,int c) { + if ((ifreldepth+=c,ifdepth+=c)>MAX_IF_DEPTH) uerrc("too many imbricated '#if's"); + else if (!ifreldepth) uerrc("'#elif' unexpected"); + else if (!ifskip || ifdepth<=ifsd) { + ifsd=ifdepth; + if (c) + ifhas[ifdepth] = x; + else + ifhas[ifdepth] |= x; + ifskip = (ifval[ifdepth] = x) - (ifcount[ifdepth] = 1); + } + if (x<0) { + ifhas[ifdepth] = x; + ifskip = x; + } + return ppquit(); +} +// vim:ts=4:sw=4 diff --git a/gtc/src/protos.h b/gtc/src/protos.h new file mode 100644 index 0000000..96601cc --- /dev/null +++ b/gtc/src/protos.h @@ -0,0 +1,329 @@ +// Auto-generated file, do not edit! + +#ifndef PROTOS_H_ +#define PROTOS_H_ + +enum OptionModes; +enum e_am; +enum e_bt; +enum e_node; +enum e_op; +enum e_sc; +enum e_sym; +struct _regsimg; +struct _stackimg; +struct amode; +struct bcd; +struct blk; +struct cse; +struct enode; +struct hstab; +struct ocode; +struct snode; +struct stab; +struct sym; +struct typ; + +struct typ *shiftop(struct enode **node); +void local_clean(void); /* remove local symbols from alsyms -- to be called just before rel_local */ +void g_label(unsigned int labno); +struct snode *casestmt(void); +void compile(void); +void dump_endnode(); +int blk_free(struct blk *bp1); +int complexity(struct enode *ep); +void check_table(struct hstab *table); +struct typ *nameref(struct enode **node); +int en_dir_cost(struct enode *ep); +void extscan(unsigned char *ext); +void genstorage(struct sym *sp, int align); +void freeregs(struct _regsimg *img); /* used by g_fcall */ +struct amode *mk_immed(long i); +char *litlate(char *s); +struct snode *forstmt(void); +struct amode *g_xmul(struct enode *node, int flags, enum(e_op) op); +struct enode *mk_icon(long i); +void getsym(); +struct typ *equalops(struct enode **node); +void genfunc(struct snode *stmt); +struct typ *copy_type(struct typ *s); +void repcse(struct snode *block); +int internal(char *s); +void genbyte(int val); +struct typ *bitor(struct enode **node); +void fill(int n); +void scan(struct snode *block); +struct snode *retstmt(void); +void out_init(); +void _scr_main(); +void add_code(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2, int line); +char *create_ti_file(int calc,int tigl_type,char *name,char *folder,char *content,unsigned long content_size,unsigned long *ti_file_size); +long intexpr(); +int bitwise_reduction(unsigned long x,int *size); +void double2bcd(double d,struct bcd *bcd); +struct amode *g_aslogic(struct enode *node, int flags, enum(e_op) op); +long auto_init(long offs,struct typ *typ,struct typ **tpp,int brace_level,int offmod,int stroff); +void initstack(); +void falsejp(struct enode *node, unsigned int lab); +int getch(); +int doif(int x,int c); +void temp_inv(void); +long inittype(struct typ *tp,struct typ **tpp); +void do_warning(char *s, ...); +struct typ *forcefit(struct enode **node1, struct typ *tp1, struct enode **node2, struct typ *tp2); +void collect(int g); +int movem(short x); +void g_code(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2); +struct enode *parmlist(struct sym *f); +int isbyte(struct enode *node); +void clean_up(); +void getrawid(); +struct typ *deref(struct enode **node, struct typ *tp); +long strip_icon(long i, enum(e_bt) type); +void genword(int val); +int getid(int c); +void d_snode(struct snode **node); +struct snode *exprstmt(void); +struct typ *relation(struct enode **node); +int integral(struct typ *tp); +void g_bitmancode(enum(e_op) op,int size,struct amode *ap1,struct amode *ap2); +struct amode *g_offset(struct amode *ap, int off); +struct amode *as_fcall(struct enode *node, int flags, char *libname); +struct snode *contstmt(void); +int vcg_init(); +long push_param(struct enode *ep); +int label(char *s); +struct amode *get_asmparam(); +struct amode *g_fderef(struct enode *node, struct amode *ap0, int flags); +int req_all_aregs(struct enode *plist,int rp_dn,int rp_an); +void genstmt(struct snode *stmt); +int vcg_cost(); +void useregs(struct _regsimg *img); /* used by g_fcall */ +char *strend(char *s); +TI_SHORT process_attr(); +void dump_genfunc(struct snode *stmt); +void getidstr(); +int stringlit(char *s, int len); +void ds_free(void); +void scope_init(void); +void verbose_print_include(char *filename); +void tmp_use(); +struct sym *symremove(char *na, struct hstab *tab); +struct sym *search(char *na, int crc, struct hstab *tab); +void add_label(int lab); +void dump_startline(); +struct typ *cond_deref(struct enode **node, struct typ *tp); +struct amode *temp_addr(void); +struct amode *g_cast2(struct enode *ep, enum(e_bt) typ2, int flags); +void get_offset(struct amode *ap); +void scanexpr(struct enode *node, int duse); +void progr_initforcurfile(); +void move_pos(long diff); /* caution : only works in overwrite mode */ +void dump_newnode(char *name); +void fatal(char *message); +int arsearch(int r,struct ocode *ip); +void usestack(struct _stackimg *img); /* used by g_expr::en_compound */ +struct typ *bitand(struct enode **node); +FILE *xfopen(char *f,char *m,int sys); +int tst_const(struct enode *node); +long mod_mask(long i); +struct amode *mk_strlab(char *s); +void concat(struct stab *dest,struct stab *src); +struct amode *temp_data(void); +void rel_dualstack(void); +int pwrof2(long i); +void hashinit(struct hstab *t); +int eq_type(struct typ *tp1, struct typ *tp2); +void dodecl(enum(e_sc) defclass); +struct snode *gotostmt(void); +void g_coder(enum(e_op) op, int len, struct amode *ap1, struct amode *ap2); +struct typ *expression(struct enode **node); +struct snode *breakstmt(void); +int has_autocon(struct enode *ep); +struct snode *dostmt(void); +char *strsave(char *s); +void opt_compare(struct enode *node); +struct amode *g_asmod(struct enode *node, int flags); +int hexatoi(char *s); +struct ocode *new_code(int s); +void d_amode(struct amode **node); +int getline(int listflag); +void call_library(char *lib_name); +unsigned long _w2ul(TI_LONG *x); +int asm_isreserved(); +void dooper(struct enode **node); +short count_dn_an(struct enode *plist,int rp_dn,int rp_an); +struct amode *g_compound(struct snode *st, int flags); +void repexpr(struct enode *node); +void initpch(); +void genfloat(double val); +void asm_searchkw(); +struct amode *g_deref(struct enode *node, enum(e_bt) type, int flags, long size); +int free_data(void); +int indir_num(struct typ *tp); +int _getline(int listflag,char *base); +struct typ *asnop(struct enode **node); +struct amode *g_fcall(struct enode *node, int flags); +void warn_usr(char *s,...); +int tst_ushort(struct enode *node); +void scope_flush(void); +void rewrite(long size); +struct amode *g_aincdec(struct enode *node, int flags, enum(e_op) op); +void funcbottom(void); +struct typ *bitxor(struct enode **node); +struct amode *g_addsub(struct enode *node, int flags, enum(e_op) op); +struct snode *statement(void); +void searchkw(void); +void opt0(struct enode **node); +void decl(struct hstab *table); /* table is used only for enum members */ +struct amode *g_index(struct enode *node); +void g_strlab(char *s); +struct enode *copynode(struct enode *node); +void expand_do(char *q,int len,char *in,char *inbound,int need_ds_update); +unsigned int getconst(enum(e_sym) s,enum(e_sym) e); +void opt1(struct snode *block); +long intexpr_notemp(); +int getasm_main(); +unsigned short _w2us(TI_SHORT *x); +struct amode *g_div(struct enode *node, int flags); +struct amode *mk_offset(struct enode *node); +unsigned long desire(struct cse *csp); +int equalnode(struct enode *node1, struct enode *node2); +void funcbody(struct sym *sp, char *names[], int nparms); +struct amode *g_commute(void *func,struct enode *node,int flags,enum(e_op) op,int dummy/*void *reversal*/); +void add_peep(struct ocode *new_ocode); +struct snode *ifstmt(void); +void locate(void); +void allocate(void); +size_t option_parse(size_t listc,char **listv,enum(OptionModes) ex_mode); +void opt3(void); +long auto_pad(long offs,int len,int offmod); +struct amode *g_asxor(struct enode *node, int flags); +void truejp(struct enode *node, unsigned int lab); +void opt4(struct enode **node); +void macro_expansion(char *in,char *inbound,int need_ds_update); +void insert(struct sym *sp,struct hstab *table); +void dumplits(); +struct amode *g_asdiv(struct enode *node, int flags); +struct amode *g_mod(struct enode *node, int flags); +struct amode *copy_addr(struct amode *ap); +int equal_address(struct amode *ap1, struct amode *ap2); +void gendouble(double val); +struct typ *commaop(struct enode **node); +void swap_nodes(struct enode *node); +int preprocess(); +void dump_addstr(char *name,char *v); +struct amode *g_alloca(struct enode *node); +struct snode *whilestmt(void); +struct amode *mk_rmask(unsigned int mask); +struct amode *mk_reg(int r); +void do_compile(); +void bitwise_optimize(struct enode *ep,long mode); +void out_close(); +unsigned int getconst2(enum(e_sym) e); +struct amode *func_result(int flags, long bytes); +struct amode *g_cast(struct amode *ap, enum(e_bt) typ1, enum(e_bt) typ2, int flags); +struct amode *g_asmul(struct enode *node, int flags); +int start_block(int m); // used in block() (func.c) +void error(int n); +void ds_allocatleast(unsigned int size); +struct typ *forceft2(struct enode **node1, struct typ *tp1, struct enode **node2, struct typ *tp2); +char *type_str(struct typ *tp); +struct amode *mk_label(unsigned int lab); +struct snode *loopstmt(void); +void asm_getsym(); +void d_ocodes(void); +void extload(unsigned char *ext); +void initsym(); +struct amode *g_shift(struct enode *node, int flags, enum(e_op) op); +void block(struct sym *sp); /* CAUTION : always requires a compound_done() after call */ +struct amode *g_ybin(struct enode *node, int flags, enum(e_op) op); +struct sym *gsearch(char *na,int crc); +int cast_ok(struct typ *tp1, struct typ *tp2, int need_physically_compatible); +void needpunc(enum(e_sym) p); +struct amode *mk_scratch(long size); +void dump_genstmt(struct snode *stmt); +void d_enode(struct enode **node); +int ap_hasbeenpushed(struct amode *ap); +struct amode *g_unary(struct enode *node, int flags, enum(e_op) op); +void append(struct sym **ptr_sp, struct hstab *table); +void checkstack(void); +void rel_global(); +void option_parse_all(enum(OptionModes) ex_mode); +int pchload(char *name,char *data,unsigned int flags,unsigned char *tabp, unsigned char *p0,TI_SHORT *extTab); +void my_fclose(FILE *f); +struct typ *andop(struct enode **node); +struct amode *g_expr(struct enode *node, int flags); +struct amode *g_assign(struct enode *node, int flags); +void rel_local(); +struct sym *mk_int(char *name); +struct snode *asmstmt(void); +unsigned long double2ffp(double d); +void decl1(void); +struct typ *orop(struct enode **node); +int alignment(struct typ *tp); +struct amode *g_asshift(struct enode *node, int flags, enum(e_op) op); +void closepch(); +void castback(long offset, struct typ *tp1, struct typ *tp2); +void dump_addreg(char *name,int v); +double floatexpr(); +void freeop(struct amode *ap); +void err_usr(int m,...); +struct typ *cast_op(struct enode **ep, struct typ *tp1, struct typ *tp2); +struct amode *g_asadd(struct enode *node, int flags, enum(e_op) op); +int tst_short(struct enode *node); +struct typ *mk_type(enum(e_bt) bt, int siz); +struct enode *mk_node(enum(e_node) nt, struct enode *v1, struct enode *v2); +void _repexpr(struct enode **ep); +struct typ *binlog(struct enode **node, struct typ *(*xfunc)(), enum(e_node) nt, enum(e_sym) sy); +struct amode *func_result2(int flags, long bytes, int reg); +struct typ *force_cast_op(struct enode **ep, struct typ *tp1, struct typ *tp2); +void _exit(int code); +struct amode *g_mul(struct enode *node, int flags); +void tmp_free(); +struct snode *switchstmt(void); +void g_pop(int reg, enum(e_am) rmode, int number); +struct snode *compound(int no_init); +int isshort(struct enode *node); +void flush_peep(); +void put_label(int lab); +int not_lvalue(struct enode *node); +struct amode *mk_smask(unsigned int mask); +int datalit(char *s, int len); +void verbose_print_searchdirs(); +void structassign(struct amode *ap1, struct amode *ap2, long size, int mode); +int pchsearch(char *id,int mode); /* returns 0 if not PCH, 1 if PCH/def, -1 if PCH/init */ +struct snode *labelstmt(void); +int getsch(int flag); +struct amode *g_xbin(struct enode *node, int flags, enum(e_op) op); +void genfuncbegin(void); +int crcN(char *na); +struct typ *binop(struct enode **node, struct typ *(*xfunc)(), enum(e_node) nt, enum (e_sym) sy); +void bsort(struct cse **list); +int macro_expand(char *id,int crc/* may equal -1 */,char *in,char *oldin,char *inbound,int need_ds_update); +void g_push(int reg, enum(e_am) rmode, int number); +int checkcases(struct snode *head); +struct amode *g_hook(struct enode *node, int flags); +void insert_macros(char *p); +struct typ *exprnc(struct enode **node); +void genptr(struct enode *node); +int *_xalloc(int siz); +int castbegin(enum(e_sym) st); +void skipspace(); +int ppquit(); +void dump_addint(char *name,int v); +void validate(struct amode *ap); +int radix36(char c); +struct amode *mk_legal(struct amode *ap, int flags, long size); +struct typ *copy_type_global(struct typ *tp); +void freestack(struct _stackimg *img); /* used by g_expr::en_compound */ +char *fill_calcvar(char *buffer, char *input); +int getcache(enum(e_sym) f); +int vcg_done(); +void put_align2(void); +int dodefine(int mode); // 1: #define, -1 : #macro, 0 : #undef +int drsearch(int r,struct ocode *ip); +struct typ *conditional(struct enode **node); +void doinit(struct sym *sp, int align); + +#endif diff --git a/gtc/src/reg68k.c b/gtc/src/reg68k.c new file mode 100644 index 0000000..7a1434b --- /dev/null +++ b/gtc/src/reg68k.c @@ -0,0 +1,446 @@ +/* + * GTools C compiler + * ================= + * source file : + * register allocation + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +/* + * Register allocation (for the expression evaluation) + * This modules handles the management of scratch registers. + * It keeps track of the allocated registers and of the stack + */ + +#ifdef MC680X0 + +xstatic int next_data CGLOB, next_addr CGLOB; + +#ifndef INFINITE_REGISTERS +xstatic char dreg_in_use[MAX_DATA + 1] CGLOBL; +xstatic char areg_in_use[MAX_ADDR + 1] CGLOBL; + +xstatic struct reg_struct reg_stack[MAX_REG_STACK + 1] CGLOBL, + reg_alloc[MAX_REG_STACK + 1] CGLOBL; + +xstatic int reg_stack_ptr CGLOB; +xstatic int reg_alloc_ptr CGLOB; +#endif + +void g_push(int reg, enum(e_am) rmode, int number) { +#ifndef INFINITE_REGISTERS +/* + * this routine generates code to push a register onto the stack + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+G_PUSH); + ap->preg = reg; + ap->mode = rmode; + g_code(op_move, 4, ap, push_am); + reg_stack[reg_stack_ptr].mode = rmode; + reg_stack[reg_stack_ptr].reg = reg; + reg_stack[reg_stack_ptr].flag = number; + if (reg_alloc[number].flag) + ierr(G_PUSH,1); + reg_alloc[number].flag = 1; + /* check on stack overflow */ + if (++reg_stack_ptr > MAX_REG_STACK) + ierr(G_PUSH,2); +#else + fatal("GPUSH/infinite"); +#endif +} + +void g_pop(int reg, enum(e_am) rmode, int number) { +#ifndef INFINITE_REGISTERS +/* + * generate code to pop a register from the stack. + */ + struct amode *ap; + + /* check on stack underflow */ + if (reg_stack_ptr-- == 0) + ierr(G_POP,1); + /* check if the desired register really is on stack */ + if (reg_stack[reg_stack_ptr].flag != number) + ierr(G_POP,2); + /* check if the register which is restored is really void */ + if (rmode == am_dreg) { + if (dreg_in_use[reg] >= 0) + ierr(G_POP,3); + dreg_in_use[reg] = number; + } else { + if (areg_in_use[reg] >= 0) + ierr(G_POP,4); + areg_in_use[reg] = number; + } + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+G_PUSH); + ap->mode = rmode; + ap->preg = reg; + g_code(op_move, 4, pop_am, ap); + /* clear the push_flag */ + reg_alloc[number].flag = 0; +#endif +} + +void initstack() { +/* + * this routine should be called before each expression is evaluated to make + * sure the stack is balanced and all of the registers are marked free. + * This is also a good place to free all 'pseudo' registers in the + * stack frame by setting act_scratch to zero + */ +#ifndef INFINITE_REGISTERS + int i; + next_data = 0; + next_addr = 0; + for (i = 0; i <= MAX_DATA; i++) + dreg_in_use[i] = -1; + for (i = 0; i <= MAX_ADDR; i++) + areg_in_use[i] = -1; + reg_stack_ptr = 0; + reg_alloc_ptr = 0; +#else + next_data = FIRSTREG; + next_addr = FIRSTREG; +#endif + act_scratch = 0; +} + +//#if 0 +#ifndef __HAVE_STACK_IMAGE +#define __HAVE_STACK_IMAGE +typedef struct _stackimg { + int next_data,next_addr; +#ifndef INFINITE_REGISTERS + int reg_alloc_ptr,reg_stack_ptr; + char dreg_in_use[MAX_DATA+1]; + char areg_in_use[MAX_ADDR+1]; + struct reg_struct reg_stack[MAX_REG_STACK+1],reg_alloc[MAX_REG_STACK+1]; + int act_scratch; +#endif +} STACK_IMAGE; +#endif +void usestack(STACK_IMAGE *img) { /* used by g_expr::en_compound */ + img->next_data = next_data; + img->next_addr = next_addr; +#ifndef INFINITE_REGISTERS + img->act_scratch = act_scratch; + img->reg_alloc_ptr = reg_alloc_ptr; + img->reg_stack_ptr = reg_stack_ptr; + memcpy(img->dreg_in_use, dreg_in_use, MAX_DATA+1); + memcpy(img->areg_in_use, areg_in_use, MAX_ADDR+1); + memcpy(img->reg_stack, reg_stack, sizeof(struct reg_struct)*(MAX_REG_STACK+1)); + memcpy(img->reg_alloc, reg_alloc, sizeof(struct reg_struct)*(MAX_REG_STACK+1)); +#endif +} +void freestack(STACK_IMAGE *img) { /* used by g_expr::en_compound */ + next_data = img->next_data; + next_addr = img->next_addr; +#ifndef INFINITE_REGISTERS + act_scratch = img->act_scratch; + reg_alloc_ptr = img->reg_alloc_ptr; + reg_stack_ptr = img->reg_stack_ptr; + memcpy(dreg_in_use, img->dreg_in_use, MAX_DATA+1); + memcpy(areg_in_use, img->areg_in_use, MAX_ADDR+1); + memcpy(reg_stack, img->reg_stack, sizeof(struct reg_struct)*(MAX_REG_STACK+1)); + memcpy(reg_alloc, img->reg_alloc, sizeof(struct reg_struct)*(MAX_REG_STACK+1)); +#endif +} +//#endif + +#ifdef REGPARM +#ifndef __HAVE_REGS_IMAGE +#define __HAVE_REGS_IMAGE +typedef struct _regsimg { +#ifndef INFINITE_REGISTERS + int reg_alloc_ptr,reg_stack_ptr; + int next_data,next_addr; +#endif +} REGS_IMAGE; +#endif +void useregs(REGS_IMAGE *img) { /* used by g_fcall */ +#ifndef INFINITE_REGISTERS + img->reg_alloc_ptr = reg_alloc_ptr; + img->reg_stack_ptr = reg_stack_ptr; + img->next_data = next_data; + img->next_addr = next_addr; + next_data = 0; + next_addr = 0; +#endif +} +void freeregs(REGS_IMAGE *img) { /* used by g_fcall */ +#ifndef INFINITE_REGISTERS + int i; + for (i = 0; i <= MAX_DATA; i++) + dreg_in_use[i] = -1; + for (i = 0; i <= MAX_ADDR; i++) + areg_in_use[i] = -1; + reg_alloc_ptr = img->reg_alloc_ptr; + reg_stack_ptr = img->reg_stack_ptr; + next_data = img->next_data; + next_addr = img->next_addr; +#endif +} +#endif + +#ifdef PC +void checkstack(void) { +#ifndef INFINITE_REGISTERS +/* + * this routines checks if all allocated registers were freed + */ + int i; + for (i=0; i<= MAX_DATA; i++) + if (dreg_in_use[i] != -1) + ierr(CHECKSTACK,1); + for (i=0; i<= MAX_ADDR; i++) + if (areg_in_use[i] != -1) + ierr(CHECKSTACK,2); + if (reg_stack_ptr != 0) + ierr(CHECKSTACK,5); + if (reg_alloc_ptr != 0) + ierr(CHECKSTACK,6); +#endif + if (next_data != FIRSTREG) + ierr(CHECKSTACK,3); + if (next_addr != FIRSTREG) + ierr(CHECKSTACK,4); +} +#endif + +int ap_hasbeenpushed(struct amode *ap) { +#ifndef INFINITE_REGISTERS + return reg_alloc[(int)(ap)->deep].flag; +#else + return 0; +#endif +} + +void validate(struct amode *ap) { +#ifndef INFINITE_REGISTERS +/* + * validate will make sure that if a register within an address mode has been + * pushed onto the stack that it is popped back at this time. + */ + switch (ap->mode) { + case am_dreg: + if (ap->preg <= MAX_DATA && reg_alloc[(int)ap->deep].flag) { + g_pop(ap->preg, am_dreg, (int) ap->deep); + } + break; + case am_indx2: + if (ap->sreg <= MAX_DATA && reg_alloc[(int)ap->deep].flag) { + g_pop(ap->sreg, am_dreg, (int) ap->deep); + } + goto common; + case am_indx3: + if (ap->sreg <= MAX_ADDR && reg_alloc[(int)ap->deep].flag) { + g_pop(ap->sreg, am_areg, (int) ap->deep); + } + goto common; + case am_areg: + case am_ind: + case am_indx: + case am_ainc: + case am_adec: +common: + if (ap->preg <= MAX_ADDR && reg_alloc[(int)ap->deep].flag) { + g_pop(ap->preg, am_areg, (int) ap->deep); + } + break; + } +#endif +} + +struct amode *temp_data(void) { +/* + * allocate a temporary data register and return it's addressing mode. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+TEMP_DATA); +#ifndef INFINITE_REGISTERS + if (dreg_in_use[next_data] >= 0) + /* + * The next available register is already in use. it must be pushed + */ + g_push(next_data, am_dreg, dreg_in_use[next_data]); + dreg_in_use[next_data] = reg_alloc_ptr; +#endif + ap->mode = am_dreg; + ap->preg = next_data; +#ifndef INFINITE_REGISTERS + ap->deep = reg_alloc_ptr; + reg_alloc[reg_alloc_ptr].reg = next_data; + reg_alloc[reg_alloc_ptr].mode = am_dreg; + reg_alloc[reg_alloc_ptr].flag = 0; + if (next_data++ == MAX_DATA) + next_data = 0; /* wrap around */ + if (reg_alloc_ptr++ == MAX_REG_STACK) + ierr(TEMP_DATA,1); +#else + next_data++; +#endif + return ap; +} + +struct amode *temp_addr(void) { +/* + * allocate a temporary addr register and return it's addressing mode. + */ + struct amode *ap; + ap = (struct amode *) xalloc((int) sizeof(struct amode), AMODE+TEMP_ADDR); +#ifndef INFINITE_REGISTERS + if (areg_in_use[next_addr] >= 0) + /* + * The next available register is already in use. it must be pushed + */ + g_push(next_addr, am_areg, areg_in_use[next_addr]); + areg_in_use[next_addr] = reg_alloc_ptr; +#endif + ap->mode = am_areg; + ap->preg = next_addr; +#ifndef INFINITE_REGISTERS + ap->deep = reg_alloc_ptr; + reg_alloc[reg_alloc_ptr].reg = next_addr; + reg_alloc[reg_alloc_ptr].mode = am_areg; + reg_alloc[reg_alloc_ptr].flag = 0; + if (next_addr++ == MAX_ADDR) + next_addr = 0; /* wrap around */ + if (reg_alloc_ptr++ == MAX_REG_STACK) + ierr(TEMP_ADDR,1); +#else + next_addr++; +#endif + return ap; +} + +int free_data(void) { +/* + * returns TRUE if a data register is available at ,,no cost'' (no push). + * Used to determine e.g. wether cmp.w #0,An or move.l An,Dm is better + */ +#ifndef INFINITE_REGISTERS + return (dreg_in_use[next_data] < 0); +#else + return 1; +#endif +} + +void freeop(struct amode *ap) { +/* + * release any temporary registers used in an addressing mode. + */ + int number; + if (ap == 0) + /* This can happen freeing a NOVALUE result */ + return; + switch (ap->mode) { + case am_dreg: + if (ap->preg <= MAX_DATA) { + if (next_data-- == 0) + next_data = MAX_DATA; +#ifndef INFINITE_REGISTERS + number = dreg_in_use[(int)ap->preg]; + dreg_in_use[(int)ap->preg] = -1; +#endif + break; + } + return; + case am_indx2: + if (ap->sreg <= MAX_DATA) { + if (next_data-- == 0) + next_data = MAX_DATA; +#ifndef INFINITE_REGISTERS + number = dreg_in_use[(int)ap->sreg]; + dreg_in_use[(int)ap->sreg] = -1; +#endif + break; + } + goto common; + case am_indx3: + if (ap->sreg <= MAX_ADDR) { + if (next_addr-- == 0) + next_addr = MAX_ADDR; +#ifndef INFINITE_REGISTERS + number = areg_in_use[(int)ap->sreg]; + areg_in_use[(int)ap->sreg] = -1; +#endif + break; + } + goto common; + case am_areg: + case am_ind: + case am_indx: + case am_ainc: + case am_adec: +common: + if (ap->preg <= MAX_ADDR) { + if (next_addr-- == 0) + next_addr = MAX_ADDR; +#ifndef INFINITE_REGISTERS + number = areg_in_use[(int)ap->preg]; + areg_in_use[(int)ap->preg] = -1; +#endif + break; + } + return; + default: + return; + } +#ifndef INFINITE_REGISTERS + /* some consistency checks */ + if (number != ap->deep) + ierr(FREEOP,1); + /* we should only free the most recently allocated register */ + if (reg_alloc_ptr-- == 0) + ierr(FREEOP,2); + if (reg_alloc_ptr != number) + ierr(FREEOP,3); + /* the just freed register should not be on stack */ + if (reg_alloc[number].flag) + ierr(FREEOP,4); +#endif +} + +void temp_inv(void) { +#ifndef INFINITE_REGISTERS +/* + * push any used temporary registers. + * This is necessary across function calls + * The reason for this hacking is actually that temp_inv should dump + * the registers in the correct order, + * the least recently allocated register first. + * the most recently allocated register last. + */ + int i; + + for (i = 0; i < reg_alloc_ptr; i++) + if (reg_alloc[i].flag == 0) { + g_push(reg_alloc[i].reg, reg_alloc[i].mode, i); + /* mark the register void */ + if (reg_alloc[i].mode == am_dreg) + dreg_in_use[reg_alloc[i].reg] = -1; + else + areg_in_use[reg_alloc[i].reg] = -1; + } +#else + g_code(_op_cleanup_for_external_call, 0, NIL_AMODE, NIL_AMODE); +#endif +} +#endif /* MC680X0 */ +// vim:ts=4:sw=4 diff --git a/gtc/src/searchkw.c b/gtc/src/searchkw.c new file mode 100644 index 0000000..c5c3222 --- /dev/null +++ b/gtc/src/searchkw.c @@ -0,0 +1,182 @@ +/* + * GTools C compiler + * ================= + * source file : + * keyword searching + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +xstatic readonly struct kwblk { + char *word; + enum(e_sym) stype; +#ifndef PC + int pad; +#endif +} keywords[] = { + { + "__asm__", kw_asm + }, { + "__attribute__", kw_attr + }, { + "__builtin_constant_p", kwb_constant_p + }, { + "__c__", kw_c + }, { + "__count__", kw_count + }, { + "__eval__", kw_eval + }, { + "__loop__", kw_loop + }, { + "__softcast__", kw_softcast + }, { + "__until__", kw_until + }, { + "alloca", kw_alloca + }, { + "asm", kw_asm + }, { + "auto", kw_auto + }, { + "break", kw_break + }, { + "case", kw_case + }, { + "char", kw_char + }, { + "const", kw_const + }, { + "continue", kw_continue + }, { + "default", kw_default + }, { + "defined", kw_defined + }, { + "do", kw_do + }, { + "double", kw_double + }, { + "else", kw_else + }, { + "enum", kw_enum + }, { + "extern", kw_extern + }, { + "float", kw_float + }, { + "for", kw_for + }, { + "goto", kw_goto + }, { + "if", kw_if + }, { + "incbin", kw_incbin + }, { + "int", kw_int + }, { + "long", kw_long + }, { + "loop", kw_loop + }, { + "register", kw_register + }, { + "return", kw_return + }, { + "short", kw_short + }, { + "signed", kw_signed + }, { + "sizeof", kw_sizeof + }, { + "static", kw_static + }, { + "struct", kw_struct + }, { + "switch", kw_switch + }, { + "typedef", kw_typedef + }, { + "typeof", kw_typeof + }, { + "union", kw_union + }, { + "unsigned", kw_unsigned + }, { + "until", kw_until + }, { + "void", kw_void + }, { + "volatile", kw_volatile + }, { + "while", kw_while +/* }, { + 0, 0*/ + } +}; + +#define kw_N 48 + +/* + * Dichotomic search allows a max of 6 comparisons instead of 50... + */ +void searchkw(void) { + char *s1,*s2,c; + const struct kwblk *kwbp; + int a=0,b=kw_N-1,m; +#ifdef PC + if (sizeof(keywords)/sizeof(struct kwblk)!=kw_N) + fatal("BUILD ERROR: INVALID KEYWORDS #"); +#endif + while (a<=b) { + m=(a+b)>>1; + kwbp=&keywords[m]; + s1=lastid; + s2=kwbp->word; + do { + if (!(c=*s2++)) { + if (!*s1) + lastst = kwbp->stype; + if (is_lang_ext(lastst) && lastid[0]!='_' && !(flags&X_LANG_EXT)) + lastst = id; + if (*s1!='u') // the only case when a kw is the beginning of another one + return; // is 'do' vs 'double' + } + } while (*s1++==c); + if (s1[-1]word != 0) { + s1 = lastid; + s2 = kwbp->word; + kwbp++; + do { + if (!(c=*s2++)) { + if (!*s1++) + lastst = (--kwbp)->stype; + return; + } + } while (*s1++==c); + } +}*/ +// vim:ts=4:sw=4 diff --git a/gtc/src/securecommdef.h b/gtc/src/securecommdef.h new file mode 100644 index 0000000..795d204 --- /dev/null +++ b/gtc/src/securecommdef.h @@ -0,0 +1,23 @@ +/* + * GTools C compiler + * ================= + * source file : + * (on-calc) GT-Dev header file + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifndef __SECURECOMMDEF_H +#define __SECURECOMMDEF_H +typedef struct { + long dummy; + void *sft[]; +} SecureTab; +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/stmt.c b/gtc/src/stmt.c new file mode 100644 index 0000000..4292c1e --- /dev/null +++ b/gtc/src/stmt.c @@ -0,0 +1,952 @@ +/* + * GTools C compiler + * ================= + * source file : + * statement handling + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifdef PC +#ifdef SHORT_INT +#undef int +#endif +#include +#ifdef SHORT_INT +#define int short +#endif +#endif + +struct enode *init_node CGLOB; + +TYP *lastexpr_tp CGLOB; +int lastexpr_size CGLOB, lastexpr_type CGLOB; + +/* + * the statement module handles all of the possible c statements and builds a + * parse tree of the statements. + * + * each routine returns a pointer to a statement parse node which reflects the + * statement just parsed. + */ + + +int start_block(int m) { // used in block() (func.c) + if (m) { + needpunc(begin); + return 1; // we don't care about the result in this case + } else + return lastst==begin; +} + +unsigned int getconst(enum(e_sym) s,enum(e_sym) e) { + struct enode *en; + getsym(); + if (lastst != s) + error(ERR_EXPREXPECT); + else { + getsym(); + if (exprnc(&en) == 0) + error(ERR_EXPREXPECT); + needpunc(e); + opt0(&en); + if (en->nodetype != en_icon) + error(ERR_CONSTEXPECT); + else if ((unsigned long)en->v.i>=65536) + error(ERR_OUTRANGE); + else return en->v.i; + } + return 0; // make the compiler happy +} +unsigned int getconst2(enum(e_sym) e) { + struct enode *en; + if (exprnc(&en) == 0) + error(ERR_EXPREXPECT); + needpunc(e); + opt0(&en); + if (en->nodetype != en_icon) + error(ERR_CONSTEXPECT); + else if ((unsigned long)en->v.i>=65536) + error(ERR_OUTRANGE); + else return en->v.i; + return 0; // make the compiler happy +} + +struct snode *whilestmt(void) { +/* + * whilestmt parses the c while statement. + */ + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_while; + snp->count = 3; + getsym(); + if (lastst != openpa) + error(ERR_EXPREXPECT); + else { + getsym(); + if (expression(&(snp->exp)) == 0) + error(ERR_EXPREXPECT); +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + needpunc(closepa); + if (lastst == kw_count) snp->count=getconst(openpa,closepa); + snp->s1 = statement(); + } + return snp; +} + +struct snode *asmstmt(); +#if !defined(AS) && !defined(ASM) +struct snode *asmstmt(void) { +/* + * asmstmt parses the gtc c asm statement. + */ + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_asm; + snp->count = 1; + getsym(); + if (lastst != openpa) + error(ERR_EXPREXPECT); + else { + getsym(); + if (lastst != sconst) + error(ERR_SYNTAX); + snp->v1.i = (long)strsave(laststr); + getsym(); + if (lastst == colon) { + getsym(); + uwarn("only asm(\"...\") is supported yet"); + error(ERR_SYNTAX); + } + needpunc(closepa); + needpunc(semicolon); + } +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + return snp; +} +#endif + +//struct enode lp_one = { en_icon, bt_ushort, 2, {1L}, 0, 0}; +xstatic struct enode *lp_one CGLOB; +struct snode *loopstmt(void) { +/* + * loopstmt parses the gtc c loop statement. + */ + struct snode *snp; TYP *tp; + struct enode *exp; + int has_count; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_loop; + snp->count = 3; + has_count = 0; + getsym(); + if (lastst != openpa) + error(ERR_EXPREXPECT); + else { + getsym(); + if (lastst != id) + error(ERR_IDEXPECT); + if (!nameref(&(snp->v1.e))) error(ERR_EXPREXPECT); + if (lastst != assign) + error(ERR_SYNTAX); + getsym(); + if (!(tp=expression(&(snp->exp)))) + error(ERR_EXPREXPECT); + cast_op(&(snp->exp),tp,(TYP *)&tp_ushort); +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + needpunc(closepa); + if (lastst == kw_count) { snp->count=getconst(openpa,closepa); has_count=1; } + opt0(&(snp->exp)); + if (snp->exp->nodetype==en_icon) { + unsigned int c=snp->exp->v.i; + if (has_count) { + if (c!=snp->count) + uwarn("loop has an effective count of %u whereas %u precised", + c,snp->count); + } else snp->count=c; + } + lp_one = mk_icon(1L); + lp_one->etype = bt_ushort; lp_one->esize = 2; + snp->exp = exp = mk_node(en_sub,snp->exp,lp_one); + exp->etype = bt_ushort; exp->esize = 2; + opt4(&(snp->exp)); + snp->exp = exp = mk_node(en_assign,snp->v1.e,snp->exp); + exp->etype = bt_ushort; exp->esize = 2; + snp->s1 = statement(); + if (lastst == kw_until) { + getsym(); + if (!expression(&(snp->v2.e))) error(ERR_EXPREXPECT); + } else snp->v2.e=NULL; + } + return snp; +} + +struct snode *dostmt(void) { +/* + * dostmt parses the c do-while construct. + */ + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_do; + snp->count = 3; + getsym(); + snp->s1 = statement(); +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + if (lastst != kw_while) + error(ERR_WHILEXPECT); + else { + getsym(); + if (lastst != openpa) + error(ERR_EXPREXPECT); + else { + getsym(); + if (expression(&(snp->exp)) == 0) + error(ERR_EXPREXPECT); + needpunc(closepa); + if (lastst == kw_count) snp->count=getconst(openpa,closepa); + } + if (lastst != end) + needpunc(semicolon); + } + return snp; +} + +struct snode *forstmt(void) { + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_for; + snp->count = 3; + getsym(); + needpunc(openpa); + /*if (*/expression(&(snp->exp))/* == 0) + snp->exp = 0*/; + needpunc(semicolon); + /*if (*/expression(&(snp->v1.e))/* == 0) + snp->v1.e = 0*/; + needpunc(semicolon); + /*if (*/expression(&(snp->v2.e))/* == 0) + snp->v2.e = 0*/; +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + needpunc(closepa); + if (lastst == kw_count) snp->count=getconst(openpa,closepa); + snp->s1 = statement(); + return snp; +} + +struct snode *ifstmt(void) { +/* + * ifstmt parses the c if statement and an else clause if one is present. + */ + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_if; + snp->count=32768; + getsym(); + if (lastst != openpa) + error(ERR_EXPREXPECT); + else { + getsym(); + if (expression(&(snp->exp)) == 0) + error(ERR_EXPREXPECT); +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + needpunc(closepa); + if (lastst == kw_count) { + unsigned int i=getconst(openpa,comma),j=getconst2(closepa); + snp->count=((unsigned long)i<<16)/(i+j); + } + snp->s1 = statement(); + if (lastst == kw_else) { + getsym(); + snp->v1.s = statement(); + } else { +#ifdef NO_CALLOC + snp->v1.s = 0; +#endif + } + } + return snp; +} + +/* + * consider the following piece of code: + * + * switch (i) { + * case 1: + * if (j) { + * ..... + * } else + * case 2: + * .... + * } + * + * case statements may be deep inside, so we need a global variable + * last_case to link them + */ +xstatic struct snode *last_case CGLOB; /* last case statement within this switch */ + +struct snode *casestmt(void) { +/* + * cases are returned as seperate statements. for normal cases label is the + * case value and v1.i is zero. for the default case v1.i is nonzero. + */ + struct snode *snp,*snp0; + snp0 = snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); +#ifdef NO_CALLOC + snp->s1 = NIL_SNODE; +#endif + if (lastst == kw_case) { + long v; + getsym(); + snp->stype = st_case; + snp->v2.i = v = intexpr(); + if (lastst == dots) { // TODO : make only one 'case' label + long max; + getsym(); + if ((max = intexpr()) < v) error(ERR_CASERANGE); + else while (v != max) { + last_case = last_case->s1 = snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + last_case->v1.s = snp; +#ifdef NO_CALLOC + snp->s1 = NIL_SNODE; +#endif + snp->stype = st_case; + snp->v2.i = ++v; + } + } + } else { + /* lastst is kw_default */ + getsym(); + /* CVW: statement type needed for analyze etc. */ + snp->stype = st_default; + } + last_case = last_case->s1 = snp; + needpunc(colon); + if (lastst != end) + snp->v1.s = statement(); + return snp0; +} + +int checkcases(struct snode *head) { +/* + * checkcases will check to see if any duplicate cases exist in the case list + * pointed to by head. + */ + struct snode *top, *cur; + cur = top = head; + while (top != 0) { + cur = top->s1; + while (cur != 0) { + if (cur->stype != st_default && top->stype != st_default + && cur->v2.i == top->v2.i) { + uwarn("duplicate case label for value %ld", cur->v2.i); + return 1; + } + if (cur->stype == st_default && top->stype == st_default) { + uwarn("duplicate default label"); + return 1; + } + cur = cur->s1; + } + top = top->s1; + } + return 0; +} + +struct snode *switchstmt(void) { + struct snode *snp; + struct snode *local_last_case; + local_last_case = last_case; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + last_case = snp; +#ifdef NO_CALLOC + snp->s1 = 0; +#endif + snp->stype = st_switch; + getsym(); + needpunc(openpa); + if ((expression(&(snp->exp))) == 0) + error(ERR_EXPREXPECT); +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + needpunc(closepa); + needpunc(begin); + snp->v1.s = compound(1); + if (checkcases(snp->s1)) + error(ERR_DUPCASE); + last_case = local_last_case; + return snp; +} + +struct snode *retstmt(void) { + struct snode *snp; + TYP *tp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_return; + getsym(); + tp = expression(&(snp->exp)); + if (snp->exp != 0) + (void) cast_op(&(snp->exp), tp, ret_type); + if (lastst != end) + needpunc(semicolon); +#ifdef DB_POSSIBLE + snp->line=prevlineid; +#endif + return snp; +} + +struct snode *breakstmt(void) { + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_break; + getsym(); + if (lastst != end) + needpunc(semicolon); +#ifdef DB_POSSIBLE + snp->line=prevlineid; +#endif + return snp; +} + +struct snode *contstmt(void) { + struct snode *snp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_continue; + getsym(); + if (lastst != end) + needpunc(semicolon); +#ifdef DB_POSSIBLE + snp->line=prevlineid; +#endif + return snp; +} + +struct snode *exprstmt(void) { +/* + * exprstmt is called whenever a statement does not begin with a keyword. the + * statement should be an expression. + */ + struct snode *snp; + debug('u'); + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_expr; +/* + * I have a problem here. + * If expression() fails on the first character and does not do a getsym(), + * there may be an infinite loop since we will continue coming up here. + * Since the compiler will stop after MAX_ERROR_COUNT calls to error(), + * this might not be THAT much of a problem. + */ + if (!(lastexpr_tp=expression(&(snp->exp)))) + error(ERR_EXPREXPECT); + else { + lastexpr_type=snp->exp->etype; + lastexpr_size=snp->exp->esize; + } + debug('v'); + if (lastst != end) + needpunc(semicolon); +#ifdef DB_POSSIBLE + snp->line=prevlineid; +#endif + debug('w'); + return snp; +} + +#ifdef AUTOINIT_PAD +//long auto_init(long offs,TYP *typ,int brace_level,int offmod); +long auto_pad(long offs,int len,int offmod) { + long nbytes=0; + while (len>0) { + int size; + if ((offs+offmod)&1) + size=1; + else if (len<=2) + size=len; + else if (len==3) + size=2; + else size=4; + + { + struct enode *ep1,*ep2=mk_icon(0L),*ep3; + ep2->esize = size; /* don't care about the etype, it's set to char */ + + ep1 = mk_node(en_autocon, NIL_ENODE, NIL_ENODE); + ep1->v.i = offs; + ep1->etype = bt_pointer; + ep1->esize = 4; + + ep3 = mk_icon((long)offmod); + ep3->etype = bt_long; + ep3->esize = 4; + + ep1 = mk_node(en_add, ep1, ep3); + ep1->etype = bt_pointer; + ep1->esize = 4; + + ep1 = mk_node(en_ref, ep1, NIL_ENODE); + ep1->esize = size; /* don't care about the etype, it's set to char */ + + ep1 = mk_node(en_assign, ep1, ep2); + ep1->esize = size; /* don't care about the etype, it's set to char */ + + if (init_node == 0) { + init_node = ep1; + } else { + init_node = mk_node(en_void, init_node, ep1); + } + } + + len-=size; + nbytes+=size; + offmod+=size; + } + return nbytes; +} +#endif + +long auto_init(long offs,TYP *typ,TYP **tpp,int brace_level,int offmod,int stroff) { +/* + * generated assignment statements for initialization of auto and register + * variables. The initialization is generated like comma operators so a + * single statement does all the initializations + */ + struct enode *ep1, *ep2; + struct typ *tp; + int brace_seen = 0; + long nbytes = 0; + +auto_init_restart: + if (lastst == begin) { + brace_level++; + brace_seen++; + getsym(); + } + if (typ->type==bt_struct && brace_level) { + struct sym *sp; + sp = typ->lst.head; /* start at top of symbol table */ + while (sp != 0) { +/* infunc("DrawPacmanLogoAndHandleMenu") + bkpt();*/ + nbytes+=auto_init(offs,sp->tp,NULL,brace_level,(int)(offmod+sp->value.i),-1); + if (lastst == comma) + getsym(); + if (lastst == end || lastst == semicolon) + break; + sp = sp->next; + } +#ifdef AUTOINIT_PAD + nbytes+=auto_pad(offs,(int)(typ->size-nbytes),offmod+nbytes); /* negative args are OK for auto_pad */ +#endif + } else if (typ->type==bt_union) { + typ = (typ->lst.head)->tp; + goto auto_init_restart; + } else if (typ->val_flag) { +// if (!brace_level) error(ERR_SYNTAX); + if (lastst != end) { + int stroff=-1; + if (lastst == sconst && !brace_seen) + stroff=0; + while (1) { + nbytes+=auto_init(offs,typ->btp,NULL,brace_level,(int)(offmod+nbytes),stroff); + if (stroff>=0) { + stroff++; + if (stroff>lstrlen || (stroff==lstrlen && typ->size)) { + getsym(); + break; + } + } else { + if (lastst == comma) + getsym(); + if (lastst == end || lastst == semicolon) break; + } + } + } + if (typ->size && nbytes > typ->size) + error(ERR_INITSIZE); + if (nbytes != typ->size && tpp) { + /* fix the symbol's size, unless tpp=0 (item of a struct/union or array) */ + typ = copy_type(typ); + *tpp = typ; + typ->size = nbytes; + } +#ifdef AUTOINIT_PAD + nbytes+=auto_pad(offs,(int)(typ->size-nbytes),offmod+nbytes); /* negative args are OK for auto_pad */ +#endif + } else { + if (stroff<0) { + if (!(tp = exprnc(&ep2))) + error(ERR_ILLINIT); + } else + ep2=mk_icon(strofftype); + +/* if (offs==0xfffffe4e) + bkpt();*/ + + ep1 = mk_node(en_autocon, NIL_ENODE, NIL_ENODE); + ep1->v.i = offs; +/* ep1->etype = typ->type; // this is a ridiculous bug that I spent hours finding... + ep1->esize = typ->size; */ + ep1->etype = bt_pointer; + ep1->esize = 4; + + if (offmod) { + struct enode *ep3 = mk_icon((long)offmod); + ep3->etype = bt_long; + ep3->esize = 4; + + ep1 = mk_node(en_add, ep1, ep3); + ep1->etype = bt_pointer; + ep1->esize = 4; + } + + ep1 = mk_node(en_ref, ep1, NIL_ENODE); + ep1->etype = typ->type; + ep1->esize = typ->size; + + ep1 = mk_node(en_assign, ep1, ep2); + ep1->etype = typ->type; + ep1->esize = typ->size; + +#ifdef MID_DECL_IN_EXPR + if (middle_decl) + md_expr = ep1, md_type = typ; + #error fix needed around here... + else { +#endif + if (init_node == 0) { + init_node = ep1; + } else { + init_node = mk_node(en_void, init_node, ep1); + } +#ifdef MID_DECL_IN_EXPR + } +#endif + } + while (brace_seen--) + needpunc(end); + return nbytes; +} + +struct snode *compound(int no_init) { +/* + * compound processes a block of statements and forms a linked list of the + * statements within the block. + * + * compound expects the input pointer to already be past the begin symbol of the + * block. + * + * If no_init is true, auto initializations are not desirable + */ + struct snode *head, *tail, *snp; +// struct sym *local_tail, *local_tagtail; + HTABLE old_lsyms,old_ltags; +// hashinit(&symtab); +/* local_tail = lsyms.tail; + local_tagtail = ltags.tail;*/ + memcpy(&old_lsyms,&lsyms,sizeof(HTABLE)); + memcpy(&old_ltags,<ags,sizeof(HTABLE)); + dodecl(sc_auto); + if (init_node == 0) { + head = tail = 0; + } else { + if (no_init>0) { + uwarn("auto initialization not reached"); + } + head = tail = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + head->stype = st_expr; + head->exp = init_node; +#ifdef NO_CALLOC + head->next = 0; +#endif +#ifdef DB_POSSIBLE + head->line = prevlineid; +#endif + } + init_node = 0; + while (lastst != end) { + if (head == 0) + head = tail = statement(); + else { + tail->next = statement(); + if (tail->next != 0) + tail = tail->next; + } + } + if (no_init>=0) + getsym(); +#ifdef LISTING + if (list_option) { +/* if (local_tail != lsyms.tail) { + if (local_tail != 0) + symtab.head = local_tail->next; + else + symtab.head = lsyms.head; + symtab.tail = lsyms.tail; + fprintf(list, "\n*** local symbol table ***\n\n"); + list_table(&symtab, 0); + fprintf(list, "\n"); + }*/ + fprintf(list, "\n*** local symbol table ***\n\n"); + list_table(&lsyms, 0); + fprintf(list, "\n"); +/* if (local_tagtail != ltags.tail) { + if (local_tagtail != 0) + symtab.head = local_tagtail->next; + else + symtab.head = ltags.head; + symtab.tail = ltags.tail; + fprintf(list, "\n*** local structures and unions ***\n\n"); + list_table(&symtab, 0); + fprintf(list, "\n"); + }*/ + fprintf(list, "\n*** local structures and unions ***\n\n"); + list_table(<ags, 0); + fprintf(list, "\n"); + } +#endif +/* if (local_tagtail != 0) { + ltags.tail = local_tagtail; + ltags.tail->next = 0; + } else { + ltags.head = 0; + ltags.tail = 0; + } + + + if (local_tail != 0) { + lsyms.tail = local_tail; + lsyms.tail->next = 0; + } else { + lsyms.head = 0; + lsyms.tail = 0; + }*/ + memcpy(&lsyms,&old_lsyms,sizeof(HTABLE)); + memcpy(<ags,&old_ltags,sizeof(HTABLE)); + + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_compound; + snp->s1 = head; +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + return snp; +} + +extern unsigned int pos; +struct snode *labelstmt(void) { +/* + * labelstmt processes a label that appears before a statement as a seperate + * statement. + */ + struct snode *snp; + struct sym *sp; + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + /*if (pos>=0x25C2) + printf("jiotrh");*/ + snp->stype = st_label; + if ((sp = search(lastid, lastcrc, &labsyms)) == 0) { + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM); + sp->name = strsave(lastid); + sp->storage_class = sc_label; +#ifdef NO_CALLOC + sp->tp = 0; +#endif + sp->value.i = nxtlabel(); + append(&sp, &labsyms); + } else { + if (sp->storage_class != sc_ulabel) + error(ERR_LABEL); + else + sp->storage_class = sc_label; + } + getsym(); /* get past id */ + needpunc(colon); + if (sp->storage_class == sc_label) { + snp->v2.i = sp->value.i; + if (lastst != end) + snp->s1 = statement(); + return snp; + } + return 0; +} + +struct snode *gotostmt(void) { +/* + * gotostmt processes the goto statement and puts undefined labels into the + * symbol table. + */ + struct snode *snp; + struct sym *sp; + getsym(); + if (lastst != id) { + error(ERR_IDEXPECT); + return 0; + } + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + if ((sp = search(lastid, lastcrc, &labsyms)) == 0) { + sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM); + sp->name = strsave(lastid); + sp->value.i = nxtlabel(); + sp->storage_class = sc_ulabel; +#ifdef NO_CALLOC + sp->tp = 0; +#endif + append(&sp, &labsyms); + } +#ifdef DB_POSSIBLE + snp->line=lineid; +#endif + getsym(); /* get past label name */ + if (lastst != end) + needpunc(semicolon); + if (sp->storage_class != sc_label && sp->storage_class != sc_ulabel) + error(ERR_LABEL); + else { + snp->stype = st_goto; + snp->v2.i = sp->value.i; + snp->next = 0; + return snp; + } + return 0; +} + +struct snode *statement(void) { +/* + * statement figures out which of the statement processors should be called + * and transfers control to the proper routine. + */ + struct snode *snp; +/* if (lineid==0x20A) + bkpt();*/ + switch (lastst) { + case semicolon: + getsym(); + snp = 0; + break; + case kw_char: case kw_short: case kw_unsigned: case kw_long: + case kw_struct: case kw_union: case kw_enum: case kw_void: + case kw_float: case kw_double: case kw_int: case kw_typeof: + case kw_signed: case kw_const: case kw_volatile: + case kw_register: case kw_auto: + case kw_static: case kw_typedef: case kw_extern: +middle_decl: + if (!(flags & X_MID_DECL)) goto default_decl; +#ifdef OLD_MID_DECL + snp = compound(0); + if ((int)cached_sym IS_VALID) fatal("CACHE"); // will never happen since no caching is + // performed when lastst==begin +/* cached_sym2 = cached_sym;*/ + cached_sym = lastst; cached_lineid = lineid; + lastst = end; + break; +#else +#ifdef MID_DECL + /* the following is much cleaner than the old mid_decl handler */ + dodecl(sc_auto); + if (init_node) { + snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE); + snp->stype = st_expr; + snp->exp = init_node; +#ifdef DB_POSSIBLE + snp->line = prevlineid; +#endif + init_node = 0; // compound resets after calling rather than before... + } // I find it pretty weird :) (maybe it should be changed?) + else snp = 0; + break; +#endif +#endif + case begin: + getsym(); + snp = compound(0); + break; + case kw_if: + snp = ifstmt(); + break; + case kw_while: + snp = whilestmt(); + break; + case kw_for: + snp = forstmt(); + break; + case kw_return: + snp = retstmt(); + break; + case kw_break: + snp = breakstmt(); + break; + case kw_goto: + snp = gotostmt(); + break; + case kw_continue: + snp = contstmt(); + break; + case kw_do: + snp = dostmt(); + break; + case kw_switch: + snp = switchstmt(); + break; + case kw_case: + case kw_default: + snp = casestmt(); + break; + case kw_loop: + snp = loopstmt(); + break; + case kw_count: + snp = NULL; + error(ERR_EXPREXPECT); + break; + case kw_asm: + snp = asmstmt(); + break; + case id: + if (!getcache(id) && cached_sym==colon) { + snp = labelstmt(); + break; + } +#if defined(OLD_MID_DECL) || defined(MID_DECL) + if (lastsp && lastsp->storage_class == sc_typedef) + goto middle_decl; +#endif +default_decl: + /* else fall through to process expression */ + default: + snp = exprstmt(); + break; + } + if (snp != 0) + snp->next = 0; + return snp; +} +// vim:ts=4:sw=4 diff --git a/gtc/src/sunpack.c b/gtc/src/sunpack.c new file mode 100644 index 0000000..2ca460e --- /dev/null +++ b/gtc/src/sunpack.c @@ -0,0 +1,91 @@ +/* + * GTools C compiler + * ================= + * source file : + * precompiled header string unpacking + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#ifdef PC +#include + +char *sUnpack(char *in,char *out,char *dic) { + char c; char *out0=out; + while ((c=*in++)) { + if ((char)c>=0) *out++=c; + else { + if (c==(char)0x80) *out++=*in++; + else if (c==(char)0xFF) { + + } else { + char *dp=dic; + c-=(char)0x81; + while (c--) { + while (*dp++); + } + strcpy(out,dp); + while (*out++); out--; + } + } + } + *out++=0; + return out0; +} +#else +char *__attribute__((stkparm)) sUnpack(char *in,char *out,char *dic); +asm( +" xdef sUnpack\n" +"sUnpack:\n" +"/* bra.s sUnpack*/\n" +" move.l 4(%sp),%a0\n" +" move.l 8(%sp),%a1\n" +" moveq #126,%d1\n" +" moveq #0,%d0\n" +" move.b (%a0)+,%d0\n" +" beq su_quit\n" +" bmi su_special\n" +"su_copy_lp:\n" +" move.b %d0,(%a1)+\n" +"su_next:\n" +" move.b (%a0)+,%d0\n" +" bgt su_copy_lp\n" +" beq su_quit\n" +"su_special:\n" +" subq.b #1,%d0\n" +" bmi su_not_escape\n" +" move.b (%a0)+,(%a1)+\n" +" bra su_next\n" +"su_not_escape:\n" +" addq.b #2,%d0\n" +" bmi su_not_romcall\n" +" \n" +"su_not_romcall:\n" +" add.b %d1,%d0\n" +" move.l %a0,%d2\n" +" move.l 12(%sp),%a0\n" +" dbf %d0,su_search_loop\n" +" bra su_search_done\n" +"su_search_loop:\n" +" tst.b (%a0)+\n" +" bne su_search_loop\n" +" dbf %d0,su_search_loop\n" +"su_search_done:\n" +" move.b (%a0)+,(%a1)+\n" +" bne su_search_done\n" +" subq.w #1,%a1\n" +" move.l %d2,%a0\n" +" moveq #0,%d0\n" +" bra su_next\n" +"su_quit:\n" +" move.b %d0,(%a1)+\n" +" move.l 8(%sp),%a0\n" +" rts"); +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/symbol.c b/gtc/src/symbol.c new file mode 100644 index 0000000..97b8400 --- /dev/null +++ b/gtc/src/symbol.c @@ -0,0 +1,343 @@ +/* + * GTools C compiler + * ================= + * source file : + * symbol handling (insertion & search) + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" +#ifdef PCH +#include "pch.h" +#endif + +#ifdef EXE_OUT +#ifndef AS +int exestub_mode CGLOB; +#endif +#endif + +HTABLE gsyms CGLOBL, gtags CGLOBL, lsyms CGLOBL, labsyms CGLOBL, ltags CGLOBL; + +void concat(TABLE *dest,TABLE *src) { + SYM *sp=src->tail,*sp2; + while (sp) { + sp2=(SYM *)xalloc((int)sizeof(SYM), _SYM+SYMBOL); + *sp2=*sp; + insert(sp2,(HTABLE *)dest); + sp=sp->prev; + } +} + +void hashinit(HTABLE *t) { + t->hash=0x2489; + memset(t->h,0,sizeof(t->h)); +} + +void insert(SYM *sp,HTABLE *table) { +/* if (!strcmp(sp->name,"wrong_calc")) + uwarn("def!");*/ + if (!table->hash) { + if (!search(sp->name,0,table)) { + TABLE *tab=(TABLE *)table; + if (!tab->head) { + tab->head = tab->tail = sp; + sp->prev = 0; + sp->used = 0; + } else { + tab->tail->next = sp; + sp->prev = tab->tail; + tab->tail = sp; + sp->used = 0; + tab->tail = sp; + } + sp->next = 0; + } + else uerr(ERR_DUPSYM,sp->name); + } else { + int crc=crcN(sp->name); +#ifdef EXE_OUT + if (table==&defsyms && sp->name[0]=='E' && !strcmp(sp->name,"EXE_OUT")) + exestub_mode=1; +#endif + if (!search(sp->name,crc,table)) { + struct htab *tab=&table->h[crc]; + if (!tab->head) { + tab->head = tab->tail = sp; + sp->prev = 0; + sp->used = 0; + } else { + tab->tail->next = sp; + sp->prev = tab->tail; + tab->tail = sp; + sp->used = 0; + tab->tail = sp; + } + sp->next = 0; + } + else uerr(ERR_DUPSYM,sp->name); + } +} + +struct sym *symremove(char *na, HTABLE *tab) { + SYM *ttail,**prv; + struct htab *root; + char *s1,*s2,c; + if (!tab->hash) + ierr(TABLE_HASH,2); +#ifdef PC + if (tab->hash!=0x2489) + ierr(TABLE_HASH,1); +#endif + prv=&((root=&tab->h[crcN(na)])->tail); + while ((ttail=*prv)) { + s1 = ttail->name; + s2 = na; + while (*s1++==(c=*s2++)) { + if (!c) { +// *prv = ttail->prev; + if (ttail->next) ttail->next->prev = ttail->prev; + if (ttail->prev) ttail->prev->next = ttail->next; +// ttail->next = prv; + if (root->tail==ttail) root->tail=ttail->prev; + if (root->head==ttail) root->head=ttail->next; +/* if (!root->tail) + root->head=0;*/ + return ttail; + } + } + prv = &(ttail->prev); + } + return 0; +} + +#ifdef PC +int crcN(char *na) { + unsigned long crc=-1; int n; + unsigned char c; + c=*na++; + do { + crc^=c; + n=crc&7; + crc=(crc>>n)+(crc<<(32-n)); + } while ((c=*na++)); + crc^=crc>>16; + crc^=crc>>8; + return crc & (N_HASH-1); +} +#else +int crcN(char *na); +asm("crcN:\n" +" move.l 4(%sp),%a0\n" +" moveq #-1,%d0\n" +" move.b (%a0)+,%d1\n" +"crcN_loop:\n" +" eor.b %d1,%d0\n" +" moveq #7,%d1\n" +" and.w %d0,%d1\n" +" ror.l %d1,%d0\n" +" move.b (%a0)+,%d1\n" +" bne crcN_loop\n" +" move.w %d0,%d1\n" +" swap %d0\n" +" eor.w %d1,%d0\n" +" move.w %d0,-(%sp)\n" +" move.b (%sp)+,%d1\n" +" eor.b %d1,%d0\n" +" and.w #" N_HASH_AND ",%d0\n" +" rts"); +#endif + +/*#ifdef PC*/ +struct sym *search(char *na, int crc, HTABLE *tab) { + char *s1,*s2,c; + if (!tab->hash) { + SYM *ttail=((TABLE *)tab)->tail; + while (ttail) { + s1 = ttail->name; + s2 = na; + while (*s1++==(c=*s2++)) { + if (!c) return ttail; + } + ttail = ttail->prev; + } + return 0; + } else { + SYM *ttail; +#ifdef PC + if (tab->hash!=0x2489) + ierr(TABLE_HASH,1); +#endif + if (crc<0) crc=crcN(na); + ttail=tab->h[crc].tail; + while (ttail) { + s1 = ttail->name; + s2 = na; + while (*s1++==(c=*s2++)) { + if (!c) return ttail; + } + ttail = ttail->prev; + } + return 0; + } +} +/*#else +asm("search: + move.l %a2,-(%sp) + move.l 8(%sp),%d1 + move.l %d1,%a1 + tst.b (%a1) +0: beq 0b + move.l 12(%sp),%a0 + move.l %a0,%d0 + beq search_end +search_lp: + move.l (%a0)+,%a2 + move.l %d1,%a1 + cmpm.b (%a1)+,(%a2)+ + bne search_nxt +search_lp2: + move.b (%a1)+,%d0 + beq search_fnd + cmp.b (%a2)+,%d0 + beq search_lp2 +search_nxt: + move.l (%a0)+,%a0 + move.l %a0,%d0 + bne search_lp +search_end: + move.l (%sp)+,%a2 + rts +search_fnd: + tst.b (%a2)+ + bne search_nxt + subq.l #4,%a0 + move.l (%sp)+,%a2 + rts"); +#endif*/ + +struct sym *gsearch(char *na,int crc) { + struct sym *sp; + if (!(sp = search(na, crc, &lsyms))) + sp = search(na, crc, &gsyms); + return sp; +} + +void append(struct sym **ptr_sp, HTABLE *table) { + struct sym *sp1, *sp = *ptr_sp; + if (table == &gsyms && (sp1 = search(sp->name, -1, table)) != 0) { + /* + * The global symbol table has only one level, this means that we + * only check if the new declaration is compatible with the old one + */ + + if (!eq_type(sp->tp, sp1->tp)) + uerr(ERR_REDECL,sp->name); + /* + * The new storage class depends on the old and on the new one. + */ + if (sp->storage_class == sp1->storage_class) { + if (sp->storage_class == sc_global) { + /* + * This hack sets sp->used to -1 so that decl.c knows to + * suppress storage allocation + */ + uwarn("global redeclaration of '%s'", sp->name); + sp1->used = -1; + } + *ptr_sp = sp1; /* caller uses old entry */ + return; + } + /* + * since we use compiler generated label for static data, we must + * retain sc_static + */ + if (sp1->storage_class == sc_static) { + *ptr_sp = sp1; /* caller uses old entry */ + return; + } + /* + * if the new storage class is global, we must update sp1 to generate + * the .globl directive at the very end and perhaps the size (e.g. + * for arrays) + */ + if (sp->storage_class == sc_global) { + sp1->storage_class = sc_global; + sp1->tp = sp->tp; + *ptr_sp = sp1; /* caller uses old entry */ + return; + } + /* + * if the new storage class is static, set it to global (since we may + * have used the ,real' name and cannot use compiler generated names + * for this symbol from now on) and set sp->value.i to -1 to prevent + * it from being exported via .globl directives + */ + if (sp->storage_class == sc_static) { + sp1->storage_class = sc_global; + sp1->value.i = -1; + *ptr_sp = sp1; /* caller uses old entry */ + return; + } + /* + * last case: global declaration followed by external decl.: just do + * nothing + */ + *ptr_sp = sp1; /* caller uses old entry */ + return; + } +/* if (table->head == 0) { + // The table is empty so far... + table->head = table->tail = sp; + sp->next = sp->prev = 0; + sp->used = 0; + } else { + table->tail->next = sp; + sp->prev = table->tail; + table->tail = sp; + sp->next = 0; + sp->used = 0; + }*/ + if (!table->hash) { + TABLE *tab=(TABLE *)table; + if (!tab->head) { + tab->head = tab->tail = sp; + sp->prev = 0; + sp->used = 0; + } else { + tab->tail->next = sp; + sp->prev = tab->tail; + tab->tail = sp; + sp->used = 0; + tab->tail = sp; + } + sp->next = 0; + } else { + struct htab *tab=&table->h[crcN(sp->name)]; + if (!tab->head) { + tab->head = tab->tail = sp; + sp->prev = 0; + sp->used = 0; + } else { + tab->tail->next = sp; + sp->prev = tab->tail; + tab->tail = sp; + sp->used = 0; + tab->tail = sp; + } + sp->next = 0; + } +} +// vim:ts=4:sw=4 diff --git a/gtc/src/trees.c b/gtc/src/trees.c new file mode 100644 index 0000000..c2f0ce8 --- /dev/null +++ b/gtc/src/trees.c @@ -0,0 +1,247 @@ +/* + * GTools C compiler + * ================= + * source file : + * tree dumping + * + * Copyright 2001-2004 Paul Froissart. + * Credits to Christoph van Wuellen and Matthew Brandt. + * All commercial rights reserved. + * + * This compiler may be redistributed as long there is no + * commercial interest. The compiler must not be redistributed + * without its full sources. This notice must stay intact. + */ + +#include "define.h" +_FILE(__FILE__) +#include "c.h" +#include "expr.h" +#include "gen.h" +#include "cglbdec.h" + +typedef struct dump { +} DUMP; +char *dump_node_stack[MAX_DUMP_NODE_STACK]; +int dump_node_stack_depth; +int dump_attribute_phase; + +#define dump_put printf +void dump_startline() { + int i; + for (i=0;i\n"); + dump_startline(); + dump_put("<%s",name); + dump_node_stack[dump_node_stack_depth++] = name; + dump_attribute_phase = 1; +} +void dump_addstr(char *name,char *v) { + assert(dump_attribute_phase); + dump_put(" %s='%s'",name,v); +} +void dump_addint(char *name,int v) { + char b[100]; + sprintf(b,"%d",v); + dump_addstr(name,b); +} +void dump_addreg(char *name,int v) { + assert(dump_attribute_phase); + if (v>=RESULT && v=PRESULT && v\n"); + else + dump_startline(), dump_put("",dump_node_stack[dump_node_stack_depth]); + dump_attribute_phase = 0; +} + +void dump_genstmt(struct snode *stmt) { + while (stmt != 0) { + switch (stmt->type) { + case st_compound: + dump_genstmt(stmt->s1); + break; + case st_label: + dump_newnode("st_label"); + dump_addint("id",stmt->v2.i); + dump_endnode(); + dump_genstmt(stmt->s1); + break; + case st_goto: + dump_newnode("st_goto"); + dump_addint("id",stmt->v2.i); + dump_endnode(); + break; + case st_break: + dump_newnode("st_break"); + dump_endnode(); + break; + case st_continue: + dump_newnode("st_continue"); + dump_endnode(); + break; + case st_expr: + dump_newnode("st_expr"); + dump_expr(stmt->exp); + dump_endnode(); + break; + case st_return: + if (!stmt->exp || ret_type->type==bt_void) { + dump_newnode("st_return"); + dump_endnode(); + break; + } + switch (ret_type->type) { + case bt_struct: + case bt_union: +#ifdef BCDFLT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif +#endif +#ifdef SHORT_STRUCT_PASSING + if (ret_type->size<=4) { + if (stmt->exp->nodetype!=en_ref) + ierr(DUMP,1); + dump_newnode("st_return"); + dump_newnode("expr"); + dump_addreg("target",mk_reg(RESULT)); + dump_newnode("e_deref"); + dump_addint("esize",ret_type->size); + dump_expr(stmt->exp->v.p[0]); + dump_endnode(); + dump_endnode(); + dump_endnode(); + break; + } +#endif + assert(0); + dump_newnode("st_return"); + dump_newnode("expr"); + dump_addstr("target","__tmp_structreturn"); + dump_expr(stmt->exp); + dump_newnode(""); + dump_newnode(""); + break; +#ifndef BCDFLT + case bt_float: +#ifdef DOUBLE + case bt_double: +#endif +#endif + case bt_char: case bt_uchar: + case bt_short: case bt_ushort: + case bt_long: case bt_ulong: + case bt_pointer: + dump_newnode("st_return"); + dump_newnode("expr"); + dump_addreg("target",ret_type->type==bt_pointer?mk_reg(PRESULT):mk_reg(RESULT)); + dump_expr(stmt->exp); + dump_endnode(); + dump_endnode(); + break; + default: + ierr(DUMP,1); + } + break; + case st_if: + dump_newnode("st_if"); + dump_newnode("condition"); + dump_expr(stmt->exp); + dump_endnode(); + dump_newnode("true"); + dump_genstmt(stmt->s1); + dump_endnode(); + dump_newnode("false"); + dump_genstmt(stmt->v1.s); + dump_endnode(); + dump_endnode(); + break; + case st_asm: + dump_newnode("st_asm"); + dump_newnode("TODO"); + //dump_asm((struct ocode *)stmt->v1.i); + dump_endnode(); + dump_endnode(); + break; + case st_while: + dump_newnode("st_while"); + if (stmt->exp) { + dump_newnode("condition"); + dump_expr(stmt->exp); + dump_endnode(); + } + dump_newnode("body"); + dump_genstmt(stmt->s1); + dump_newnode("st_labelcontinue"); + dump_endnode(); + dump_endnode(); + dump_endnode(); + break; + case st_do: + dump_newnode(stmt->exp ? "st_do" : "st_while"); + dump_newnode("body"); + dump_genstmt(stmt->s1); + dump_endnode(); + if (stmt->exp) { + dump_newnode("condition"); + dump_expr(stmt->exp); + dump_endnode(); + } + dump_endnode(); + break; + case st_for: + if (stmt->exp) { + dump_newnode("st_expr"); + dump_expr(stmt->exp); + dump_endnode(); + } + dump_newnode("st_while"); + dump_newnode("condition"); + dump_expr(stmt->v1.e); + dump_endnode(); + dump_newnode("body"); + dump_genstmt(stmt->s1); + if (stmt->v2.e) { + dump_newnode("st_expr"); + dump_expr(stmt->v2.e); + dump_endnode(); + } + dump_endnode(); + dump_endnode(); + break; + case st_switch: + default: + ierr(DUMP,2); + } + stmt = stmt->next; + } +} + +void dump_genfunc(struct snode *stmt) { + opt1(stmt); + dump_newnode("function"); + dump_newnode("returns"); + dump_type(ret_type); + dump_endnode(); + dump_newnode("code"); + dump_genstmt(stmt); + dump_genreturn(NIL_SNODE); + dump_endnode(); + dump_endnode(); +} diff --git a/gtc/src/vcg.c b/gtc/src/vcg.c new file mode 100644 index 0000000..3547009 --- /dev/null +++ b/gtc/src/vcg.c @@ -0,0 +1,98 @@ +#ifdef VCG +#ifdef PC +#define MAXINT 0x7FFFFFFF +#endif +#ifndef __HAVE_STACK_IMAGE +#define __HAVE_STACK_IMAGE +typedef struct _stackimg { + int next_data,next_addr; +#ifndef INFINITE_REGISTERS + int reg_alloc_ptr,reg_stack_ptr; + char dreg_in_use[MAX_DATA+1]; + char areg_in_use[MAX_ADDR+1]; + struct reg_struct reg_stack[MAX_REG_STACK+1],reg_alloc[MAX_REG_STACK+1]; + int act_scratch; +#endif +} STACK_IMAGE; +#endif +STACK_IMAGE vcg_img[VCG_MAX+1]; +int vcg_nxl[VCG_MAX+1]; +int vcg_aborted[VCG_MAX+1]; +int vcg_init() { + if (--vcg_lvl<0) { + vcg_lvl++; + return 0; + } +// tmp_use(); + usestack(&vcg_img[vcg_lvl]); + vcg_peep_head[vcg_lvl]=0; + vcg_aborted[vcg_lvl]=0; + vcg_nxl[vcg_lvl]=nextlabel; + g_code(op_label,0,0,0); + return 1; +// vcg_on++; +// vcg_cost[vcg_lvl]=0; +} +int en_dir_cost(struct enode *ep) { + switch (ep->nodetype) { + case en_icon: + return (ep->v.i>=-32768 && ep->v.i<32767)?1:2; + case en_labcon: + case en_nacon: + return 1; + case en_add: + case en_sub: + return max(en_dir_cost(ep->v.p[0]),en_dir_cost(ep->v.p[1])); + } +} +int cost_tab[] = { + 0,0,0,0,0,1,1,1,-MAXINT-1,2,1,1,1,1,2,0,0 +}; +int vcg_cost() { + int cost=0; + if (!vcg_aborted[vcg_lvl]) { + struct ocode *ip; + opt3(); + ip = peep_head; + while (ip != 0) { + #define am_cost(x) (x?(x->mode==am_direct?en_dir_cost(x->offset):cost_tab[x->mode]):0) + cost++; + switch (ip->opcode) { + case op_label: + case op_even: + cost--; + break; + case op_moveq: + case op_addq: case op_subq: + case op_lsl: case op_lsr: case op_asl: case op_asr: + case op_rol: case op_ror: case op_roxl: case op_roxr: + case op_trap: + cost+=am_cost(ip->oper2); + break; + case op_bxx: + /* what should we do here? */ + break; + case op_dbxx: + cost++; + break; + default: + cost+=am_cost(ip->oper1)+am_cost(ip->oper2); + break; + } + if (cost<0) cost+=(-MAXINT-1)+((ip->length+1)>>1); + ip = ip->fwd; + } + // vcg_on--; + // tmp_free(); + } else cost=12345; + return cost; +} +int vcg_done() { + freestack(&vcg_img[vcg_lvl]); + nextlabel=vcg_nxl[vcg_lvl]; + int cost=vcg_cost(); + vcg_lvl++; + return cost; +} +#endif +// vim:ts=4:sw=4 diff --git a/gtc/src/version.h b/gtc/src/version.h new file mode 100644 index 0000000..40dbaa1 --- /dev/null +++ b/gtc/src/version.h @@ -0,0 +1,8 @@ +#ifndef VERSION_H_ +#define VERSION_H_ + +#define GTC_MAJOR 0 +#define GTC_MINOR 902 +#define GTC_VERSION "0.90.2" + +#endif diff --git a/h/Makefile b/h/Makefile new file mode 100644 index 0000000..03c8f46 --- /dev/null +++ b/h/Makefile @@ -0,0 +1,24 @@ +BIN=../bin +STRIP = perl script/strip.pl +TXT89 = $(BIN)/txt89t + +all: src/*.h + $(RM) *.89t + $(RM) processed/*.89t + $(RM) -r stripped + mkdir stripped + sh -c 'for f in src/*.h; do $(STRIP) "$$f" > "stripped/$${f#src/}"; done' + $(TXT89) --compact -f gtchdr stripped/*.h + mv *.89t processed + $(RM) -r stripped + touch all + +clean: +distclean: clean +scratchclean: distclean + $(RM) processed/*.89t all + +include ../config.mk +install: all + mkdir -p $(prefix)/share/gtc/include + install -m 644 src/*.h $(prefix)/share/gtc/include diff --git a/h/all b/h/all new file mode 100644 index 0000000..e69de29 diff --git a/h/legacy/README b/h/legacy/README new file mode 100644 index 0000000..23ccd55 --- /dev/null +++ b/h/legacy/README @@ -0,0 +1 @@ +These files are deprecated, but I'm leaving them here for reference purposes. diff --git a/h/legacy/ezgen b/h/legacy/ezgen new file mode 100644 index 0000000..93fddff --- /dev/null +++ b/h/legacy/ezgen @@ -0,0 +1,67 @@ + #include "inclgen" + #include "genle" + #ifdef RESOURCE + FILE *resf=0; + #ifdef RES_TYPE + RES_TYPE *data=0; + #else + void *data=0; + #endif + #endif + DSCREEN *scr1=0,*scr2=0,*sc=0; + #ifdef DISP_SCR + DSCREEN *sd=0; + #endif + + int curscr=0; + void gl_main(); + void gl_upd() { + if (!curscr) { + gl_set_dscreen_int( + #ifdef DISP_SCR + sd= + #endif + scr1); + gl_set_dscreen_function(sc=scr2); + } else { + gl_set_dscreen_int( + #ifdef DISP_SCR + sd= + #endif + scr2); + gl_set_dscreen_function(sc=scr1); + } + curscr=~curscr; + } + int gl_load() { + int hd; + gl_init(); + gl_init_dscreen(&scr1, &hd); + if (!hd) goto nohd; + gl_push_hd(hd); + gl_init_dscreen(&scr2, &hd); + if (!hd) goto nohd; + gl_push_hd(hd); + gl_upd(); + #ifdef RESOURCE + resf=fopen(RESOURCE,"rb"); + if (!resf) goto nohd; + (void *)data=*(void **)resf; + #ifdef GFX_RES + gl_set_spr_xy(0,0); + gl_set_spr_tile(data); + #endif + #endif + return 1; + nohd: + return 0; + } + void _main() { + if (gl_load()) gl_main(); + #ifdef RESOURCE + if (resf) fclose(resf); + #endif + gl_wait_no_key(); + gl_free_hd(); + gl_quit(); + } diff --git a/h/legacy/ezgensc b/h/legacy/ezgensc new file mode 100644 index 0000000..fb9ad39 --- /dev/null +++ b/h/legacy/ezgensc @@ -0,0 +1,42 @@ + #include "inclgen" + #include "genle" + #include "sccomm" + #include "scliba" + #ifdef RESOURCE + FILE *resf; + #endif + + void gl_main(); + int gl_load() { + GLB + int hd; + gl_init(); + gl_init_dscreen(&g scr1, &hd); + if (!hd) goto nohd; + gl_push_hd(hd); + gl_init_dscreen(&g scr2, &hd); + if (!hd) goto nohd; + gl_push_hd(hd); + gl_upd(); + #ifdef RESOURCE + resf=fopen(RESOURCE,"rb"); + if (!resf) goto nohd; + (void *)g data=*(void **)resf; + #ifdef GFX_RES + gl_set_spr_xy(0,0); + gl_set_spr_tile(g data); + #endif + #endif + return 1; + nohd: + return 0; + } + void _main() { + if (gl_load()) gl_main(); + #ifdef RESOURCE + if (resf) fclose(resf); + #endif + gl_wait_no_key(); + gl_free_hd(); + gl_quit(); + } diff --git a/h/legacy/genle b/h/legacy/genle new file mode 100644 index 0000000..c59cdc6 --- /dev/null +++ b/h/legacy/genle @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/h/legacy/inclgen b/h/legacy/inclgen new file mode 100644 index 0000000..9e42b25 --- /dev/null +++ b/h/legacy/inclgen @@ -0,0 +1,4 @@ +#define USE_KERNEL +#include +#define X 160 +#define Y 100 diff --git a/h/legacy/include b/h/legacy/include new file mode 100644 index 0000000..27bda51 --- /dev/null +++ b/h/legacy/include @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/h/processed/COPYING b/h/processed/COPYING new file mode 100644 index 0000000..2ba72d5 --- /dev/null +++ b/h/processed/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/h/processed/assert.89t b/h/processed/assert.89t new file mode 100644 index 0000000000000000000000000000000000000000..e64b549ec32d83efc5eeadd68fdb479357fb0702 GIT binary patch literal 222 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0o5iJ7pE4LFfb@GFf-f(@|Q+|4QOFtR8Y=L z%S%a3Q}A2j~ts!>nTdh3SNUq3Z!4%u~ZcyS_%x}rW%!%r0T^E-0z z@i$eY8@r9`ZD`dr=Zks+e(rpa2BV=dvW=l-&S?-j2e5YbdxpDS2mUdlU;X3m$@g4( zy>-GCTW@&2yW7;ECmP$kOze(rHm}Y;wNP z4^K4x>%<~xp^7$i81`mmX$!(ax@7T9TLD8Gliu4^?7WalrwX=bL<-$1QZ<)Tf|aXS zdsa-MSA`?jg$jq2ygs}&rz(-nO%=YF=(+BxmtbPP7-HD&xrgkuCrfar%@?{krE?6A z7;k^{auWy8h7^WtZr*}N=jhQ4^CQ@~EtX-J{AdC2e0TxTkeSsw}m8D8WvfFC>V?FdvtLaizRRtWzY0t5xFC z^DNYD5`@{o47)|9EU*9rw=)o3b;<2TI^+de;i2rLqkuT#-Xd9%Q-lJEFHaH@Bo6il LVR$mBUybb_X#sIV literal 0 HcmV?d00001 diff --git a/h/processed/default.89t b/h/processed/default.89t new file mode 100644 index 0000000000000000000000000000000000000000..4966a1f5b28f3b4d0bf1bea926d74a00c7715f76 GIT binary patch literal 3054 zcmb_e-EP}96n3yX_a#^u2qYmLY_}bpH4UK1bShMq3`q{w76su%RHDX~3|ZO|w7uIS z>}C(J_u3Qe8Fna26eTN5H!L@?4!`rm@BC5Id~21X9k}9);mChD2(A45i-RyeQEjq0enU=l_gQgAWIJu-#i{K1Vl)z zrPm+OIEcbN7<|et1PVW&9IJyzV_fU7oyOb`68qY(W+uHl}O zW8&D>JK+buFfnw?D8r%xcO}LDoNvk#@PsEhx1FSGAXO#2TPV8Z*%B&63#~ zKI(w;Hrj(e7f`z1Q5GPd7<=~;M^)d8jMjeTFbgyPB2IySJW$R=Nr>R3&Pk)0+ha%+ zPenzYqzl~@Y*eR2_kEXm{*(|HnyV~Jqsu&_geVFjyX$o*X_lvP!wyU%>r6M^g4a5PnsYAnO~)&&KLTk)BCxfz({2?3IH-QMap#6XNLy%` zX9UFibfxr~)1{2mea4uY?#&;$PKBytmkFw+ok5k97STO)r6T$Y$m8jNe%fqFcDY81 zru>{lfu?C{W4)0y*^sN%daYzftD{H-oRTS8nM=sKnWS|{VNO&zMwPB#+o&TQsk-1q*g%lR~i1)^YEO&@LV`IDPmEg}1|(k-WpKi>9OcPqD8KZCO&N1qV)&J_`z-~FXmlS-n>86{!Dp9?+8@Nz&c-H>VXFl{`*%S$@e6 MI+j%L&tHH48&M6URsaA1 literal 0 HcmV?d00001 diff --git a/h/processed/doors.89t b/h/processed/doors.89t new file mode 100644 index 0000000000000000000000000000000000000000..c79f0db4e5ef392a8780ba3235a1b7f00db79c5f GIT binary patch literal 906 zcma))QHt9z5Qd%REvL}N5F`^qA6qB|uOp~wVg*@VLSF`NByUU|8DyJM*c0>~y;qM? zIZk3{4W)h=N%PP5kH+#m5q|jSc@yWQJ{+ZS{`;Fa+-hZ6n##rpXX^Z#I?nHJEnxcI znIJdMv{V^dGsfeYYnQoJ*Ik~qsffiQd7Qb*n9|J8tkrRTYN{IPvPRDe<@!)GQc1g* z>$0kw=lQ9W>S5+KL%1p`HM52-lhnYvO$Mbx8xV4l}T&WiYv=T z-<8p-KrMS^E49os%j?WPS!&u8_3HTfY73@3!67Y*(E+4Vn%iw}I$ST)Wlpe%ag99y zUkDB&WHA6q30?qaTL}Ek23$8Mgp3JiFt&&{+Fp4|bBzf=7yEOQcD>?!SrhAjM)*U! zv3BS-lwOC-sYrMPPyQyMeRV|X8UnW6ZRj4hei-$m?A}7efbK&9akASnZvWBcRlvV0 zQ74jktRk&*0KkD6IM^Xzp literal 0 HcmV?d00001 diff --git a/h/processed/extgraph.89t b/h/processed/extgraph.89t new file mode 100644 index 0000000000000000000000000000000000000000..1ea97098b6829abcb8158edf5ca2126aff0f6d76 GIT binary patch literal 113 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0oA5fl%y9W7Gx+gFf$Ya`Aeg~28c5-Dkx{9 SCZ?no*}#<8aWOpTW(NTIj}e;y literal 0 HcmV?d00001 diff --git a/h/processed/gen.89t b/h/processed/gen.89t new file mode 100644 index 0000000000000000000000000000000000000000..7baf2e82abce6a8b76349615188996b303eb0355 GIT binary patch literal 108 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0oA6b=7Du6GB7jb09i|;z+52)Mg`@J)Wnq3 OA{(F*J1&L?v8(_~I1LW~ literal 0 HcmV?d00001 diff --git a/h/processed/nostub.89t b/h/processed/nostub.89t new file mode 100644 index 0000000000000000000000000000000000000000..2897f15db638ae19579d3a7fa72be1994b3d9b69 GIT binary patch literal 629 zcma)3OKQU~6jaikuh2ym8;WH@)-9BRlc->@EhEVxWb<%hyD|6!{_Jv{?s}*mrFLDb z>84a0N%Lmr&66xkIuDPQHAAoM=^WSS-)n|=&n>H_?T!d7&<*P52)!K!gZV9*VIxb+ zI7zY3gbdf3(Vw$2QP(UTid)9G(2S(6t6Cq;R%gBFniiK;i;oG;%2VFON!%awZB^Bc zUQ}_i(2VYvdy+SaW_**Mdh4jm+tvBG$5K4Dj?GX|cyS${0%sm=oi^IrLbVPu3TOBP7Sa}HPi``ODl zONW@ld;CdIa|nA!L2Njs{#AZXWypQl*=|UCcrnf8GoX7%f(V0vae1YnzP)xSP|g{L vQQk)#br^g~x3FPe;L<&Kw&Sa;6QhW-(j)-m{-Yc}5`W=JG|q`W?%qEEuTZt7 literal 0 HcmV?d00001 diff --git a/h/processed/patch.89t b/h/processed/patch.89t new file mode 100644 index 0000000000000000000000000000000000000000..094e1d461f810a97669cbeb0e4af106e15dca861 GIT binary patch literal 5660 zcmbVQ%W~t^5#>~N*e9zjIK!$ba)y!tkb=lbdBLGE9#$w)#fLnJ>AD3HkVFS0C;%GL zj_p6mGC$%k@j73T)Axl7iZgLV3lX@ukM7gmr@QZ~SF=H<`|8!R%3Z#?57Wx;{(DxL zVD2u!GW}!AIPX>L~oAlogZhQ+LXnf+& z=93Y-=?&)?!^nCYRT<0jw0>yR4#vS?9)I77H zm*~;Sp!arY3Uf1pM3bA>^=$oPl-$;_4auSxK=ekVVMT{LO1IV3eUS3`-+uQOs}^m; z^{xJSLdY$|G{VD`AiGMM!x?Q>yNLlhyDk4)f}EQkBjgFv1Q_QhvQ4nwzR}zAS7=A0kS5NeVx#G7{#H-a z>$gdkKQ6ID8HuvWo8)739#_Lw^Q<0RHmqgzu-GOn-> zX)WR;*;zptKAi7sE{$Z5%ZKxro?FI3e!%w`Y&02Pv3_qjWNxb`ChV)B-P98B4aJEx z_FC_QX_xdO0T7xUZP~F2nUctS~XM+*@`u%u1W7F$i-&d-*Hq^GQ zU>ib5`{3L3MK6K3dL5+?ZM&~_J&%GKNpujyR6+^dX_yC{Gs-|t(T zzE~PPJg(CytnXG(HVqb=?2bi;b#57wDmqiK8e`#L_i8-aCmF3=Q`~+ zy)Rd*^UM@+nME9yjxrs0XNBDv)PmW77&jZaC!VEaI~rqzj)Tz2b`8V&rS~#?POH-v z_}LcxmL5gq#5GuPr#6v`gboh5*BM_{(qg^M@*s{az-j0uP$b=!2tbF6mgboyr^rQb z_(>abK=&;0z6e`qh%6yEpgnVKT3AQ~Q?|MnZZpsUEl^fL;OQU`UhcFU`w|YP;{fval>gwaPcjL2Zf8zV2#>|=tk6yrC)4@$ z^>{L4lnjs&`cux`{E?03S0do{H9bI*fXGo&C@9NvG%UeNe43~Lq`2deFLoJ^hJWLX z#Fb3`LHi+_5-}Dde5v56eVT0VxMoiYN~&|bP?43CtyD+|aYo20NZMe#PvrD+aZs99 zDr`ULaFd4gP7|t5w|(L9r;Zt@Zu?SjVc-hN!ahf4M9txU z7$8jwYjUF#w{TYZf`^pk7PYXHZYdfDqZ#4>bJW>7%4%g(gxQ$V( zvU_-Z9BD_Rn6?j+hY@}@4@w}3*{R}THhzqJxM;A z7>-4Q)^ce3xDnAT*+WJ%P$kU0wnC;1<>!q0du&C!zW%(mBwi}oKH-I8Bf}MsP(O+j zBOXM0Dnf%NY!OA6RVXf;OPqrsQ8<)*{A62j5@YT!+-YSo&V5EYt=;vgPA)u}TbP%O zRN|>h0YakQSp=KRVOY+aA^tZ;>NgrtIAL#U@f6LF}jyu~g}?$ThxsDh!Ss}dMh^pp$Cer1(L0s0m4=vZ_! zJaBZg;dq{^wc5=9eT!;z0YXn zP=gpJ@u^bP@^LDxi3i?JrX|l44rw9=11rBTIw7rHQ$EpLj{d&olw~c4%Wsl zRrH=+kbyAQdyW#`FBZW$5u2g3lw1GG-QSmE6~`9 zN{VW43T+-hjNOdPut6(F!DvPeahs@gsd^TQ%Zz;zo|49f3psYT$tFG7DBJcs14OA* z(MQu{GZz1c^krx5c$~;TA+(hJ)Q^ac&k=n&Rg0$Md@mVU$1-Pn)nfAOqWf7w7wx}F z=dRsG|8HAy7E^;vkEVegGLp%T;54d~&-cPa%Dpu+>pI=2B4rV8RO>1jiz>B&8ebKl zAchl{1r1BLu~O|At+KoeC^)u60%h)_PPjyWC*r4wEAsooA1-hqCzUM!e70|S`BLd* zz=7f(H*6oHt!0+?g2B&wy*+-AKft_3yJCrqcdd~!iSJHP*?bxoJ9Rds9eWK+$WGO~?p X$uD0l>=&mlF$=+jxhlW?=U@K?Bu%Hc literal 0 HcmV?d00001 diff --git a/h/processed/std.89t b/h/processed/std.89t new file mode 100644 index 0000000000000000000000000000000000000000..13d9c73aa41fa2f4b38d5a5f658bc0bf830a7a48 GIT binary patch literal 168 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0o4|lq=0oOGB7i&0J4@wfw_JRj0(z`X?ZEB zX$r0po+0tUp#cH@K_OhqK#|P6R0Ti(cvSJ!yp+r|F6GR;6>RMUoBH)r(H{pLFssPW3w1BN~bc`|qd4$&*x T;0Nf9Z0$tbt$5AD=lJvmyBc*5 literal 0 HcmV?d00001 diff --git a/h/processed/ttunpack.89t b/h/processed/ttunpack.89t new file mode 100644 index 0000000000000000000000000000000000000000..742d0969b7a28437bfe3a6c5568ba9a82cdc17d1 GIT binary patch literal 3610 zcma)8+iqJ`5Ou}dk>CS(GD522Xd~_WMQK59o0h61uF?dRB4k<4A+g9!wu7LhpTke^ z#Ha8nthM(!$Hq>9_MtwrXV0uzvu1X8caNXPw7Yw+ceb3KpU!*#`_H}J5qy`++pC+& z^rz2yAN4-{q}TiX4Fi1qXYXEr`Rh%6TL0KzEa$h=<-6+kYB4*zs!#jV^U1t_y_mhN z#~0UociPWqoA%4e*=(xrwCYXk^aHVreLHr&*p7U4y}Vu2r)D#DW4D`j#Mr`dHo3f< zY+=sUE#LZ=<$QASb~9{~ZYxM*-wHFosOzicd{!^^s`tmoCx)4p*&VgL9+Tdk@y&R!v(q(oaeh5t!m!iDE=hL>*>mv4 zmu<&?`){Z7*@FjhFc@s7{&{jSJ8g1*I8_nL!-pM~Qs@2q{{k=H(VKVl3PTrc^kVp3 ze??1YKOF79di->Ba`>dLZS1gj=Qw@z{P-0P)Ar%P@b$Cd!NIVv-5sI#UmqV0zj^Z# zr)vA|;V9RKL%n@CIyruH@^tj={?XCNAzaM13j&W`0e0)MQbX7B(|US+c{8sUi~eTQ zchKTa2Au6(@z2k}U_8Df&|o$BSv>tay}tk9;k!yj?~O1zcrCQF`0brjT0|p_h*B8E z4=Zr$m6oC^1{}a(f)`2~8wL0g+B$s0OQ;}?6hX@FTt&9rU zCWTeTi;B0M)kv6Bgrn5n!9gV>6pYaan~gRb;jBdk*QA9B)^@H49X;XuWMH&b$`+|j zD9Rd95w(m_Al*6yrG#|~h?x)7Sh_1w;ma9EM(`E#2h*48kuO*8SQL<>aO=GFaPwfH zbyJO-W%$OJ}kY=|Eh z(Ug$DlQZQapj(4B0;a@8Xd*`dWk`g(7BVUKm))DKil27E4{%~>%NHF^vU zY73XhFl$lTiwa?t)-mO)C>vtyu4c(FRbt;umos0M^SVYq&d{E!F@XkLie5XC5y85n zs$AAho@?a{)`ZqRv~sSzGm0#4LMcUbMO!L3%cdl&+Wu2!)+2fzI>*kyFMwnI;3qrR zG{8iM8D%IPaSw3UyS5&m>xH!X09Kl&X4vaaMX_r_HS7T=rwkk94+=}?kkoodDS$)l zC!ZNenP13^O(NLJVAmD26bUsa6&EXhx}+r(R`immgN?|NQjPEpL6^4w}{S_-ID!JX6-99r5CNo;UutFxX9j)1c9-N1nE3k^*s(1-E@ zd9~c43M0e`Lvfg1AV!-C;x>+HUk0c|Q6*V!g(%G_&0_^D>y0E)P<=ClRa>&mdxz6h z-YR4RQ6Xhc7)s*Jkoa4*x&bc8KZZQ`Wel}KGc}$f9lEFR6_y zgRKi48ldb9fmgBYfI&OVhvbx$xrSiSEkr>*T451^-w3!Vz_HZQtXKfxB0+X;np_Mv z6SjQ}*i~&oCdV;+LS4*5v{n&;vuOzdSjvzLa8{@Y+b2KO+<$r1@^Nh~;3PlD QIeEtUey{5N^~YC#1Kz1h8~^|S literal 0 HcmV?d00001 diff --git a/h/processed/xupak.89t b/h/processed/xupak.89t new file mode 100644 index 0000000000000000000000000000000000000000..131ce3a9ace1dae66d118c6b810f383e40cb6bc6 GIT binary patch literal 429 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0o7KN79?f^X+;KRhP8|g3`?Ux1~3LQFe;Q( z7Nn-6rYRJc6qP2IRC8tKl_=yUre`Kc8^v04mF5*^rst)mD1d}Z3$lwdt5S6!lr>j! zMq-gdYH@N>W=XLQkT!q{DmmF7YPfSlxL1E6uW5dn_g@g6Qg)?CU!OEdFQ z6~H3Cj_#h$h6)-Q>h9_`HWr%N>LKcySd) { + chomp; + if (!$multicomment) { + s|//.*$| |g; + s|/\*.*?\*/| |g; + if (m|/\*|) { + s|/\*.*$| |g; + $multicomment=1; + } + } elsif (m|\*/|) { + s|^.*?\*/| |g; + $multicomment=0; + } else { + $_=''; + } + s|^\s+||g; + s|\s+$||g; + s|\s+| |g; + s|^(\#define \w+) |\1\t|g; + s|(\W) (.)|\1\2|g; + s|(.) (\W)|\1\2|g; + s:(? + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/h/src/assert.h b/h/src/assert.h new file mode 100644 index 0000000..14bac7e --- /dev/null +++ b/h/src/assert.h @@ -0,0 +1,5 @@ +#ifndef NDEBUG +#define assert(p) ((p)?(void)0:__assertion_failed(#p,__FILE__,__LINE__)) +#else +#define assert(p) ((void)0) +#endif diff --git a/h/src/compat.h b/h/src/compat.h new file mode 100644 index 0000000..c482067 --- /dev/null +++ b/h/src/compat.h @@ -0,0 +1,66 @@ +#ifdef DOORS + #define _CALCULATOR _ram_call(0,const unsigned char*) +#endif + +#if defined(DOORS) && !defined(_ONE_CALC_ONLY) + #define LCD_WIDTH _ram_call(1,unsigned long) + #define LCD_HEIGHT _ram_call(2,unsigned long) + #define LCD_LINE_BYTES _ram_call(4,unsigned long) + #define KEY_LEFT _ram_call(5,unsigned long) + #define KEY_RIGHT _ram_call(6,unsigned long) + #define KEY_UP _ram_call(7,unsigned long) + #define KEY_DOWN _ram_call(8,unsigned long) + #define KEY_UPRIGHT _ram_call(9,unsigned long) + #define KEY_DOWNLEFT _ram_call(A,unsigned long) + #define KEY_DIAMOND _ram_call(B,unsigned long) + #define KEY_SHIFT _ram_call(D,unsigned long) + #define CALCULATOR (_CALCULATOR[0]) + #define HW_VERSION (_CALCULATOR[1]) +#else + #if defined (_TI89_ONLY) + #define ROM_base ((void*)(((unsigned long)__jmp_tbl)&0xE00000)) + #define CALCULATOR 0 + #else +#if defined (_TI92PLUS_ONLY) + #define ROM_base ((void*)0x400000) + #define CALCULATOR 1 + #else +#if defined (_V200_ONLY) + #define ROM_base ((void*)(((unsigned long)__jmp_tbl)&0xE00000)) + #define CALCULATOR 3 + #else + #ifdef DOORS + #define ROM_base _ram_call (3, const void*) + #else + #define ROM_base ((void*)(((unsigned long)__jmp_tbl)&0xE00000)) + #endif + #ifdef NO_CALC_DETECT + #ifdef USE_V200 + #define CALCULATOR (ROM_base==(void*)0x400000?1:(((unsigned char*)(_rom_call_addr(2F)))[2]>=200?3:0)) + #else + #define CALCULATOR (ROM_base==(void*)0x400000) + #endif + #else + extern const short __calculator; + #ifdef USE_TI89 + #define CALCULATOR (__calculator) + #else + #define CALCULATOR (__calculator==3?3:1) + #endif + #endif +#endif +#endif + #endif + #define KEY_DIAMOND (CALCULATOR?8192U:16384U) + #define KEY_DOWN (CALCULATOR?344:340) + #define KEY_DOWNLEFT (CALCULATOR?345:342) + #define KEY_LEFT (CALCULATOR?337:338) + #define KEY_OFF2 (CALCULATOR?8459U:16651U) + #define KEY_RIGHT (CALCULATOR?340:344) + #define KEY_SHIFT (CALCULATOR?16384U:8192U) + #define KEY_UP (CALCULATOR?338:337) + #define KEY_UPRIGHT (CALCULATOR?342:345) + #define LCD_HEIGHT (CALCULATOR?128:100) + #define LCD_LINE_BYTES (CALCULATOR?30:20) + #define LCD_WIDTH (CALCULATOR?240:160) +#endif diff --git a/h/src/default.h b/h/src/default.h new file mode 100644 index 0000000..2ce67b6 --- /dev/null +++ b/h/src/default.h @@ -0,0 +1,132 @@ +#ifndef __DEFAULT +#define __DEFAULT + +#ifdef USE_TI92P +#define USE_TI92PLUS +#endif +#if !defined (USE_TI89) && !defined (USE_TI92PLUS) && !defined (USE_V200) +#define USE_TI89 +#define USE_TI92PLUS +#define USE_V200 +#elif defined(USE_TI89) && !defined (USE_TI92PLUS) && !defined (USE_V200) +#define _TI89_ONLY +#define _ONE_CALC_ONLY +#elif !defined(USE_TI89) && defined (USE_TI92PLUS) && !defined (USE_V200) +#define _TI92PLUS_ONLY +#define _ONE_CALC_ONLY +#elif !defined(USE_TI89) && !defined (USE_TI92PLUS) && defined (USE_V200) +#define _V200_ONLY +#define _ONE_CALC_ONLY +#endif +#if defined (USE_TI89) && defined (USE_TI92PLUS) && defined (USE_V200) +#define _SUPPORT_ALL_CALCS +#endif + +#ifdef DOORS +#define USE_KERNEL +#endif + +#if defined(EXECUTE_IN_GHOST_SPACE) && defined(USE_KERNEL) +#error EXECUTE_IN_GHOST_SPACE does not work in kernel mode yet +#endif + +#if !defined (NO_CALC_DETECT) && (!defined (USE_KERNEL) || !defined (_SUPPORT_ALL_CALCS)) +#define _NEED_CALC_DETECT +#ifdef _ONE_CALC_ONLY +#ifdef USE_TI89 +#define _CALC_NUM 0 +#endif +#ifdef USE_TI92PLUS +#define _CALC_NUM 1 +#endif +#ifdef USE_V200 +#define _CALC_NUM 3 +#endif +#else +#ifndef _SUPPORT_ALL_CALCS +#ifndef USE_TI89 +#define _CALC_NUM 0 +#endif +#ifndef USE_TI92PLUS +#define _CALC_NUM 1 +#endif +#ifndef USE_V200 +#define _CALC_NUM 3 +#endif +#endif +#endif +#endif +#if !defined (_ONE_CALC_ONLY) && !defined (USE_KERNEL) +#define _NEED_CALC_VAR +#endif + +#define __ATTR_STD__ __attribute__((__stkparm__)) +#define __ATTR_STD_NORETURN__ __attribute__((__stkparm__,__noreturn__)) +#define CALLBACK __ATTR_STD__ +#define __ATTR_TIOS__ __ATTR_STD__ +#define __ATTR_TIOS_NORETURN__ __ATTR_STD_NORETURN__ +#define __ATTR_TIOS_CALLBACK__ CALLBACK +#define __ATTR_GCC__ +#define __ATTR_LIB_C__ __attribute__((__regparm__(1))) +#define __ATTR_LIB_ASM__ __ATTR_STD__ +#define __ATTR_LIB_ASM_NORETURN__ __ATTR_STD_NORETURN__ +#define __ATTR_LIB_CALLBACK_C__ CALLBACK +#define __ATTR_LIB_CALLBACK_ASM__ CALLBACK + +#define __jmp_tbl (*(void***)0xC8) +//#define _rom_call(type,args,index) (*((type(*__ATTR_TIOS__)args)(_rom_call_addr_concat(0x##index,_ROM_CALL_##index)))) +//#define _rom_call_addr(index) _rom_call_addr_concat(0x##index,_ROM_CALL_##index) +//#define _rom_call_addr_concat(intindex,romindex) (__jmp_tbl[intindex]) +#define _rom_call(t,a,i) (*((t(*__ATTR_TIOS__)a)(__jmp_tbl[0x##i]))) +#define _rom_call_addr(i) (__jmp_tbl[0x##i]) +#define offsetof(t,m) ((unsigned long)&(((t*)0)->m)) +#define OFFSETOF offsetof +#define import_binary(f,i) asm { i: incbin f }; + +#ifdef _GENERIC_ARCHIVE +#undef OPTIMIZE_ROM_CALLS +#undef USE_FLINE_ROM_CALLS +#undef USE_INTERNAL_FLINE_EMULATOR +#endif + +#ifndef MIN_AMS +#define MIN_AMS 101 +#endif + +#ifdef USE_FLINE_ROM_CALLS +#if !defined (USE_FLINE_EMULATOR) && !defined (USE_INTERNAL_FLINE_EMULATOR) +#if MIN_AMS<204 +#error You need to define USE_[INTERNAL_]FLINE_EMULATOR +#endif +#endif +//#error _INCLUDE_PATCH(fline_rom_calls); +#endif + +#define TIOS_entries (*(unsigned long*)(__jmp_tbl-1)) + +#ifdef DOORS +#define AMS_1xx ((ROM_VERSION&0x0F00)==0x100) +#define AMS_2xx ((ROM_VERSION&0x0F00)==0x200) +#else +#define AMS_1xx (TIOS_entries<1000) +#define AMS_2xx (TIOS_entries>1000) +#endif + +typedef short *__pshort; +typedef unsigned short *__pushort; +typedef long *__plong; +typedef unsigned long *__pulong; + +//extern float __BC()__ATTR_LIB_ASM__; +//#define _tios_float_1(f,x,t) ({typedef float(*__temp__type__)(short,t)__ATTR_LIB_ASM__;((__temp__type__)__BC)(4*0x##f,x);}) +//#define _tios_float_2(f,x,y,t1,t2) ({typedef //float(*__temp__type__)(short,t1,t2)__ATTR_LIB_ASM__;((__temp__type__)__BC)(4*0x##f,x,y);}) + +#if !defined (NOSTUB) && !defined (DOORS) +#ifdef USE_KERNEL +#include +#else +#include +#endif +#endif + +#endif diff --git a/h/src/doors.h b/h/src/doors.h new file mode 100644 index 0000000..b1ff7ab --- /dev/null +++ b/h/src/doors.h @@ -0,0 +1,47 @@ +#ifndef DOORS +#define DOORS + +#ifdef NOSTUB + +#error "doors.h" must not be included in "nostub" mode! +#undef DOORS + +#else + +#ifdef EXE_OUT +#error As of now, you cannot generate EXEs in kernel mode. +#endif + +#include + +//#undef _rom_call_addr_concat +//#define _rom_call_addr_concat(intindex,romindex) (&romindex) +#undef _rom_call +#undef _rom_call_addr +#define _rom_call(t,a,i) (*((t(*__ATTR_TIOS__)a)(&_ROM_CALL_##i))) +#define _rom_call_addr(i) (&_ROM_CALL_##i) + +#define _main() __main() + +/* Begin Auto-Generated Part */ +#define _ram_call(i,t) ((t)(&_RAM_CALL_##i)) +#define _ram_call_addr(i) (&_RAM_CALL_##i) +/* End Auto-Generated Part */ + +#ifdef RETURN_VALUE +#define _NEED_COMPLEX_MAIN +#endif + +#ifndef NO_EXIT_SUPPORT +#define _NEED_COMPLEX_MAIN +#endif + +#if defined (_NEED_COMPLEX_MAIN) || defined (_NEED_AMS_CHECK) || defined (_NEED_CALC_DETECT) +#define NO_VSIMPLE_MAIN +#endif + +#if defined(ENABLE_ERROR_RETURN) && defined(_NEED_COMPLEX_MAIN) +#define SPECIAL_ERROR_RETURN +#endif +#endif +#endif diff --git a/h/src/extgraph.h b/h/src/extgraph.h new file mode 100644 index 0000000..1405f23 --- /dev/null +++ b/h/src/extgraph.h @@ -0,0 +1 @@ +#header \ No newline at end of file diff --git a/h/src/gen.h b/h/src/gen.h new file mode 100644 index 0000000..2c48c3e --- /dev/null +++ b/h/src/gen.h @@ -0,0 +1 @@ +#header diff --git a/h/src/nostub.h b/h/src/nostub.h new file mode 100644 index 0000000..bf5a027 --- /dev/null +++ b/h/src/nostub.h @@ -0,0 +1,36 @@ +#ifndef NOSTUB +#define NOSTUB + +#ifdef DOORS +#error "nostub.h" must not be included in "Doors" mode! +#undef NOSTUB +#else +#include + +#if defined(USE_FLINE_ROM_CALLS) || defined(EXE_OUT) +//#undef _rom_call_addr_concat +//#define _rom_call_addr_concat(intindex,romindex) (&romindex) +//#undef _rom_call_addr +//#define _rom_call_addr(index) (__jmp_tbl[0x##index]) +#undef _rom_call +#define _rom_call(t,a,i) (*((t(*__ATTR_TIOS__)a)(&_ROM_CALL_##i))) +#undef OPTIMIZE_ROM_CALLS +#endif + +#ifdef OPTIMIZE_ROM_CALLS +//#error OPTIMIZE_ROM_CALLS isn't supported yet +#endif + +/* Various conditional compilations are defined below, to make an extra */ +/* support code as small as possible. If no RETURN_VALUE and SAVE_SCREEN */ +/* options are defined, the code overload is only two extra bytes! */ + +#if defined(SAVE_SCREEN) || defined(RETURN_VALUE) || !defined(NO_EXIT_SUPPORT) || defined(ENABLE_ERROR_RETURN) +#define _NEED_COMPLEX_MAIN +#endif + +#define _main() __main() +#define _nostub _main + +#endif +#endif diff --git a/h/src/patch.h b/h/src/patch.h new file mode 100644 index 0000000..5ea85c1 --- /dev/null +++ b/h/src/patch.h @@ -0,0 +1,420 @@ +#ifndef _GENERIC_ARCHIVE +#ifdef RETURN_VALUE +#define __str(x) #x +#define __xstr(x) __str(x) +#define __var(x) x##1 +#define __xvar(x) __var(x) +#if !__xvar(RETURN_VALUE) +#define RETURN_VARIABLE +#define __VN __RV+(sizeof(__xstr(RETURN_VALUE))) +extern char __RV[]; +#endif +#endif +#undef RETURN_VARIABLE ///// bug in GTC!!!!!!! + +#ifdef EXE_OUT +#define _NEED_COMPLEX_MAIN +#endif + +#ifdef ENABLE_ERROR_RETURN +#define SPECIAL_ERROR_RETURN +#endif +asm { +#ifdef NO_VSIMPLE_MAIN +#define NO_MAIN +_main: +#define _main __main +#else +#ifdef NOSTUB +#define NO_MAIN +_nostub: +#endif +#endif +#ifdef EXE_OUT +// [params : d3=optional SYM_ENTRY* to twin ; a2=ROM_CALL table] + move.l d3,-(a7) + beq \no_twin_delete +#if 0 + move.l d3,-(a7) + moveq #0,d7 // we only need the current HSym as DelTwin will make it alright +\loop + addq.w #2,d7 + subq.l #2,d3 + move.l d3,(a7) + jsr _ROM_CALL_23A /* HeapPtrToHandle */ + move.w d0,(a7) + beq \loop + move.l (a7)+,d3 + move.w d7,d3 +#else +//#ifdef FULL_EXE +// // note that in fact the latter won't work, since SymDelTwin won't delete anything... +// move.l d3,a0 +// move.w 12(a0),d3 +// clr.w 12(a0) // hack so that SymDelTwin won't free the handle +//#else + // will work as long as we don't *need* to return a locked handle (TSR...) + // -> maybe should use full version for programs that need ghost space execution? +//#endif +#endif + jsr _ROM_CALL_280 /* SymDelTwin */ +#if 0 + move.l d3,(a7) // save the HSym +#else +//#ifdef FULL_EXE +// clr.l (a7) // for HeapRealloc +// move.w d3,-(a7) // save the HANDLE +// jsr _ROM_CALL_9F /* HeapUnlock */ +// jsr _ROM_CALL_9D /* HeapRealloc */ +//#endif +#endif +\no_twin_delete +#endif +#ifdef EXECUTE_IN_GHOST_SPACE + //-------------------------------------------------------------------------- + // get the HW parm block using the algorithm suggested by Julien Muchembled + //-------------------------------------------------------------------------- + move.l 0xc8,d0 + and.l #0xE00000,d0 // get the ROM base + move.l d0,a0 + move.l 260(a0),a1 // get pointer to the hardware param block + add.l #0x10000,a0 + cmp.l a0,a1 // check if the HW parameter block is near enough + bhs \is_hw1or2 // if it is too far, it is HW1 + cmpi.w #22,(a1) // check if the parameter block contains HW ver + bls \is_hw1or2 // if it is too small, it is HW1 + + //-------------------------------------------------------------------------- + // check for VTI (trick suggested by Julien Muchembled) + //-------------------------------------------------------------------------- + trap #12 // enter supervisor mode. returns old (sr) in d0.w + move.w #0x3000,sr // set a non-existing flag in sr (but keep s-flag) + move.w sr,d1 // get sr content and check for non-existing flag + move.w d0,sr // restore old sr content + btst.l #12,d1 // this non-existing flag can only be set on the VTI + bne \is_hw1or2 // flag set -> VTI -> treat as HW1 + + //-------------------------------------------------------------------------- + // check for HW3 + //-------------------------------------------------------------------------- + cmp.l #3,22(a1) // check the hardware version + bcs \is_hw1or2 // <3 -> proceed + + //-------------------------------------------------------------------------- + // now check for an appropriate ROM patch (HW3Patch?) + //-------------------------------------------------------------------------- + move.l 0xc8,a0 + move.l 0xc0*4(a0),a1 // abuse EX_stoBCD + tst.w 92(a1) // check for HW3Patch (ROM resident) + beq \ghost_done // if it is installed, we're done + cmp.l #0x100,0xac // check for HW3Patch (RAM resident) + beq \ghost_done // if it is installed, we're done + + //-------------------------------------------------------------------------- + // now we have a problem: we are on unpatched HW3 -> can't proceed + //-------------------------------------------------------------------------- + pea __hw3patch_required(pc) + bra \msg_exit + +\is_hw1or2 + #ifndef EXE_OUT + lea gtc_compiled,a0 + move.l a0,d0 + cmp.l #0x40000,d0 + bcc.s \ghost_done + bset.l #18,d0 + moveq #0,d1 + move.w -2(a0),d1 + add.l d0,d1 + subq.l #1,d1 + move.l d1,-(sp) + move.l d0,-(sp) + move.l 0xC8,a0 + move.l 1384(a0),a0 + jsr (a0) + addq.l #8,sp + move.l 0xC8,a0 + cmp.l #1000,-4(a0) + bcc.s \ghost_install + pea \ghost_done(pc) + bset.b #2,1(sp) + rts +\ghost_install: + movem.l a2-a6/d3-d7,-(sp) + lea -20(sp),sp + move.l #0x3E000,a3 + move.l a0,d0 + and.l #0x600000,d0 + add.l #0x20000,d0 + move.l d0,12(sp) + move.l d0,16(sp) + trap #12 + move.w #0x2700,sr + moveq #0xF,d3 + pea \ghost_cont(pc) + bset.b #2,1(sp) + clr.w -(sp) + move.l 0xAC,a0 + jmp (a0) +\ghost_cont + lea 20(sp),sp + movem.l (sp)+,a2-a6/d3-d7 + #endif +\ghost_done +#endif +#if defined(_NEED_CALC_DETECT) || (defined(SAVE_SCREEN) && !defined(USE_KERNEL)) + move.l 0xC8,a0 +#endif +#ifdef _NEED_CALC_DETECT + moveq #1,d0 + move.l a0,d1 + and.l #0x400000,d1 + bne \calc_d0 + clr.w d0 + move.l 0x2F*4(a0),a1 + cmp.b #200,2(a1) + blt \calc_d0 + moveq #3,d0 +\calc_d0 +#ifdef _NEED_CALC_VAR + lea __calculator(pc),a1 + move.w d0,(a1) +#endif +#ifndef _SUPPORT_ALL_CALCS +#if _CALC_NUM + subq.w #_CALC_NUM,d0 +#elif !defined(_NEED_CALC_VAR) + tst.w d0 +#endif +#ifdef _ONE_CALC_ONLY + beq \calc_ok +#else + bne \calc_ok +#endif + pea __wrong_calc(pc) + bra \msg_exit +#endif +\calc_ok +#endif +#ifndef _NEED_COMPLEX_MAIN + #ifdef NOSTUB + bra __main + #else + #ifdef NO_VSIMPLE_MAIN + bra __main + #endif + #endif +#else + #ifdef NOSTUB + #ifdef SAVE_SCREEN + pea (a2) + lea -3840(sp),sp + pea 3840 + pea 0x4C00 + pea 8(sp) + move.l 0x26A*4(a0),a2 + jsr (a2) /* memcpy */ + #endif + #ifndef NO_EXIT_SUPPORT + movem.l d3-d7/a2-a6,-(sp) + #endif + #endif + #ifdef USE_INTERNAL_FLINE_EMULATOR + move.l 0x2C,-(sp) + lea \fline_handler(pc),a1 + lea 0x600000,a0 + and.w #~4,(a0) + move.l a1,0x2C + or.w #4,(a0) + #endif + #ifdef SPECIAL_ERROR_RETURN + lea -60(sp),sp + pea (sp) + move.l 0xC8,a0 + move.l 0x154*4(a0),a0 /* ER_catch */ + jsr (a0) + tst.w d0 + bne \error_returned + #endif + #ifdef NOSTUB + jsr __main + #else + jsr __main + #endif + #if defined(ENABLE_ERROR_RETURN) + move.l 0xC8,a0 + move.l 0x155*4(a0),a0 /* ER_success */ + jsr (a0) + clr.w d0 +\error_returned + lea \error_num(pc),a0 + move.w d0,(a0) + lea 64(sp),sp + #endif + #ifdef USE_INTERNAL_FLINE_EMULATOR + lea 0x600000,a0 + and.w #~4,(a0) + move.l (sp)+,0x2C + or.w #4,(a0) + #endif + #ifdef NOSTUB + #ifndef NO_EXIT_SUPPORT + movem.l (sp)+,d3-d7/a2-a6 + #endif + #ifdef SAVE_SCREEN + pea 3840 + pea 16(sp) + pea 0x4C00 + jsr (a2) + lea 3864(sp),sp + move.l (sp)+,a2 + #endif + #endif + #ifdef SPECIAL_ERROR_RETURN + lea \error_num(pc),a0 + tst.w (a0) + beq \no_error + or.w #0xA000,(a0) + /* for AMS 1, to unlock the prgm hd */ + move.l 0xC8,a2 + cmp.l #1000,-4(a2) + bcc \ams1_err_ok + pea gtc_compiled-2(pc) + move.l 0x23A*4(a2),a0 /* HeapPtrToHandle */ + jsr (a0) + tst.w d0 + beq \ams1_err_ok + move.w d0,-(sp) + move.l 0x9F*4(a2),a0 /* HeapUnlock */ + jsr (a0) +\ams1_err_ok +\error_num: + dc.w 0 +\no_error + #endif +#ifdef EXE_OUT +\program_rts +#if 0 + move.l (a7),d0 + beq \no_twin_create + clr.l -(a7) + jsr _ROM_CALL_166 /* EM_twinSymFromExtMem */ + addq.l #4,a7 +\no_twin_create + addq.l #4,a7 +#else +#ifdef FULL_EXE + tst.w (a7) + beq \no_twin_free + jsr _ROM_CALL_97 /* HeapFree */ + addq.l #2,a7 +\no_twin_free +#endif + addq.l #4,a7 +#endif +#ifdef BSS_SUPPORT + pea __bss_start + jsr _ROM_CALL_A3 /* tios::HeapFreePtr */ + addq.l #4,a7 +#endif + movem.l (a7)+,d3-d7/a2-a6 + move.l 0xC8,a0 + move.l 0x97*4(a0),a0 /* tios::HeapFree */ + jmp (a0) // note : we can't use a _ROM_CALL here, as we need a jmp + #ifdef RETURN_VALUE + #error Not compatible yet. + #endif +#else + #ifndef RETURN_VALUE + rts + #else + #ifdef NOSTUB + #ifndef RETURN_VARIABLE + move.l (sp)+,a0 + cmpi.w #0x21EE,(a0) + bne.s \A2 + addq.l #2,a0 +\A2: + jmp 4(a0) + #else + move.l 0xC8,a0 + move.l 1060(a0),a1 + move.l (a1),-(sp) + move.l #0x40000000,-(sp) + pea __VN(pc) + move.l 0x86*4(a0),a0 + jsr (a0) /* VarStore */ + lea 12(sp),sp + rts + #endif + #else + #ifndef RETURN_VARIABLE + move.l _ROM_CALL_109,_RAM_CALL_00F + rts + #else + move.l _ROM_CALL_109,-(sp) + move.l #0x40000000,-(sp) + pea __VN(pc) + jsr _ROM_CALL_86 + lea 12(sp),sp + rts + #endif + #endif + #endif +/* #ifdef ENABLE_ERROR_RETURN +\error_num: +// move.w #0,#8 + dc.w 0 + #endif*/ +#endif +#endif +#ifdef USE_INTERNAL_FLINE_EMULATOR +\fline_handler: + move.w (sp)+,d0 + move.l (sp)+,a0 + move.w d0,sr + move.w (a0)+,d0 + and.w #0x7FF,d0 + lsl.w #2,d0 + move.l 0xC8,a1 + pea (a0) + move.l 0(a1,d0.w),a0 + jmp (a0) +#endif +#if (defined(_NEED_CALC_DETECT)&&!defined(_SUPPORT_ALL_CALCS)) || defined(EXECUTE_IN_GHOST_SPACE) +\msg_exit: + move.l 0xE6*4(a0),a0 /* ST_helpMsg */ + jsr (a0) + addq.l #4,a7 +#ifdef EXE_OUT + bra \program_rts +#else +#ifdef NOSTUB + rts +#else + jmp _ROM_CALL_51 /* ngetchx */ +#endif +#endif +#endif +#if defined(_NEED_CALC_DETECT) && defined(_NEED_CALC_VAR) + even +__calculator: + dc.w -1 +#endif +#ifndef NO_EXIT_SUPPORT +__save__sp__: + dc.l 0 +#endif + even +}; + +#if (defined(_NEED_CALC_DETECT)&&!defined(_SUPPORT_ALL_CALCS)) +char __wrong_calc[]="Wrong calculator model"; +#endif +#ifdef EXECUTE_IN_GHOST_SPACE +char __hw3patch_required[]="HW3Patch required"; +#endif +#ifdef RETURN_VARIABLE +char __RV[]="\0" __xstr(RETURN_VALUE); +#endif +#endif diff --git a/h/src/std.h b/h/src/std.h new file mode 100644 index 0000000..2fe1388 --- /dev/null +++ b/h/src/std.h @@ -0,0 +1,4 @@ +#ifndef EXIT_SUPPORT +#define NO_EXIT_SUPPORT +#endif +#include diff --git a/h/src/tigcclib.h b/h/src/tigcclib.h new file mode 100644 index 0000000..ed10eb2 --- /dev/null +++ b/h/src/tigcclib.h @@ -0,0 +1,17 @@ +#ifndef __TIGCCLIB +#define __TIGCCLIB +#define inline +#include +#header +#include +#include +#ifndef __SECONDARY_FILE__ +#include +#endif +#headeropt +#headeropt +#headeropt +#headeropt +#headeropt +#headeropt +#endif diff --git a/h/src/ttunpack.h b/h/src/ttunpack.h new file mode 100644 index 0000000..c23edb9 --- /dev/null +++ b/h/src/ttunpack.h @@ -0,0 +1,81 @@ +typedef struct { + unsigned char osize_lo; // original size lowbyte + unsigned char osize_hi; // original size highbyte + unsigned char magic1; // must be equal to TTUNPACK_MAGIC1 + unsigned char magic2; // must be equal to TTUNPACK_MAGIC2 + unsigned char csize_lo; // compressed size lowbyte + unsigned char csize_hi; // compressed size lowbyte + unsigned char esc1; // escape >> (8-escBits) + unsigned char notused3; + unsigned char notused4; + unsigned char esc2; // escBits + unsigned char gamma1; // maxGamma + 1 + unsigned char gamma2; // (1<osize_lo | (((TTUNPACK_HEADER*)(_p_))->osize_hi << 8))) +#define ttunpack_valid(_p_) (((TTUNPACK_HEADER*)(_p_))->magic1 == TTUNPACK_MAGIC1 && ((TTUNPACK_HEADER*)(_p_))->magic2 == TTUNPACK_MAGIC2) + +#define TTUNPACK_OKAY 0 +#define TTUNPACK_NOESCFOUND 248 +#define TTUNPACK_ESCBITS 249 +#define TTUNPACK_MAXGAMMA 250 +#define TTUNPACK_EXTRALZP 251 +#define TTUNPACK_NOMAGIC 252 +#define TTUNPACK_OUTBUFOVERRUN 253 +#define TTUNPACK_LZPOSUNDERRUN 254 + +#define ttunpack_decompress ((unsigned short(*)(unsigned char*,unsigned char*))__ttunpack_decompress) +unsigned short __ttunpack_decompress[] = { +0x48e7,0x7ffa,0x4fef,0xffe8,0x206f,0x0050,0x0c28,0x0054,0x0002,0x6608, +0x0c28,0x0050,0x0003,0x6708,0x303c,0x00fc,0x6000,0x0264,0x4286,0x1c28, +0x0006,0x4247,0x1e28,0x0009,0x4245,0x1a28,0x000a,0x5345,0x4240,0x1028, +0x000c,0x3c40,0x7201,0xeb69,0x3f41,0x000e,0x7002,0xeb68,0x3f40,0x000c, +0x7208,0x9245,0x3f41,0x000a,0x7008,0x9047,0x3840,0x303c,0x00f9,0x0c47, +0x0008,0x6200,0x021e,0x4240,0x1028,0x000b,0xb06f,0x000e,0x660c,0x0c45, +0x0004,0x6306,0x0c45,0x0007,0x6308,0x303c,0x00fa,0x6000,0x01fe,0x7204, +0xb24e,0x6408,0x303c,0x00fb,0x6000,0x01f0,0x43e8,0x000f,0x2f49,0x0010, +0x266f,0x0054,0x43fa,0x01ea,0x2f49,0x0006,0x226f,0x0010,0x4280,0x1011, +0x41f0,0x0810,0x226f,0x0006,0x2288,0x41fa,0x01d4,0x2f48,0x0002,0x30bc, +0x0080,0x3606,0x4a47,0x670c,0x3f07,0x41fa,0x0274,0x4e90,0x3600,0x548f, +0x3043,0xbc88,0x6600,0x018c,0x3f05,0x45fa,0x021a,0x4e92,0x3800,0x426f, +0x0002,0x548f,0x0c44,0x0001,0x6754,0x3f05,0x4e92,0x3600,0x5343,0x302f, +0x000e,0x5540,0x548f,0xb043,0x6618,0x0c44,0x0003,0x6300,0x0170,0x45fa, +0x017e,0x4e92,0x3f40,0x0000,0x4e92,0x6000,0x0120,0x300e,0x6710,0x3f0e, +0x41fa,0x021a,0x4e90,0x320e,0xe36b,0x8640,0x548f,0x41fa,0x015a,0x4e90, +0x0a40,0x00ff,0x3203,0xe149,0x8240,0x6000,0x00fe,0x226f,0x0006,0x2051, +0x4240,0x1010,0x206f,0x0002,0x3210,0xc041,0x6700,0x00ca,0xe219,0x6402, +0x5291,0x3081,0x2051,0x4240,0x1010,0xc041,0x6630,0x3001,0xe218,0x6402, +0x5291,0x226f,0x0002,0x3280,0x3f07,0x45fa,0x01c0,0x4e92,0x3600,0x3f0c, +0x4e92,0x320c,0x48c1,0xe3ae,0x8c00,0x16c6,0x4286,0x3c03,0x588f,0x6000, +0xff26,0x3001,0xe218,0x6402,0x5291,0x206f,0x0002,0x3080,0x3f05,0x4e92, +0x3600,0x548f,0xb66f,0x000e,0x6522,0x3f2f,0x000a,0x41fa,0x0180,0x4e90, +0x966f,0x0010,0x322f,0x000c,0xe36b,0x8640,0x3f05,0x4e92,0x5340,0xe148, +0x8640,0x588f,0x3f05,0x4e92,0x3800,0x548f,0x0c44,0x001f,0x6210,0x4280, +0x3004,0x206f,0x0010,0x1230,0x0800,0x4881,0x6016,0x3f3c,0x0003,0x41fa, +0x0140,0x4e90,0x3204,0x0641,0xffe0,0xe749,0x8240,0x548f,0x4242,0xb642, +0x6500,0xfeac,0x16c1,0x5242,0xb642,0x64f8,0x6000,0xfea0,0x3001,0x226f, +0x0006,0xe218,0x6402,0x5291,0x206f,0x0002,0x3080,0x41fa,0x0056,0x4e90, +0x3200,0x0a41,0x00ff,0x4242,0xb842,0x6500,0xfe7a,0x4280,0x3001,0x204b, +0x91c0,0x102f,0x0001,0xd028,0xffff,0x16c0,0x5242,0xb842,0x64e8,0x6000, +0xfe5e,0x3f0c,0x41fa,0x00d6,0x4e90,0x320c,0xe36b,0x8600,0x16c3,0x548f, +0x6000,0xfe48,0x4240,0x4fef,0x0018,0x4cdf,0x5ffe,0x4e75,0x0000,0x0000, +0x0000,0x41fa,0xfff8,0x2250,0x4240,0x1019,0x2089,0x323a,0xfff0,0x0c01, +0x0080,0x6602,0x4e75,0xe148,0x1011,0x0c01,0x0008,0x6212,0x6630,0x0240, +0x0fff,0xe848,0x4e75,0x0240,0x7fff,0xee48,0x4e75,0x0c01,0x0020,0x62f2, +0x6508,0x0240,0x3fff,0xec48,0x4e75,0x0240,0x1fff,0xea48,0x4e75,0x0240, +0x07ff,0xe648,0x4e75,0x0c01,0x0002,0x62f2,0x6608,0x0240,0x03ff,0xe448, +0x4e75,0x0240,0x01ff,0xe248,0x4e75,0x2f03,0x4281,0x302f,0x0008,0x207a, +0xff84,0x343a,0xff84,0xb041,0x6312,0x3602,0xc610,0xe21a,0x6402,0x5288, +0x4a03,0x6704,0x5241,0x60ea,0x2608,0x41fa,0xff64,0x2083,0x41fa,0xff62, +0x3082,0x2043,0x7601,0xe36b,0x3f01,0x6108,0x544f,0x8043,0x261f,0x4e75, +0x4240,0x322f,0x0004,0x6730,0x207a,0xff3e,0x2243,0x343a,0xff3c,0x5341, +0xe348,0x3602,0xc610,0x6702,0x5200,0xe21a,0x6402,0x5288,0x51c9,0xffee, +0x2609,0x43fa,0xff20,0x3282,0x43fa,0xff16,0x2288,0x2243,0x4e75}; diff --git a/h/src/xupak.h b/h/src/xupak.h new file mode 100644 index 0000000..5471afe --- /dev/null +++ b/h/src/xupak.h @@ -0,0 +1,12 @@ +typedef struct { + int magic[2]; + unsigned int upksize,pksize; + char escbits,esc0; + char lzx,rlenum; + char rlec[0]; +} XPAK_HDR; +#define XPAK_MAGIC1 (('G'<<8)+'T') +#define XPAK_MAGIC2 (('P'<<8)+'k') +#define xpak_ismagic(m) (m[0]==XPAK_MAGIC1 && m[1]==XPAK_MAGIC2) +#define xpak_setmagic(m) (void)(m[0]=XPAK_MAGIC1,m[1]=XPAK_MAGIC2) +#header diff --git a/pch/Makefile b/pch/Makefile new file mode 100644 index 0000000..fc6256b --- /dev/null +++ b/pch/Makefile @@ -0,0 +1,81 @@ +# - no, it's not a true makefile... +# - yes, it's a .bat quick-and-dirtily converted to a makefile +# :-b + +BIN=$(shell pwd)/../bin +MERGE=perl script/merge.pl +PCHMK=$(BIN)/pchmaker +DAT89=$(BIN)/dat89y -e HDR +O2EXT=$(BIN)/obj2ti -x + +PCHFILES = stdhead.pch keywords.pch estack.pch estackle.pch events.pch homescr.pch tiosdlg.pch wingraph.pch xupaki.pch #gen.pch extgraph.pch +TIPCHFILES = $(patsubst %.pch,%.89y,$(PCHFILES)) + +all: src/* srcdata/* subprojects/xupaki.pch + $(RM) lex.txt *.pchsource + cp src/lex.txt src/*.pchsource . + $(MAKE) $(TIPCHFILES) $(PCHFILES) + $(RM) lex.txt pchlog.txt *.pchsource + touch all +stdhead.pchsource: src/* + $(MERGE) src/stdhead-light.pchmerge +tiosdlg.pchsource: src/* + $(MERGE) src/tiosdlg-merge.pchmerge +keywords.pch: keywords.pchsource extfiles + $(PCHMK) $< +stdhead.pch: stdhead.pchsource extfiles + $(PCHMK) $< +estackle.pch: estackle.pchsource stdhead.pch extfiles + $(PCHMK) -istdhead.def $< +estack.pch: estack.pchsource stdhead.pch estackle.pch extfiles + $(PCHMK) -istdhead.def -iestackle.def $< +events.pch: events.pchsource stdhead.pch extfiles + $(PCHMK) -istdhead.def $< +homescr.pch: homescr.pchsource stdhead.pch extfiles + $(PCHMK) -istdhead.def $< +tiosdlg.pch: tiosdlg.pchsource stdhead.pch extfiles + $(PCHMK) -istdhead.def $< +wingraph.pch: wingraph.pchsource stdhead.pch extfiles + $(PCHMK) -istdhead.def $< +#gen.pch: srcdata/gen.pch +# cp $< $@ +#extgraph.pch: srcdata/extgraph.pch +# cp $< $@ +xupaki.pch: subprojects/xupaki.pch + cp $< $@ +%.89y: %.pch + $(DAT89) -f zheader $< + +clean: + $(RM) lex.txt pchlog.txt *.pchsource + $(RM) extfiles + $(RM) -r a2ext + +distclean: clean + +scratchclean: distclean + $(RM) *.pch *.89y *.def subprojects/*.pch all + +include ../config.mk +install: all + mkdir -p $(prefix)/share/gtc/include + install -m 644 *.pch $(prefix)/share/gtc/include + +try-import-tigcc-archive: + mv -f src/tigcc-archive/tigcc.a srcdata/tigcc.a&&rm -f src/tigcc-archive/*.o||true + +srcdata/tigcc.a: try-import-tigcc-archive + +extfiles: srcdata/* + $(RM) -r a2ext + mkdir a2ext + sh -c 'cd a2ext && ar x ../srcdata/tigcc.a' + cp srcdata/export.dat srcdata/*.ext srcdata/*.ref a2ext + $(MAKE) -C a2ext -f ../ext.mk O2EXT="$(O2EXT)" + touch extfiles + +subprojects/xupaki.pch: subprojects/xupaki/xupaki.pchsource subprojects/xupaki/unpack2.o + $(RM) -r subprojects/xupaki/a2ext + mkdir subprojects/xupaki/a2ext + sh -c 'cd subprojects/xupaki/a2ext && cp ../export.dat ../*.o . && for i in *.o; do $(O2EXT) "$$i"; done' + sh -c 'cd subprojects/xupaki && $(PCHMK) xupaki.pchsource && rm -f pchlog.txt xupaki.def && mv xupaki.pch ..' diff --git a/pch/all b/pch/all new file mode 100644 index 0000000..e69de29 diff --git a/pch/deflt.txt b/pch/deflt.txt new file mode 100644 index 0000000..47b5b94 --- /dev/null +++ b/pch/deflt.txt @@ -0,0 +1,345 @@ +#var .text +#var tigcc_compiled. +#var .data +#var qsort +#var .text +#var tigcc_compiled. +#var .data +#var fseek +#var .text +#var tigcc_compiled. +#var .data +#var fputc +#var .text +#var tigcc_compiled. +#var .data +#var fgetc +#var .text +#var tigcc_compiled. +#var .data +#var fwrite +#var .text +#var tigcc_compiled. +#var .data +#var fread +#var .text +#var tigcc_compiled. +#var .data +#var fgets +#var .text +#var tigcc_compiled. +#var .data +#var rename +#var .text +#var tigcc_compiled. +#var .data +#var unlink +#var .text +#var tigcc_compiled. +#var buff.0 +#var .data +#var tmpnam +#var .text +#var tigcc_compiled. +#var .data +#var fsetbufsize +#var .text +#var tigcc_compiled. +#var .data +#var bsearch +#var .text +#var tigcc_compiled. +#var .data +#var Sprite8 +#var .text +#var tigcc_compiled. +#var .data +#var Sprite16 +#var .text +#var tigcc_compiled. +#var .data +#var Sprite32 +#var .text +#var tigcc_compiled. +#var .data +#var __get_HS_pushEmptyFIFONode +#var .text +#var tigcc_compiled. +#var .data +#var HomeStorePair +#var .text +#var tigcc_compiled. +#var .data +#var LoadDLL +#var __DLL_body_ptr +#var __DLL_interface_ptr +#var UnloadDLL +#var .text +#var tigcc_compiled. +#var .data +#var __gray_version +#var .text +#var .data +#var bzero +#var .text +#var .data +#var bcopy +#var .text +#var .data +#var __mulsi3 +#var .text +#var tigcc_compiled. +#var .data +#var atoi +#var .text +#var .data +#var __divsi3 +#var .text +#var .data +#var __udivsi3 +#var .text +#var .data +#var __modsi3 +#var .text +#var .data +#var __umodsi3 +#var .text +#var .data +#var __div_entry +#var .text +#var .data +#var __muldi3 +#var .text +#var .data +#var __ashldi3 +#var .text +#var .data +#var __ashrdi3 +#var .text +#var .data +#var __lshrdi3 +#var .text +#var .data +#var __divdi3 +#var .text +#var tigcc_compiled. +#var .data +#var atol +#var .text +#var .data +#var __udivdi3 +#var .text +#var .data +#var __moddi3 +#var .text +#var .data +#var __umoddi3 +#var .text +#var .data +#var __addbf3 +#var .text +#var .data +#var __subbf3 +#var .text +#var .data +#var __mulbf3 +#var .text +#var .data +#var __negbf2 +#var .text +#var .data +#var __divbf3 +#var .text +#var .data +#var __floatsibf +#var .text +#var .data +#var __fixbfsi +#var __fixunsbfsi +#var .text +#var tigcc_compiled. +#var .data +#var strtol +#var .text +#var .data +#var __cmpbf2 +#var __nebf2 +#var __eqbf2 +#var __gebf2 +#var __ltbf2 +#var __gtbf2 +#var __lebf2 +#var .text +#var .data +#var __fp_entry +#var .text +#var .data +#var __fp_entry_1 +#var __fp_call +#var .text +#var .data +#var __BC +#var .text +#var .data +#var rand +#var __randseed +#var .text +#var __gray_check_hw_version +#var __gray_init_mem +#var __gray_init_handler +#var __gray_patches_for_hw1 +#var __gray_hw2type_detected +#var __gray_size_to_allocate +#var __gray_size_to_add +#var __gray_int1_handler_hw1 +#var __gray_skipcount +#var __gray_proceed_old +#var __gray_store +#var __gray_dummy1 +#var __gray_phase +#var __gray_init_return +#var __gray_used_mem +#var __gray_int1_handler_hw2 +#var __gray_startagain +#var __gray_copy_first_or_sec +#var __gray_to_oldint +#var __gray_copy_next_third +#var __gray_perform_copying +#var __gray_update_index +#var __gray_init_hw1_handler +#var __gray_cpy_d_plane +#var __gray_init_proceed +#var __gray_clr_l_plane +#var __gray_ok +#var __gray_off_out +#var __gray_hw1_cleanup +#var __gray_dark2lcd +#var __gray_continue_cleanup +#var .data +#var GrayOn +#var GrayOff +#var __D_plane +#var __L_plane +#var __gray_handle +#var __gray_hw_type +#var __switch_cnt +#var __gray_old_int1_hw1 +#var __gray_old_int1_hw2 +#var __gray_sync_n_count +#var __gray_plane_index +#var __gray_dbl_offset +#var __L_plane2 +#var __D_plane2 +#var .text +#var .data +#var realloc +#var .text +#var .data +#var calloc +#var .text +#var .data +#var clrscr +#var .text +#var .data +#var printf +#var .text +#var tigcc_compiled. +#var .data +#var strtoul +#var .text +#var .data +#var fprintf +#var .text +#var .data +#var fputchar +#var .text +#var .data +#var puts +#var .text +#var .data +#var strputchar +#var .text +#var .data +#var fputs +#var .text +#var .data +#var atof +#var .text +#var .data +#var push_shortint +#var .text +#var .data +#var push_longint +#var .text +#var .data +#var push_longlongint +#var .text +#var .data +#var NoCallBack +#var .text +#var tigcc_compiled. +#var .data +#var fopen +#var .text +#var .data +#var kbd_queue +#var .text +#var .data +#var OSVRegisterTimer +#var .text +#var .data +#var OSVFreeTimer +#var .text +#var .data +#var EV_getAppID +#var .text +#var .data +#var enter_ghost_space +#var .text +#var .data +#var __exit +#var .text +#var .data +#var atexit +#var .text +#var .data +#var __assertion_failed +#var .text +#var .data +#var _rowread +#var .text +#var .data +#var _extalnum_list +#var .text +#var tigcc_compiled. +#var .data +#var fclose +#var .text +#var .data +#var _extpunct_list +#var .text +#var .data +#var HomeStore +#var .text +#var .data +#var __dummy_handler__ +#var .text +#var .data +#var malloc_throw +#var HeapAllocPtrThrow +#var .text +#var .data +#var calloc_throw +#var .text +#var .data +#var realloc_throw +#var .text +#var .data +#var HeapReallocThrow +#var .text +#var LoadDLLThrow +#var .data +#var .text +#var tigcc_compiled. +#var .data +#var ftell diff --git a/pch/estack.89y b/pch/estack.89y new file mode 100644 index 0000000000000000000000000000000000000000..2003e702beb843294e42ae5e0785b3eece0cb0fd GIT binary patch literal 12268 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 P5hwkd3R~=hm!A4RwH@TW literal 0 HcmV?d00001 diff --git a/pch/estack.def b/pch/estack.def new file mode 100644 index 0000000..f7afa31 --- /dev/null +++ b/pch/estack.def @@ -0,0 +1,533 @@ + +ABS_TAG +ACOSH_TAG +ACOS_TAG +ADDELT_TAG +ADD_TAG +ANDPIC_ITAG +AND_TAG +ANGLE_TAG +ANS_TAG +APPEND_TAG +APPROX_TAG +ARB_INT_TAG +ARB_REAL_TAG +ARCHIVE_ITAG +ARCLEN_TAG +ASINH_TAG +ASIN_TAG +ATANH_TAG +ATAN_TAG +AUGMENT_TAG +AVGRC_TAG +BIN_TAG +BLDDATA_ITAG +CEILING_TAG +CFACTOR_TAG +CHAR_TAG +CIRCLE_ITAG +CLRDRAW_ITAG +CLRERR_ITAG +CLRGRAPH_ITAG +CLRHOME_ITAG +CLRIO_ITAG +CLRTABLE_ITAG +COLDIM_TAG +COLNORM_TAG +COMDENOM_TAG +COMMA_TAG +COMMENT_TAG +COMPLEX_ANGLE_TAG +COMPLEX_TAG +CONJ_TAG +COPYVAR_ITAG +CORR_TAG +COSH_TAG +COS_TAG +CROSSP_TAG +CSOLVE_TAG +CUBICREG_ITAG +CUMSUM_TAG +CUSTMOFF_ITAG +CUSTMON_ITAG +CUSTOM_ITAG +CYCLEPIC_ITAG +CYCLE_ITAG +CZEROS_TAG +DASH_TAG +DD_TAG +DEFINE_ITAG +DELFOLD_ITAG +DELTA_TBL_TAG +DELTA_TMPCNV_TAG +DELTA_X_TAG +DELTA_Y_TAG +DELVAR_ITAG +DESOLVE_TAG +DET_TAG +DET_TOL_TAG +DIAG_TAG +DIALOG_ITAG +DIFFERENTIATE_TAG +DIFTOL_TAG +DIM_TAG +DISPG_ITAG +DISPHOME_ITAG +DISPTBL_ITAG +DISP_ITAG +DIVELT_TAG +DIV_TAG +DMS_TAG +DOTP_TAG +DRAWFUNC_ITAG +DRAWINV_ITAG +DRAWPARM_ITAG +DRAWPOL_ITAG +DRAWSLP_ITAG +DROPDOWN_ITAG +DRWCTOUR_ITAG +DTIME_TAG +EIGVC_TAG +EIGVL_TAG +ELSEIF_ITAG +ELSE_ITAG +ELSE_TRY_ITAG +ENDCUSTM_ITAG +ENDDLOG_ITAG +ENDFOR_ITAG +ENDFUNC_ITAG +ENDIF_ITAG +ENDLOOP_ITAG +ENDPRGM_ITAG +ENDSTACK_TAG +ENDTBAR_ITAG +ENDTRY_ITAG +ENDWHILE_ITAG +ENTRY_TAG +EQ_TAG +ERRORNUM_TAG +ERROR_MSG_TAG +ESTEP_TAG +EXACT_TAG +EXEC_ITAG +EXIT_ITAG +EXP2LIST_TAG +EXPAND_TAG +EXPF_TAG +EXPR2DMS_TAG +EXPREG_ITAG +EXPR_TAG +EXP_TAG +EXT_INSTR_TAG +EXT_SYSTEM_TAG +EXT_TAG +EYE_PHI_TAG +EYE_PSI_TAG +EYE_THETA_TAG +FACTORIAL_TAG +FACTOR_TAG +FDASH_TAG +FILL_ITAG +FLDPIC_TAG +FLDRES_TAG +FLOOR_TAG +FMAX_TAG +FMIN_TAG +FNOFF_ITAG +FNON_ITAG +FORMAT_TAG +FOR_ITAG +FPART_TAG +FUNC_ITAG +GCD_TAG +GETCALC_ITAG +GETCONFG_TAG +GETDENOM_TAG +GETFOLD_TAG +GETKEY_TAG +GETMODE_TAG +GETNUM_TAG +GETTYPE_TAG +GETUNITS_TAG +GET_ITAG +GE_TAG +GOTO_ITAG +GRAPH_ITAG +GT_TAG +HEX_TAG +IDENTITY_TAG +IFTHEN_ITAG +IF_ITAG +IMAG_TAG +IM_TAG +INDIR_TAG +INFINITY_TAG +INPUTSTR_ITAG +INPUT_ITAG +INSTRING_TAG +INT2BIN_TAG +INT2DEC_TAG +INT2HEX_TAG +INTDIV_TAG +INTEGRATE_TAG +INT_TAG +IPART_TAG +ISPRIME_TAG +ISTORE_TAG +ITAN_TAG +ITEM_ITAG +LBL_ITAG +LCM_TAG +LEFT_TAG +LE_TAG +LIMIT_TAG +LINEHORZ_ITAG +LINETAN_ITAG +LINEVERT_ITAG +LINE_ITAG +LINREG_ITAG +LIST2MAT_TAG +LIST_END_TAG +LIST_START_TAG +LNREG_ITAG +LN_TAG +LOCALVAR_TAG +LOCAL_ITAG +LOCK_ITAG +LOGB_TAG +LOGISTIC_ITAG +LOG_TAG +LOOP_ITAG +LT_TAG +LU_ITAG +MAT2LIST_TAG +MAT_END_TAG +MAT_START_TAG +MAXX_TAG +MAXY_TAG +MAX_TAG +MEAN_TAG +MEDIAN_TAG +MEDMED_ITAG +MEDSTAT_TAG +MEDX1_TAG +MEDX2_TAG +MEDX3_TAG +MEDY1_TAG +MEDY2_TAG +MEDY3_TAG +MID_TAG +MINUS_TAG +MINX_TAG +MINY_TAG +MIN_TAG +MOD_TAG +MOVEVAR_ITAG +MROWADD_TAG +MROW_TAG +MULELT_TAG +MUL_TAG +NCONTOUR_TAG +NCR_TAG +NCURVES_TAG +NC_TAG +NDERIV_TAG +NEGFRAC_TAG +NEGINFINITY_TAG +NEWDATA_ITAG +NEWFOLD_ITAG +NEWLINE_TAG +NEWLIST_TAG +NEWMAT_TAG +NEWPIC_ITAG +NEWPLOT_ITAG +NEWPROB_ITAG +NEXTEXPR_TAG +NE_TAG +NINT_TAG +NMAX_TAG +NMIN_TAG +NORM_TAG +NOTHING_TAG +NOT_TAG +NPR_TAG +NSOLVE_TAG +NSTAT_TAG +OK_TAG +ONEVAR_ITAG +ORD_TAG +OR_TAG +OUTPUT_ITAG +P2PR_TAG +P2PTHETA_TAG +P2RX_TAG +P2RY_TAG +PARENTH_END_TAG +PARENTH_START_TAG +PART_TAG +PASSERR_ITAG +PAUSE_ITAG +PERCENT_TAG +PI_PRODUCT_TAG +PI_TAG +PLOTSOFF_ITAG +PLOTSON_ITAG +PLOTSTEP_TAG +PLOTSTRT_TAG +PN1_TAG +PN2_TAG +PN_INFINITY_TAG +POLCPLX_TAG +POLYEVAL_TAG +POPUP_ITAG +POSFRAC_TAG +POWELT_TAG +POWERREG_ITAG +POW_TAG +PRGM_ITAG +PRINTOBJ_ITAG +PRODUCT_TAG +PROMPT_ITAG +PROPFRAC_TAG +PTCHG_ITAG +PTOFF_ITAG +PTON_ITAG +PTTEST_TAG +PTTEXT_ITAG +PXLCHG_ITAG +PXLCRCL_ITAG +PXLHORZ_ITAG +PXLLINE_ITAG +PXLOFF_ITAG +PXLON_ITAG +PXLTEST_TAG +PXLTEXT_ITAG +PXLVERT_ITAG +Q1_TAG +Q3_TAG +QR_ITAG +QUADREG_ITAG +QUARTREG_ITAG +QUOTE_TAG +R2_TAG +RACOS_TAG +RADIANS_TAG +RANDMAT_TAG +RANDNORM_TAG +RANDPOLY_TAG +RANDSEED_ITAG +RAND_TAG +RASIN_TAG +RATAN_TAG +RCLGDB_ITAG +RCLPIC_ITAG +RC_TAG +REAL_TAG +REF_TAG +REF_TOL_TAG +REGCOEF_TAG +REGEQ_TAG +REMAIN_TAG +RENAME_ITAG +REQUEST_ITAG +RETURN_ITAG +RIGHT_TAG +ROTATE_TAG +ROUND_TAG +ROWADD_TAG +ROWDIM_TAG +ROWNORM_TAG +ROWSWAP_TAG +RPLCPIC_ITAG +RREF_TAG +RREF_TOL_TAG +SEED1_TAG +SEED2_TAG +SEMICOLON_TAG +SENDCALC_ITAG +SENDCHAT_ITAG +SEND_ITAG +SEQ_TAG +SETFOLD_TAG +SETGRAPH_TAG +SETMODE_TAG +SETTABLE_TAG +SETUNITS_TAG +SHADE_ITAG +SHIFT_TAG +SHOWSTAT_ITAG +SIGMA_SUM_TAG +SIGMA_X2_TAG +SIGMA_XY_TAG +SIGMA_X_TAG +SIGMA_Y2_TAG +SIGMA_Y_TAG +SIGN_TAG +SIMULT_TAG +SIMULT_TOL_TAG +SINCOS_TAG +SINGLE_QUOTE_TAG +SINH_TAG +SINREG_ITAG +SIN_TAG +SMLSIGMA_X_TAG +SMLSIGMA_Y_TAG +SOLVE_TAG +SORTA_ITAG +SORTD_ITAG +SQRT_TAG +START_TAG +STDDEV_TAG +STOGDB_ITAG +STOPIC_ITAG +STOP_ITAG +STORE_TAG +STRING_TAG +STYLE_ITAG +SUBELT_TAG +SUBMAT_TAG +SUBSCRIPT_TAG +SUB_TAG +SUM_TAG +SWITCH_TAG +SX_TAG +SYSDATA_TAG +SYSMATH_TAG +SY_TAG +T0_TAG +TABLE_ITAG +TANH_TAG +TAN_TAG +TAYLOR_TAG +TBLINPUT_TAG +TBLSTART_TAG +TCOLLECT_TAG +TC_TAG +TEXPAND_TAG +TEXT_ITAG +THEN_ITAG +THETA_C_TAG +THETA_MAX_TAG +THETA_MIN_TAG +THETA_STEP_TAG +TITLE_ITAG +TMAX_TAG +TMIN_TAG +TMPCNV_TAG +TOOLBAR_ITAG +TPLOT_TAG +TRACE_ITAG +TRANSPOSE_TAG +TRY_ITAG +TSTEP_TAG +TWOVAR_ITAG +UNARCHIV_ITAG +UNITCONV_TAG +UNITV_TAG +UNLOCK_ITAG +VARIANCE_TAG +VARIANCE_TWOARG_TAG +VAR_A_TAG +VAR_B_TAG +VAR_C_TAG +VAR_D_TAG +VAR_E_TAG +VAR_F_TAG +VAR_G_TAG +VAR_H_TAG +VAR_I_TAG +VAR_J_TAG +VAR_K_TAG +VAR_L_TAG +VAR_M_TAG +VAR_NAME_TAG +VAR_N_TAG +VAR_O_TAG +VAR_P_TAG +VAR_Q_TAG +VAR_R_TAG +VAR_S_TAG +VAR_T_TAG +VAR_U_TAG +VAR_V_TAG +VAR_W_TAG +VAR_X_TAG +VAR_Y_TAG +VAR_Z_TAG +VEC2CYLIND_TAG +VEC2POLAR_TAG +VEC2RECT_TAG +VEC2SPHERE_TAG +VEC_CYLIND_TAG +VEC_POLAR_TAG +VEC_SPHERE_TAG +V_AUGMENT_TAG +WHEN_TAG +WHILE_ITAG +WITH_TAG +XC_TAG +XFACT_TAG +XGRID_TAG +XMAX_TAG +XMIN_TAG +XORPIC_ITAG +XOR_TAG +XRES_TAG +XSCL_TAG +X_BAR_TAG +YC_TAG +YFACT_TAG +YGRID_TAG +YMAX_TAG +YMIN_TAG +YSCL_TAG +Y_BAR_TAG +ZC_TAG +ZEROS_TAG +ZEYE_PHI_TAG +ZEYE_PSI_TAG +ZEYE_THETA_TAG +ZFACT_TAG +ZMAX_TAG +ZMIN_TAG +ZNMAX_TAG +ZNMIN_TAG +ZOOMBOX_ITAG +ZOOMDATA_ITAG +ZOOMDEC_ITAG +ZOOMFIT_ITAG +ZOOMINT_ITAG +ZOOMIN_ITAG +ZOOMOUT_ITAG +ZOOMPREV_ITAG +ZOOMRCL_ITAG +ZOOMSQR_ITAG +ZOOMSTD_ITAG +ZOOMSTO_ITAG +ZOOMTRIG_ITAG +ZPLTSTEP_TAG +ZPLTSTRT_TAG +ZSCL_TAG +ZT0DE_TAG +ZTMAXDE_TAG +ZTMAX_TAG +ZTMIN_TAG +ZTPLOTDE_TAG +ZTSTEPDE_TAG +ZTSTEP_TAG +ZXGRID_TAG +ZXMAX_TAG +ZXMIN_TAG +ZXRES_TAG +ZXSCL_TAG +ZYGRID_TAG +ZYMAX_TAG +ZYMIN_TAG +ZYSCL_TAG +ZZMAX_TAG +ZZMIN_TAG +ZZSCL_TAG +Z_THETA_MAX_TAG +Z_THETA_MIN_TAG +Z_THETA_STEP_TAG +_VAR_Q_TAG diff --git a/pch/estack.pch b/pch/estack.pch new file mode 100644 index 0000000000000000000000000000000000000000..58fdc4e05409ef7331a766b5e5be1cc326a6f702 GIT binary patch literal 12172 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 literal 0 HcmV?d00001 diff --git a/pch/estackle.89y b/pch/estackle.89y new file mode 100644 index 0000000000000000000000000000000000000000..214255fc31dd3fb8168d263ab06518c38a7d820f GIT binary patch literal 5670 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 ZttMz>$oJ*K#DYF|k!5TJ_O?q%N0eBaDB^PX)O zwVBgr3`2n%4y!j<0RQ(>U=E>6CocoLD&R2Oo;MqGNx#TvuBMv3zHXWV~NzHF#eY4jNq~n);uZbt@%lT3z_*#H5 zD@@VtMH+Bo+wt2%F7{WZh}vIX!BMBG8$eM_`xK=#IfPhvp3+i}dr zHecEXQ-3D=Q$}hHRa4R8T}VpTby(Xev&NU&Z0)=MB(CVI_!?s7wvH(5K(x(Mn{!vW zA23i~Xex}t?G=5H1*L@hs0cOD#B!hy#HKUj(WWskd6l{=epMQQLvVYT9*VXq-EkO7 zg=R`cF@O)@-b%`#dMeZ(q0(!<+eoLRAvChk^*V0TV+{g=*kB8!!-KBPw_NBre!!6? zEwu1$g6naxeXqj_*iJnF8u*LUuD4n#pfq2r&C%M-Y!y|+UU}v`oqpTRS1-r_l=4=g zYyvhg(x9h-Nbw0ZaSn_V`;PbE&oOuJ!xM+|uVHj7ByM8L8jSroMy)RKAu;~@Zm_yI zs)`q}xi2|8JheXE2um-I!C9EvL$FTC+xUYx$%-{N1@o&5o`?}=crJU2QJTLzRy^Wsr#e0)QFX2nknTo%}9p8Y+La8tZuZ}+Y7sN`KVE_OC literal 0 HcmV?d00001 diff --git a/pch/homescr.def b/pch/homescr.def new file mode 100644 index 0000000..e36722b --- /dev/null +++ b/pch/homescr.def @@ -0,0 +1,20 @@ + +FIFO_ELEMENT +FIFO_NODE +HS_chopFIFO +HS_countFIFO +HS_deleteFIFONode +HS_freeAll +HS_freeFIFONode +HS_getAns +HS_getEntry +HS_getFIFONode +HS_newFIFONode +HS_popEStack +HS_pushEmptyFIFONode +HS_pushFIFONode +HomeExecute +HomePushEStack +HomeStore +HomeStorePair +__HS_pushEmptyFIFONode__type__ diff --git a/pch/homescr.pch b/pch/homescr.pch new file mode 100644 index 0000000000000000000000000000000000000000..d1bc129859537ec1076848c088240e15e546d163 GIT binary patch literal 1342 zcmZ`(O>fgc5FI-y(DKy+XIOEl;wY$1DF~5DA#EL{Qg8!_pc06sINR7FwIgQ(senU2 z0P_)=28xh4aOTbh#1SFHk)ObY8wZXYD6?y~v`~E6oqg}kyqR6OFqQ*=$gfBd4(5uq z!gzKfJ88IO25?OILb_X>r~c~D@No@kNGP)^SO zj(`GpZ^v4{yR#Th75TKsQ%gR%XqUMqHaTWjES~a7$*p02y;<{Q;O1SYf;+6s`CP$! zD9DJ4C2KbW57@D3xiw)I>nkHfZOt!Yt7G9fOt<04iAi@P(ptJN;PDWiL8n41=c(LQ zUXUHFc^uX7;3h(*S`E})LGEmb;a%WlMA_$1d9v%*pJM89$X;FamgoG0zq1LEd z`fQEQZKA2K$(~p|wt}vyDDgKXrfC|iY=^Ayxf)w}{$Jsuwv4YKRBoz>#`Xr&Jh|R? zk-HuP^=m|hURYSv+9^ zQsJ3WkqqDf+*^#rsTT9KC+PHsYnKx-xeywx&~WN@#bIRvLRe-qq|UvD$u~l%Tdv1Z zCReE9+XUO;V7gA76ELl552)wPQggamjRB>ZQt3P`O-vTiMHuBLM(NnrFjG7$4y{CVc9*dmaxQ%>0DjexKOU5u@Gzs-GGS;zD%r{Z23% z*s6*bu|6-^JA5=QtogZbhv77g>>`*a=d67oR#(AjpMXs}OrVUEj2yR`f+ qTiGX>JJwG`gjw?G$ki|T@6cRp8dv`5EO-gmL}e;|iQB#bf&K=qSd0q* literal 0 HcmV?d00001 diff --git a/pch/keywords.89y b/pch/keywords.89y new file mode 100644 index 0000000000000000000000000000000000000000..49e8cf5af17a83541b2665a57377c27809dca86c GIT binary patch literal 792 zcma)3J8M)y7(FxV+x7j5(Il(uBW{sS&_WwiL=cf+CFnAH@9gfdvoq`5xyA$=3&Fxh z8?lx&wia55U~lCg5bUjNYy{8Ty^_`ghi}gL9`ovS?%up|wbK#U7;2U4fd7TSDoaOt zea(lwXrh6c2C#WA^~=w9ZmgvEQGP%t^DY`!YG7U{9HrkLt1Nh637@b#Y3=eca1Bqe zt&-OCfm^r_kz}s>#;PWi4R%a*N&(wRCS8>U-eG5D zxXhM$J$@G*Wv$N?@KwxWf2x=SH5jXwRc-+Mz%T6Ga=9Y*knOS_EE;H1ce^UaV0vZL z-EJxZ_K}(5*~Ow*#vv+I@ZJ!Yae$#0v>GuI2gz)x(szhe98Su+A~F(3$ii%B--mc8 zn^>SWF6$Ww@l<@lN$TmFI;RsDtA|yvGTKfsg!>gc&mE!9;~I z#5eI1r)e0Mdc}9lGFYFUBHnk|>) zb)2aT6-~wk(ISf&$}CNgw{bS) z1SI4{`~VU;5it_=dKzs>rT41d;kNtU&D#L<7yTJmZHmRm)&XnE;3)m!%-EcO4SdCJ z(Jodq;5uGlTPK5`0C(^JN@V3GK63m&hAuRn4A4^NwDb#>$f2Kb0(gyg*s;)30=APZ z#;yu{#Lmu$Hndg0eit1RLb3+XBZ?S!y5c*hi?B>Kjf`FW#(zdZXUs_`)!4=rNn2N@KI*fPpmM6Bu^nYO=efx#iqYlrEaDv_Xn*}mS=M(Pp((>LtK!0 z+3a@f4SfUWI>QuinGgfADY><>LEpuB(NBD_QzpcaY-8i==ql*Bev8X=`ZESwldo{G c>-0(PNL(TxCtoq>4_NP1;JKmy^;hWNA6qbj`~Uy| literal 0 HcmV?d00001 diff --git a/pch/script/merge.pl b/pch/script/merge.pl new file mode 100644 index 0000000..4638689 --- /dev/null +++ b/pch/script/merge.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +$out=<>; +$out=~s/\r//g; +chomp $out; +-e $out and die "file already exists, cowardly exiting"; +open OUT,">",$out or die "failed to write file"; +$param=<>; +$param=~s/\r//g; +chomp $param; +die "extended merges aren't supported" if $param!=''; +while (<>) { + chomp; + s/\r//g; + open FILE,"<",$_ or die "failed to open file"; + print OUT while ; + close FILE; +} +close OUT; diff --git a/pch/src/COPYING b/pch/src/COPYING new file mode 100644 index 0000000..2ba72d5 --- /dev/null +++ b/pch/src/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/pch/src/alloc.pchsource b/pch/src/alloc.pchsource new file mode 100644 index 0000000..cc42f3d --- /dev/null +++ b/pch/src/alloc.pchsource @@ -0,0 +1,40 @@ +#var H_NULL D(0) +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var HANDLE typedef unsigned short HANDLE; +#var size_t typedef unsigned long size_t; +#var calloc void *calloc(short,short)__ATTR_LIB_ASM__; +#var calloc_throw void *calloc_throw(short,short)__ATTR_LIB_ASM__; +#var free D(_rom_call(void,(void*),A3)) +#var FreeHandles D(_rom_call(short,(void),23B)) +#var HeapAlloc D(_rom_call(HANDLE,(long),90)) +#var HeapAllocESTACK D(_rom_call(HANDLE,(long),91)) +#var HeapAllocHigh D(_rom_call(HANDLE,(long),92)) +#var HeapAllocHighThrow D(_rom_call(HANDLE,(long),94)) +#var HeapAllocPtr D(_rom_call(void*,(long),A2)) +#var HeapAllocPtrThrow void *HeapAllocPtrThrow(long)__ATTR_TIOS__; +#var HeapAllocThrow D(_rom_call(HANDLE,(long),93)) +#var HeapAvail D(_rom_call(unsigned long,(void),8F)) +#var HeapCompress D(_rom_call(void,(void),95)) +#var HeapDeref D(_rom_call(void*,(HANDLE),96)) +#var HeapEnd D(_rom_call(void*,(void),A1)) +#var HeapFree D(_rom_call(void,(HANDLE),97)) +#var HeapFreeIndir D(_rom_call(void,(void*),98)) +#var HeapFreePtr D(_rom_call(void,(void*),A3)) +#var HeapGetHandle D(_rom_call(HANDLE,(void),239)) +#var HeapGetLock D(_rom_call(short,(HANDLE),9B)) +#var HeapLock D(_rom_call(HANDLE,(HANDLE),9A)) +#var HeapMax D(_rom_call(unsigned long,(void),9C)) +#var HeapMoveHigh D(_rom_call(HANDLE,(HANDLE),A0)) +#var HeapPtrToHandle D(_rom_call(HANDLE,(void*),23A)) +#var HeapRealloc D(_rom_call(HANDLE,(HANDLE,long),9D)) +#var HeapReallocThrow HANDLE HeapReallocThrow(HANDLE,long)__ATTR_TIOS__; +#var HeapSize D(_rom_call(unsigned short,(HANDLE),9E)) +#var HeapUnlock D(_rom_call(HANDLE,(HANDLE),9F)) +#var HLock D(_rom_call(void*,(HANDLE),99)) +#var malloc D(_rom_call(void*,(long),A2)) +#var malloc_throw void *malloc_throw(long)__ATTR_TIOS__; +#var realloc void *realloc(void*,long)__ATTR_LIB_ASM__; +#var realloc_throw void *realloc_throw(void*,long)__ATTR_LIB_ASM__; diff --git a/pch/src/ams2-basfunc.pchsource b/pch/src/ams2-basfunc.pchsource new file mode 100644 index 0000000..51cf2bf --- /dev/null +++ b/pch/src/ams2-basfunc.pchsource @@ -0,0 +1,111 @@ +#var push_approx D(_rom_call(void,(CESI),4F7)) +#var push_augment D(_rom_call(void,(CESI,CESI),496)) +#var push_char D(_rom_call(void,(CESI),497)) +#var push_coldim D(_rom_call(void,(CESI),498)) +#var push_colnorm D(_rom_call(void,(CESI),499)) +#var push_cross_product D(_rom_call(void,(CESI,CESI),4CE)) +#var push_cumsum D(_rom_call(void,(CESI),49A)) +#var push_determinant D(_rom_call(void,(CESI,CESI),49D)) +#var push_diag D(_rom_call(void,(CESI),49E)) +#var push_dimension D(_rom_call(void,(CESI),49F)) +#var push_dotproduct D(_rom_call(void,(CESI,CESI),4A3)) +#var push_eigvc D(_rom_call(void,(CESI),4CF)) +#var push_eigvl D(_rom_call(void,(CESI),4D0)) +#var push_identity_mat D(_rom_call(void,(CESI),4A4)) +#var push_left D(_rom_call(void,(CESI,CESI),4A5)) +#var push_list_to_mat D(_rom_call(void,(CESI,CESI),4A6)) +#var push_mat_to_list D(_rom_call(void,(CESI),4A8)) +#var push_matnorm D(_rom_call(void,(CESI),4A7)) +#var push_mean D(_rom_call(void,(CESI),4A9)) +#var push_median D(_rom_call(void,(CESI),4AA)) +#var push_mid D(_rom_call(void,(CESI,CESI,CESI),4AB)) +#var push_mrow D(_rom_call(void,(CESI,CESI,CESI),4AC)) +#var push_mrowadd D(_rom_call(void,(CESI,CESI,CESI,CESI),4AD)) +#var push_newlist D(_rom_call(void,(CESI),4AE)) +#var push_newmat D(_rom_call(void,(CESI,CESI),4AF)) +#var push_ord D(_rom_call(void,(CESI),4B0)) +#var push_prodlist D(_rom_call(void,(CESI),4B2)) +#var push_randmat D(_rom_call(void,(CESI,CESI),4B4)) +#var push_randnorm D(_rom_call(void,(CESI,CESI),4B5)) +#var push_red_row_ech D(_rom_call(void,(CESI,CESI),4B6)) +#var push_right D(_rom_call(void,(CESI,CESI),4B7)) +#var push_rotate D(_rom_call(void,(CESI,CESI),4B8)) +#var push_round D(_rom_call(void,(CESI,CESI),4B9)) +#var push_row_echelon D(_rom_call(void,(CESI,CESI),4BE)) +#var push_rowadd D(_rom_call(void,(CESI,CESI,CESI),4BA)) +#var push_rowdim D(_rom_call(void,(CESI),4BB)) +#var push_rownorm D(_rom_call(void,(CESI),4BC)) +#var push_rowswap D(_rom_call(void,(CESI,CESI,CESI),4BD)) +#var push_sequence D(_rom_call(void,(CESI,CESI,CESI,CESI,CESI),4BF)) +#var push_shift D(_rom_call(void,(CESI,CESI),4C0)) +#var push_simult D(_rom_call(void,(CESI,CESI,CESI),4C1)) +#var push_stddev D(_rom_call(void,(CESI),4C3)) +#var push_submat D(_rom_call(void,(CESI,CESI,CESI,CESI,CESI),4C4)) +#var push_sumlist D(_rom_call(void,(CESI),4C5)) +#var push_unitv D(_rom_call(void,(CESI),4C8)) +#var push_variance D(_rom_call(void,(CESI),4C9)) +#var did_push_anti_deriv D(_rom_call(short,(CESI,CESI,short),5B1)) +#var did_push_series D(_rom_call(short,(CESI,CESI,CESI,CESI,short),588)) +#var push_1st_derivative D(_rom_call(void,(CESI,CESI),5AE)) +#var push_abs D(_rom_call(void,(CESI),543)) +#var push_acos D(_rom_call(void,(CESI),537)) +#var push_acosh D(_rom_call(void,(CESI),53E)) +#var push_asin D(_rom_call(void,(CESI),536)) +#var push_asinh D(_rom_call(void,(CESI),53D)) +#var push_atan D(_rom_call(void,(CESI),538)) +#var push_atanh D(_rom_call(void,(CESI),53F)) +#var push_ceiling D(_rom_call(void,(CESI),54B)) +#var push_comb D(_rom_call(void,(CESI,CESI),542)) +#var push_comdenom D(_rom_call(void,(CESI,CESI),59B)) +#var push_conj D(_rom_call(void,(CESI),547)) +#var push_cos D(_rom_call(void,(CESI),533)) +#var push_cosh D(_rom_call(void,(CESI),53B)) +#var push_csolve D(_rom_call(void,(CESI,CESI),585)) +#var push_czeros D(_rom_call(void,(CESI,CESI),587)) +#var push_def_int D(_rom_call(void,(CESI,CESI,CESI,CESI),5B2)) +#var push_denominator D(_rom_call(void,(CESI),55B)) +#var push_desolve D(_rom_call(void,(CESI),58B)) +#var push_exp D(_rom_call(void,(CESI),52E)) +#var push_expand D(_rom_call(void,(CESI,CESI,short),59A)) +#var push_extended_prod D(_rom_call(void,(CESI,CESI,CESI,CESI),5B5)) +#var push_factor D(_rom_call(void,(CESI,CESI,short),59C)) +#var push_floor D(_rom_call(void,(CESI),54A)) +#var push_fractional_part D(_rom_call(void,(CESI),54E)) +#var push_gcd_numbers D(_rom_call(void,(CESI,CESI),514)) +#var push_im D(_rom_call(void,(CESI),546)) +#var push_integer_gcd D(_rom_call(void,(CESI,CESI),551)) +#var push_integer_lcm D(_rom_call(void,(CESI,CESI),552)) +#var push_integer_part D(_rom_call(void,(CESI),54D)) +#var push_integer_quotient D(_rom_call(void,(CESI,CESI),54F)) +#var push_integer_remainder D(_rom_call(void,(CESI,CESI),550)) +#var push_is_prime D(_rom_call(void,(CESI),515)) +#var push_lim D(_rom_call(void,(CESI,CESI,CESI,CESI),5AD)) +#var push_ln D(_rom_call(void,(CESI),52F)) +#var push_log10 D(_rom_call(void,(CESI),530)) +#var push_max1 D(_rom_call(void,(CESI),554)) +#var push_max2 D(_rom_call(void,(CESI,CESI),599)) +#var push_max D(_rom_call(void,(CESI,CESI),58A)) +#var push_min1 D(_rom_call(void,(CESI),553)) +#var push_min2 D(_rom_call(void,(CESI,CESI),598)) +#var push_min D(_rom_call(void,(CESI,CESI),589)) +#var push_mod D(_rom_call(void,(CESI,CESI),54C)) +#var push_nint D(_rom_call(void,(CESI,CESI,CESI,CESI),5B3)) +#var push_nsolve D(_rom_call(void,(CESI,CESI),583)) +#var push_nth_derivative D(_rom_call(void,(CESI,CESI,CESI),5AF)) +#var push_numerator D(_rom_call(void,(CESI),55A)) +#var push_perm D(_rom_call(void,(CESI,CESI),541)) +#var push_phase D(_rom_call(void,(CESI),548)) +#var push_r_cis D(_rom_call(void,(CESI,CESI),549)) +#var push_re D(_rom_call(void,(CESI),545)) +#var push_rec_to_angle D(_rom_call(void,(CESI,CESI),539)) +#var push_sign D(_rom_call(void,(CESI),544)) +#var push_sin2 D(_rom_call(void,(CESI,CESI),531)) +#var push_sin D(_rom_call(void,(CESI),532)) +#var push_sinh D(_rom_call(void,(CESI),53A)) +#var push_solve D(_rom_call(void,(CESI,CESI),584)) +#var push_sqrt D(_rom_call(void,(CESI),52B)) +#var push_summation D(_rom_call(void,(CESI,CESI,CESI,CESI),5B4)) +#var push_tan D(_rom_call(void,(CESI),534)) +#var push_tanh D(_rom_call(void,(CESI),53C)) +#var push_when D(_rom_call(void,(CESI),57D)) +#var push_zeros D(_rom_call(void,(CESI,CESI),586)) diff --git a/pch/src/ams2-basop.pchsource b/pch/src/ams2-basop.pchsource new file mode 100644 index 0000000..0288548 --- /dev/null +++ b/pch/src/ams2-basop.pchsource @@ -0,0 +1,30 @@ +#var push_assignment D(_rom_call(void,(CESI),4DD)) +#var push_dot_add D(_rom_call(void,(CESI,CESI),4A0)) +#var push_dot_div D(_rom_call(void,(CESI,CESI),4CD)) +#var push_dot_mult D(_rom_call(void,(CESI,CESI),4A1)) +#var push_dot_sub D(_rom_call(void,(CESI,CESI),4A2)) +#var push_radians D(_rom_call(void,(CESI),4B3)) +#var push_substitute_no_simplify D(_rom_call(void,(CESI,CESI,CESI),489)) +#var push_and D(_rom_call(void,(CESI,CESI),5AB)) +#var push_arg_minus_1 D(_rom_call(void,(CESI),520)) +#var push_arg_plus_1 D(_rom_call(void,(CESI),51F)) +#var push_difference D(_rom_call(void,(CESI,CESI),51A)) +#var push_dot_exponentiate D(_rom_call(void,(CESI,CESI),596)) +#var push_equals D(_rom_call(void,(CESI,CESI),5A3)) +#var push_exponentiate D(_rom_call(void,(CESI,CESI),595)) +#var push_factorial D(_rom_call(void,(CESI),540)) +#var push_greater_than D(_rom_call(void,(CESI,CESI),5A5)) +#var push_greater_than_or_equals D(_rom_call(void,(CESI,CESI),5A7)) +#var push_less_than D(_rom_call(void,(CESI,CESI),5A6)) +#var push_less_than_or_equals D(_rom_call(void,(CESI,CESI),5A8)) +#var push_negate D(_rom_call(void,(CESI),524)) +#var push_not D(_rom_call(void,(CESI),5AA)) +#var push_not_equals D(_rom_call(void,(CESI,CESI),5A4)) +#var push_or D(_rom_call(void,(CESI,CESI),5AC)) +#var push_percent D(_rom_call(void,(CESI),555)) +#var push_product D(_rom_call(void,(CESI,CESI),521)) +#var push_ratio D(_rom_call(void,(CESI,CESI),526)) +#var push_square D(_rom_call(void,(CESI),52C)) +#var push_sum D(_rom_call(void,(CESI,CESI),594)) +#var push_substitute_simplify D(_rom_call(void,(CESI,CESI,CESI),5B9)) +#var push_substitute_using_such_that D(_rom_call(void,(CESI,CESI,CESI),5BE)) diff --git a/pch/src/ams2-kbd.pchsource b/pch/src/ams2-kbd.pchsource new file mode 100644 index 0000000..30fe5db --- /dev/null +++ b/pch/src/ams2-kbd.pchsource @@ -0,0 +1,6 @@ +#var alphaLockOff D(_rom_call(void,(unsigned char*),482)) +#var alphaLockOn D(_rom_call(void,(unsigned char*),481)) +#var GetAlphaStatus D(_rom_call(unsigned char,(void),164)) +#var KeyYesOrNo D(_rom_call(short,(short),3EB)) +#var restoreAlphaLock D(_rom_call(void,(unsigned char*),483)) +#var SetAlphaStatus D(_rom_call(void,(char),163)) diff --git a/pch/src/ams2-menus.pchsource b/pch/src/ams2-menus.pchsource new file mode 100644 index 0000000..373d01f --- /dev/null +++ b/pch/src/ams2-menus.pchsource @@ -0,0 +1,10 @@ +#var DynMenuAdd D(_rom_call(HANDLE,(HANDLE,short,const void*,short,short),3F1)) +#var DynMenuChange D(_rom_call(HANDLE,(HANDLE,short,const void*,short),3F0)) +#var MenuFlags D(_rom_call(short,(HANDLE),3F4)) +#var MenuItemDef D(_rom_call(void*,(HANDLE,short,__pushort),3F3)) +#var MenuLoad D(_rom_call(HANDLE,(const void*,short),3F2)) +#var MenuOff D(_rom_call(void,(HANDLE),419)) +#var PopupBegin D(_rom_call(HANDLE,(HANDLE,short),3F5)) +#var PopupBeginDo D(_rom_call(short,(HANDLE,short,short,short),3F6)) +#var QMenuTopSelect D(_rom_call(unsigned short,(HANDLE),41A)) +#var FKeyI_H D(_rom_call(short,(HANDLE,short),592)) diff --git a/pch/src/args-le.pchsource b/pch/src/args-le.pchsource new file mode 100644 index 0000000..a1cdd63 --- /dev/null +++ b/pch/src/args-le.pchsource @@ -0,0 +1,48 @@ + +#var NULL D(((void*)0)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var ESI typedef ESQ*ESI; +#var EStackIndex D(ESI) +#var Quantum D(ESQ) +#var SYM_STR typedef CESI SYM_STR; +#var POSINT_TAG D(31) +#var NEGINT_TAG D(32) +#var FLOAT_TAG D(35) +#var BCD_TAG D(35) +#var UNDEF_TAG D(42) +#var FALSE_TAG D(43) +#var TRUE_TAG D(44) +#var STR_TAG D(45) +#var LIST_TAG D(217) +#var USERFUNC_TAG D(218) +#var MATRIX_TAG D(219) +#var FUNC_TAG D(220) +#var DATA_TAG D(221) +#var GDB_TAG D(222) +#var PIC_TAG D(223) +#var TEXT_TAG D(224) +#var FIG_TAG D(225) +#var MAC_TAG D(226) +#var END_TAG D(229) +#var ASM_TAG D(243) +#var OTH_TAG D(248) + +#var ti_float typedef float ti_float; +#var top_estack D((*((ESI*)(_rom_call_addr(109))))) +#var ArgCount() D((RemainingArgCnt(top_estack))) +#var EX_getArg D(_rom_call(ESI,(short),BE)) +#var EX_getBCD D(_rom_call(short,(short,float*),BF)) +#var GetArgType(p) D((*(CESI)(p))) +#var GetFloatArg(p) D(({float __f;(ESI)(p)-=10;_rom_call(void*,(),26A)(&__f,(ESI)(p)+1,9L);((char*)&__f)[9]=0;__f;})) +#var GetIntArg(p) D(({register unsigned short __n=*(--(ESI)(p));register unsigned long __s=0;while(__n--)__s=(__s<<8)+*(--(unsigned char*)(p));(ESI)(p)--;__s;})) +#var GetLongLongArg(p) D(({register unsigned short __n=*(--(ESI)(p));register unsigned long long __s=0;while(__n--)__s=(__s<<8)+*(--(unsigned char*)(p));(ESI)(p)--;__s;})) +#var GetStrnArg(p) D(({(ESI)(p)-=2;while(*(ESI)(p)--);(const char*)((ESI)(p)+2);})) +#var GetSymstrArg(p) D(({register ESI __t=(ESI)(p);(ESI)(p)-=2;while(*(ESI)(p)--);(const char*)(__t-1);})) +#var InitArgPtr(p) D(((void)((p)=top_estack))) +#var SkipArg(p) D(((void)((p)=_rom_call(ESI,(ESI),10A)(p)))) +#var RemainingArgCnt D(_rom_call(unsigned short,(CESI),3C3)) diff --git a/pch/src/args.pchsource b/pch/src/args.pchsource new file mode 100644 index 0000000..d4f9861 --- /dev/null +++ b/pch/src/args.pchsource @@ -0,0 +1,263 @@ + +#var NULL D(((void*)0)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var ESI typedef ESQ*ESI; +#var EStackIndex D(ESI) +#var Quantum D(ESQ) +#var SYM_STR typedef CESI SYM_STR; +#var VAR_NAME_TAG D(0) +#var _VAR_Q_TAG D(1) +#var VAR_R_TAG D(2) +#var VAR_S_TAG D(3) +#var VAR_T_TAG D(4) +#var VAR_U_TAG D(5) +#var VAR_V_TAG D(6) +#var VAR_W_TAG D(7) +#var VAR_X_TAG D(8) +#var VAR_Y_TAG D(9) +#var VAR_Z_TAG D(10) +#var VAR_A_TAG D(11) +#var VAR_B_TAG D(12) +#var VAR_C_TAG D(13) +#var VAR_D_TAG D(14) +#var VAR_E_TAG D(15) +#var VAR_F_TAG D(16) +#var VAR_G_TAG D(17) +#var VAR_H_TAG D(18) +#var VAR_I_TAG D(19) +#var VAR_J_TAG D(20) +#var VAR_K_TAG D(21) +#var VAR_L_TAG D(22) +#var VAR_M_TAG D(23) +#var VAR_N_TAG D(24) +#var VAR_O_TAG D(25) +#var VAR_P_TAG D(26) +#var VAR_Q_TAG D(27) +#var EXT_SYSTEM_TAG D(28) +#var ARB_REAL_TAG D(29) +#var ARB_INT_TAG D(30) +#var POSINT_TAG D(31) +#var NEGINT_TAG D(32) +#var POSFRAC_TAG D(33) +#var NEGFRAC_TAG D(34) +#var FLOAT_TAG D(35) +#var BCD_TAG D(35) +#var PI_TAG D(36) +#var EXP_TAG D(37) +#var IM_TAG D(38) +#var NEGINFINITY_TAG D(39) +#var INFINITY_TAG D(40) +#var PN_INFINITY_TAG D(41) +#var UNDEF_TAG D(42) +#var FALSE_TAG D(43) +#var TRUE_TAG D(44) +#var STR_TAG D(45) +#var NOTHING_TAG D(46) +#var ACOSH_TAG D(47) +#var ASINH_TAG D(48) +#var ATANH_TAG D(49) +#var COSH_TAG D(53) +#var SINH_TAG D(54) +#var TANH_TAG D(55) +#var ACOS_TAG D(59) +#var ASIN_TAG D(60) +#var ATAN_TAG D(61) +#var RACOS_TAG D(65) +#var RASIN_TAG D(66) +#var RATAN_TAG D(67) +#var COS_TAG D(68) +#var SIN_TAG D(69) +#var TAN_TAG D(70) +#var ITAN_TAG D(74) +#var ABS_TAG D(75) +#var ANGLE_TAG D(76) +#var CEILING_TAG D(77) +#var FLOOR_TAG D(78) +#var INT_TAG D(79) +#var SIGN_TAG D(80) +#var SQRT_TAG D(81) +#var EXPF_TAG D(82) +#var LN_TAG D(83) +#var LOG_TAG D(84) +#var FPART_TAG D(85) +#var IPART_TAG D(86) +#var CONJ_TAG D(87) +#var IMAG_TAG D(88) +#var REAL_TAG D(89) +#var APPROX_TAG D(90) +#var TEXPAND_TAG D(91) +#var TCOLLECT_TAG D(92) +#var GETDENOM_TAG D(93) +#var GETNUM_TAG D(94) +#var CUMSUM_TAG D(96) +#var DET_TAG D(97) +#var COLNORM_TAG D(98) +#var ROWNORM_TAG D(99) +#var NORM_TAG D(100) +#var MEAN_TAG D(101) +#var MEDIAN_TAG D(102) +#var PRODUCT_TAG D(103) +#var STDDEV_TAG D(104) +#var SUM_TAG D(105) +#var VARIANCE_TAG D(106) +#var UNITV_TAG D(107) +#var DIM_TAG D(108) +#var MAT2LIST_TAG D(109) +#var NEWLIST_TAG D(110) +#var RREF_TAG D(111) +#var REF_TAG D(112) +#var IDENTITY_TAG D(113) +#var DIAG_TAG D(114) +#var COLDIM_TAG D(115) +#var ROWDIM_TAG D(116) +#var TRANSPOSE_TAG D(117) +#var FACTORIAL_TAG D(118) +#var PERCENT_TAG D(119) +#var RADIANS_TAG D(120) +#var NOT_TAG D(121) +#var MINUS_TAG D(122) +#var VEC_POLAR_TAG D(123) +#var VEC_CYLIND_TAG D(124) +#var VEC_SPHERE_TAG D(125) +#var START_TAG D(126) +#var ISTORE_TAG D(127) +#var STORE_TAG D(128) +#var WITH_TAG D(129) +#var XOR_TAG D(130) +#var OR_TAG D(131) +#var AND_TAG D(132) +#var LT_TAG D(133) +#var LE_TAG D(134) +#var EQ_TAG D(135) +#var GE_TAG D(136) +#var GT_TAG D(137) +#var NE_TAG D(138) +#var ADD_TAG D(139) +#var ADDELT_TAG D(140) +#var SUB_TAG D(141) +#var SUBELT_TAG D(142) +#var MUL_TAG D(143) +#var MULELT_TAG D(144) +#var DIV_TAG D(145) + +#var DIVELT_TAG D(146) +#var POW_TAG D(147) +#var POWELT_TAG D(148) +#var SINCOS_TAG D(149) +#var SOLVE_TAG D(150) +#var CSOLVE_TAG D(151) +#var NSOLVE_TAG D(152) +#var ZEROS_TAG D(153) +#var CZEROS_TAG D(154) +#var FMIN_TAG D(155) +#var FMAX_TAG D(156) +#var COMPLEX_TAG D(157) +#var POLYEVAL_TAG D(158) +#var RANDPOLY_TAG D(159) +#var CROSSP_TAG D(160) +#var DOTP_TAG D(161) +#var GCD_TAG D(162) +#var LCM_TAG D(163) +#var MOD_TAG D(164) +#var INTDIV_TAG D(165) +#var REMAIN_TAG D(166) +#var NCR_TAG D(167) +#var NPR_TAG D(168) +#var P2RX_TAG D(169) +#var P2RY_TAG D(170) +#var P2PTHETA_TAG D(171) +#var P2PR_TAG D(172) +#var AUGMENT_TAG D(173) +#var NEWMAT_TAG D(174) +#var RANDMAT_TAG D(175) +#var SIMULT_TAG D(176) +#var PART_TAG D(177) +#var EXP2LIST_TAG D(178) +#var RANDNORM_TAG D(179) +#var MROW_TAG D(180) +#var ROWADD_TAG D(181) +#var ROWSWAP_TAG D(182) +#var ARCLEN_TAG D(183) +#var NINT_TAG D(184) +#var PI_PRODUCT_TAG D(185) +#var SIGMA_SUM_TAG D(186) +#var MROWADD_TAG D(187) +#var ANS_TAG D(188) +#var ENTRY_TAG D(189) +#var EXACT_TAG D(190) +#var LOGB_TAG D(191) +#var COMDENOM_TAG D(192) +#var EXPAND_TAG D(193) +#var FACTOR_TAG D(194) +#var CFACTOR_TAG D(195) +#var INTEGRATE_TAG D(196) +#var DIFFERENTIATE_TAG D(197) +#var AVGRC_TAG D(198) +#var NDERIV_TAG D(199) +#var TAYLOR_TAG D(200) +#var LIMIT_TAG D(201) +#var PROPFRAC_TAG D(202) +#var WHEN_TAG D(203) +#var ROUND_TAG D(204) +#var DMS_TAG D(205) +#var LEFT_TAG D(206) +#var RIGHT_TAG D(207) +#var MID_TAG D(208) +#var SHIFT_TAG D(209) +#var SEQ_TAG D(210) +#var LIST2MAT_TAG D(211) +#var SUBMAT_TAG D(212) +#var SUBSCRIPT_TAG D(213) +#var RAND_TAG D(214) +#var MIN_TAG D(215) +#var MAX_TAG D(216) +#var LIST_TAG D(217) +#var USERFUNC_TAG D(218) +#var MATRIX_TAG D(219) +#var FUNC_TAG D(220) +#var DATA_TAG D(221) +#var GDB_TAG D(222) +#var PIC_TAG D(223) +#var TEXT_TAG D(224) +#var FIG_TAG D(225) +#var MAC_TAG D(226) +#var EXT_TAG D(227) +#var EXT_INSTR_TAG D(228) +#var END_TAG D(229) +#var COMMENT_TAG D(230) +#var NEXTEXPR_TAG D(231) +#var NEWLINE_TAG D(232) +#var ENDSTACK_TAG D(233) +#var PN1_TAG D(234) +#var PN2_TAG D(235) +#var ERROR_MSG_TAG D(236) +#var EIGVC_TAG D(237) +#var EIGVL_TAG D(238) +#var DASH_TAG D(239) +#var LOCALVAR_TAG D(240) +#var DESOLVE_TAG D(241) +#var FDASH_TAG D(242) +#var ASM_TAG D(243) +#var ISPRIME_TAG D(244) +#var OTH_TAG D(248) +#var ROTATE_TAG D(249) + +#var ti_float typedef float ti_float; +#var top_estack D((*((ESI*)(_rom_call_addr(109))))) +#var ArgCount() D((RemainingArgCnt(top_estack))) +#var EX_getArg D(_rom_call(ESI,(short),BE)) +#var EX_getBCD D(_rom_call(short,(short,float*),BF)) +#var GetArgType(p) D((*(CESI)(p))) +#var GetFloatArg(p) D(({float __f;(ESI)(p)-=10;_rom_call(void*,(),26A)(&__f,(ESI)(p)+1,9L);((char*)&__f)[9]=0;__f;})) +#var GetIntArg(p) D(({register unsigned short __n=*(--(ESI)(p));register unsigned long __s=0;while(__n--)__s=(__s<<8)+*(--(unsigned char*)(p));(ESI)(p)--;__s;})) +#var GetLongLongArg(p) D(({register unsigned short __n=*(--(ESI)(p));register unsigned long long __s=0;while(__n--)__s=(__s<<8)+*(--(unsigned char*)(p));(ESI)(p)--;__s;})) +#var GetStrnArg(p) D(({(ESI)(p)-=2;while(*(ESI)(p)--);(const char*)((ESI)(p)+2);})) +#var GetSymstrArg(p) D(({register ESI __t=(ESI)(p);(ESI)(p)-=2;while(*(ESI)(p)--);(const char*)(__t-1);})) +#var InitArgPtr(p) D(((void)((p)=top_estack))) +#var SkipArg(p) D(((void)((p)=_rom_call(ESI,(ESI),10A)(p)))) +#var RemainingArgCnt D(_rom_call(unsigned short,(CESI),3C3)) diff --git a/pch/src/asmtypes.pchsource b/pch/src/asmtypes.pchsource new file mode 100644 index 0000000..2baffd0 --- /dev/null +++ b/pch/src/asmtypes.pchsource @@ -0,0 +1,20 @@ + +#var BOOL typedef unsigned short BOOL; +#var BYTE typedef unsigned char BYTE; +#var DWORD typedef unsigned long DWORD; +#var SBYTE typedef signed char SBYTE; +#var SCHAR typedef signed char SCHAR; +#var SDWORD typedef signed long SDWORD; +#var SINT typedef signed int SINT; +#var SLONG typedef signed long SLONG; +#var SSHORT typedef signed short SSHORT; +#var SWORD typedef signed short SWORD; +#var UBYTE typedef unsigned char UBYTE; +#var UCHAR typedef unsigned char UCHAR; +#var UDWORD typedef unsigned long UDWORD; +#var UINT typedef unsigned int UINT; +#var ULONG typedef unsigned long ULONG; +#var USHORT typedef unsigned short USHORT; +#var UWORD typedef unsigned short UWORD; +#var WORD typedef unsigned short WORD; + diff --git a/pch/src/assert.pchsource b/pch/src/assert.pchsource new file mode 100644 index 0000000..055a945 --- /dev/null +++ b/pch/src/assert.pchsource @@ -0,0 +1 @@ +#var __assertion_failed void __assertion_failed(const char*,const char*,short)__ATTR_LIB_ASM_NORETURN__; diff --git a/pch/src/bascmd.pchsource b/pch/src/bascmd.pchsource new file mode 100644 index 0000000..0cd4179 --- /dev/null +++ b/pch/src/bascmd.pchsource @@ -0,0 +1,135 @@ + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var ESI typedef ESQ*ESI; +#var EStackIndex D(ESI) +#var Quantum D(ESQ) +#var SYM_STR typedef CESI SYM_STR; +#var cmd_andpic D(_rom_call(void,(SYM_STR,CESI,CESI),32A)) +#var cmd_blddata D(_rom_call(void,(ESI),32B)) +#var cmd_circle D(_rom_call(void,(CESI,CESI,CESI,CESI),32C)) +#var cmd_clrdraw D(_rom_call(void,(void),32D)) +#var cmd_clrerr D(_rom_call(void,(void),32E)) +#var cmd_clrgraph D(_rom_call(void,(void),32F)) +#var cmd_clrhome D(_rom_call(void,(void),330)) +#var cmd_clrio D(_rom_call(void,(void),331)) +#var cmd_clrtable D(_rom_call(void,(void),332)) +#var cmd_copyvar D(_rom_call(void,(SYM_STR,SYM_STR),333)) +#var cmd_cubicreg D(_rom_call(void,(ESI),334)) +#var cmd_custmoff D(_rom_call(void,(void),335)) +#var cmd_custmon D(_rom_call(void,(void),336)) +#var cmd_custom D(_rom_call(void,(void),337)) +#var cmd_cycle D(_rom_call(void,(void),338)) +#var cmd_cyclepic D(_rom_call(void,(CESI,CESI,CESI,CESI,CESI),339)) +#var cmd_delfold D(_rom_call(void,(CESI),33A)) +#var cmd_delvar D(_rom_call(void,(CESI),33B)) +#var cmd_dialog D(_rom_call(void,(void),33C)) +#var cmd_disp D(_rom_call(void,(CESI),33D)) +#var cmd_dispg D(_rom_call(void,(void),33E)) +#var cmd_disphome D(_rom_call(void,(void),33F)) +#var cmd_disptbl D(_rom_call(void,(void),340)) +#var cmd_drawfunc D(_rom_call(void,(CESI),341)) +#var cmd_drawinv D(_rom_call(void,(CESI),342)) +#var cmd_drawparm D(_rom_call(void,(CESI),343)) +#var cmd_drawpol D(_rom_call(void,(CESI),344)) +#var cmd_else D(_rom_call(void,(void),345)) +#var cmd_endfor D(_rom_call(void,(void),346)) +#var cmd_endloop D(_rom_call(void,(void),347)) +#var cmd_endtry D(_rom_call(void,(void),348)) +#var cmd_endwhile D(_rom_call(void,(void),349)) +#var cmd_exit D(_rom_call(void,(void),34A)) +#var cmd_expreg D(_rom_call(void,(ESI),34B)) +#var cmd_fill D(_rom_call(void,(CESI,SYM_STR),34C)) +#var cmd_fnoff D(_rom_call(void,(CESI),34D)) +#var cmd_fnon D(_rom_call(void,(CESI),34E)) +#var cmd_for D(_rom_call(void,(SYM_STR,CESI,CESI,CESI),34F)) +#var cmd_get D(_rom_call(void,(SYM_STR),350)) +#var cmd_getcalc D(_rom_call(void,(SYM_STR),351)) +#var cmd_goto D(_rom_call(void,(SYM_STR),352)) +#var cmd_graph D(_rom_call(void,(CESI),353)) +#var cmd_if D(_rom_call(void,(CESI),354)) +#var cmd_ifthen D(_rom_call(void,(CESI),355)) +#var cmd_input D(_rom_call(void,(CESI),356)) +#var cmd_inputstr D(_rom_call(void,(ESI),357)) +#var cmd_line D(_rom_call(void,(CESI,CESI,CESI,CESI,CESI),358)) +#var cmd_linehorz D(_rom_call(void,(CESI,CESI),359)) +#var cmd_linetan D(_rom_call(void,(CESI,CESI),35A)) +#var cmd_linevert D(_rom_call(void,(CESI,CESI),35B)) +#var cmd_linreg D(_rom_call(void,(ESI),35C)) +#var cmd_lnreg D(_rom_call(void,(ESI),35D)) +#var cmd_local D(_rom_call(void,(CESI),35E)) +#var cmd_lock D(_rom_call(void,(CESI),35F)) +#var cmd_logistic D(_rom_call(void,(ESI),360)) +#var cmd_medmed D(_rom_call(void,(ESI),361)) +#var cmd_movevar D(_rom_call(void,(SYM_STR,SYM_STR,SYM_STR),362)) +#var cmd_newdata D(_rom_call(void,(CESI),363)) +#var cmd_newfold D(_rom_call(void,(SYM_STR),364)) +#var cmd_newpic D(_rom_call(void,(ESI,SYM_STR,ESI,ESI),365)) +#var cmd_newplot D(_rom_call(void,(ESI),366)) +#var cmd_newprob D(_rom_call(void,(void),367)) +#var cmd_onevar D(_rom_call(void,(ESI),368)) +#var cmd_output D(_rom_call(void,(CESI,CESI,CESI),369)) +#var cmd_passerr D(_rom_call(void,(void),36A)) +#var cmd_pause D(_rom_call(void,(CESI),36B)) +#var cmd_plotsoff D(_rom_call(void,(CESI),36C)) +#var cmd_plotson D(_rom_call(void,(CESI),36D)) +#var cmd_popup D(_rom_call(void,(ESI,ESI),36E)) +#var cmd_powerreg D(_rom_call(void,(ESI),36F)) +#var cmd_printobj D(_rom_call(void,(SYM_STR),370)) +#var cmd_prompt D(_rom_call(void,(CESI),371)) +#var cmd_ptchg D(_rom_call(void,(CESI,CESI),372)) +#var cmd_ptoff D(_rom_call(void,(CESI,CESI),373)) +#var cmd_pton D(_rom_call(void,(CESI,CESI),374)) +#var cmd_pttext D(_rom_call(void,(CESI,CESI,CESI),375)) +#var cmd_pxlchg D(_rom_call(void,(CESI,CESI),376)) +#var cmd_pxlcircle D(_rom_call(void,(CESI,CESI,CESI,CESI),377)) +#var cmd_pxlhorz D(_rom_call(void,(CESI,CESI),378)) +#var cmd_pxlline D(_rom_call(void,(CESI,CESI,CESI,CESI,CESI),379)) +#var cmd_pxloff D(_rom_call(void,(CESI,CESI),37A)) +#var cmd_pxlon D(_rom_call(void,(CESI,CESI),37B)) +#var cmd_pxltext D(_rom_call(void,(CESI,CESI,CESI),37C)) +#var cmd_pxlvert D(_rom_call(void,(CESI,CESI),37D)) +#var cmd_quadreg D(_rom_call(void,(ESI),37E)) +#var cmd_quartreg D(_rom_call(void,(ESI),37F)) +#var cmd_randseed D(_rom_call(void,(CESI),380)) +#var cmd_rclgdb D(_rom_call(void,(SYM_STR),381)) +#var cmd_rclpic D(_rom_call(void,(SYM_STR,CESI,CESI),382)) +#var cmd_rename D(_rom_call(void,(SYM_STR,SYM_STR),383)) +#var cmd_request D(_rom_call(void,(CESI,SYM_STR),384)) +#var cmd_return D(_rom_call(void,(CESI),385)) +#var cmd_rplcpic D(_rom_call(void,(SYM_STR,CESI,CESI),386)) +#var cmd_send D(_rom_call(void,(CESI),387)) +#var cmd_sendcalc D(_rom_call(void,(SYM_STR),388)) +#var cmd_sendchat D(_rom_call(void,(SYM_STR),389)) +#var cmd_shade D(_rom_call(void,(ESI),38A)) +#var cmd_showstat D(_rom_call(void,(void),38B)) +#var cmd_sinreg D(_rom_call(void,(ESI),38C)) +#var cmd_slpline D(_rom_call(void,(CESI,CESI,CESI),38D)) +#var cmd_sorta D(_rom_call(void,(ESI),38E)) +#var cmd_sortd D(_rom_call(void,(ESI),38F)) +#var cmd_stogdb D(_rom_call(void,(SYM_STR),390)) +#var cmd_stopic D(_rom_call(void,(ESI),391)) +#var cmd_style D(_rom_call(void,(CESI,CESI),392)) +#var cmd_table D(_rom_call(void,(ESI),393)) +#var cmd_text D(_rom_call(void,(CESI),394)) +#var cmd_toolbar D(_rom_call(void,(void),395)) +#var cmd_trace D(_rom_call(void,(void),396)) +#var cmd_try D(_rom_call(void,(void),397)) +#var cmd_twovar D(_rom_call(void,(ESI),398)) +#var cmd_unlock D(_rom_call(void,(CESI),399)) +#var cmd_while D(_rom_call(void,(CESI),39A)) +#var cmd_xorpic D(_rom_call(void,(SYM_STR,CESI,CESI),39B)) +#var cmd_zoombox D(_rom_call(void,(void),39C)) +#var cmd_zoomdata D(_rom_call(void,(void),39D)) +#var cmd_zoomdec D(_rom_call(void,(void),39E)) +#var cmd_zoomfit D(_rom_call(void,(void),39F)) +#var cmd_zoomin D(_rom_call(void,(void),3A0)) +#var cmd_zoomint D(_rom_call(void,(void),3A1)) +#var cmd_zoomout D(_rom_call(void,(void),3A2)) +#var cmd_zoomprev D(_rom_call(void,(void),3A3)) +#var cmd_zoomrcl D(_rom_call(void,(void),3A4)) +#var cmd_zoomsqr D(_rom_call(void,(void),3A5)) +#var cmd_zoomstd D(_rom_call(void,(void),3A6)) +#var cmd_zoomsto D(_rom_call(void,(void),3A7)) +#var cmd_zoomtrig D(_rom_call(void,(void),3A8)) + diff --git a/pch/src/basfunc.pchsource b/pch/src/basfunc.pchsource new file mode 100644 index 0000000..c3c2dea --- /dev/null +++ b/pch/src/basfunc.pchsource @@ -0,0 +1,28 @@ + +#var NULL_INDEX D(((CESI)0)) +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var ESI typedef ESQ*ESI; +#var EStackIndex D(ESI) +#var Quantum D(ESQ) +#var SYM_STR typedef CESI SYM_STR; +#var push_getfold D(_rom_call(void,(void),317)) +#var push_getkey D(_rom_call(void,(void),316)) +#var push_getmode D(_rom_call(void,(CESI),318)) +#var push_gettype D(_rom_call(void,(CESI),319)) +#var push_instring D(_rom_call(void,(CESI,CESI,CESI),31A)) +#var push_part D(_rom_call(void,(),31C)) +#var push_pttest D(_rom_call(void,(CESI,CESI),31D)) +#var push_pxltest D(_rom_call(void,(CESI,CESI),31E)) +#var push_rand D(_rom_call(void,(CESI),31F)) +#var push_randpoly D(_rom_call(void,(CESI,CESI),320)) +#var push_setfold D(_rom_call(void,(CESI),321)) +#var push_setgraph D(_rom_call(void,(CESI,CESI),322)) +#var push_setmode D(_rom_call(void,(CESI,CESI),323)) +#var push_settable D(_rom_call(void,(CESI,CESI),324)) +#var push_str_to_expr D(_rom_call(void,(CESI),325)) +#var push_string D(_rom_call(void,(CESI),326)) +#var push_switch D(_rom_call(void,(CESI),327)) + +#var push_subst_no_simp D(push_substitute_no_simplify) +#var push_nSolve D(push_nsolve) diff --git a/pch/src/basop.pchsource b/pch/src/basop.pchsource new file mode 100644 index 0000000..caf673a --- /dev/null +++ b/pch/src/basop.pchsource @@ -0,0 +1,17 @@ + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var ESI typedef ESQ*ESI; +#var EStackIndex D(ESI) +#var Quantum D(ESQ) +#var SYM_STR typedef CESI SYM_STR; +#var did_push_to_polar D(_rom_call(short,(),313)) +#var push_degrees D(_rom_call(void,(CESI,CESI,CESI),314)) +#var push_indir_name D(_rom_call(void,(CESI),2B2)) +#var push_list_plus D(_rom_call(void,(CESI,CESI),3BD)) +#var push_list_times D(_rom_call(void,(CESI,CESI),3BE)) +#var push_matrix_product D(_rom_call(void,(CESI,CESI),3C5)) +#var push_pow D(_rom_call(void,(CESI,CESI),30F)) +#var push_to_cylin D(_rom_call(void,(),328)) +#var push_to_sphere D(_rom_call(void,(),329)) + diff --git a/pch/src/cert.pchsource b/pch/src/cert.pchsource new file mode 100644 index 0000000..8ce43d0 --- /dev/null +++ b/pch/src/cert.pchsource @@ -0,0 +1,27 @@ + +#var H_NULL D(0) +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var CERT_FIELD typedef struct{unsigned short Field;unsigned short HdrLen;unsigned long Len;void*Data;}CERT_FIELD; +#var CFILE typedef struct{void*Start,*Pos,*End;short EOFVal;}CFILE; +#var HANDLE typedef unsigned short HANDLE; +#var size_t typedef unsigned long size_t; +#var ceof D(_rom_call(short,(CFILE*),128)) +#var cfindfield D(_rom_call(short,(CFILE*,short,CERT_FIELD*),12A)) +#var cgetc D(_rom_call(unsigned char,(CFILE*),12B)) +#var cgetcertrevno D(_rom_call(short,(__plong),2A0)) +#var cgetflen D(_rom_call(unsigned long,(CFILE*,short),12D)) +#var cgetfnl D(_rom_call(long,(CERT_FIELD*),12E)) +#var cgetnl D(_rom_call(long,(CFILE*),12F)) +#var cgetns D(_rom_call(short,(CFILE*),130)) +#var cgetsn D(_rom_call(void,(char*),2A1)) +#var copen D(_rom_call(void,(CFILE*,char*,long),132)) +#var copensub D(_rom_call(void,(CFILE*,CERT_FIELD*),133)) +#var cputhdr D(_rom_call(short,(CFILE*,short,short),134)) +#var cputnl D(_rom_call(void,(CFILE*,long),135)) +#var cputns D(_rom_call(void,(CFILE*,short),136)) +#var cread D(_rom_call(short,(CFILE*,CERT_FIELD*),137)) +#var ctell D(_rom_call(unsigned long,(CFILE*),138)) +#var cwrite D(_rom_call(short,(CFILE*,CERT_FIELD*),139)) diff --git a/pch/src/compat-x.pchsource b/pch/src/compat-x.pchsource new file mode 100644 index 0000000..2ae033e --- /dev/null +++ b/pch/src/compat-x.pchsource @@ -0,0 +1,89 @@ +#var _RR(a,b,c,d) D((CALCULATOR?a:b),(CALCULATOR?c:d)) +#var _RS(a,b) D((CALCULATOR?a:b)) +#var RR_0 D(_RR(9,4,5,0)) +#var RR_1 D(_RR(1,4,5,1)) +#var RR_2 D(_RR(1,3,6,1)) +#var RR_3 D(_RR(1,2,7,1)) +#var RR_4 D(_RR(2,4,5,2)) +#var RR_5 D(_RR(2,3,6,2)) +#var RR_6 D(2,_RS(7,2)) +#var RR_7 D(_RR(3,4,5,3)) +#var RR_8 D(3,_RS(6,3)) +#var RR_9 D(_RR(3,2,7,3)) +#var RR_2ND D(0,_RS(0,4)) +#var RR_A D(_RR(9,15,2,15)) +#var RR_ALPHA D(_RR(15,0,15,7)) +#var RR_APPS D(_RR(7,5,6,0)) +#var RR_B D(_RR(5,15,1,15)) +#var RR_BCKSPC D(_RR(8,2,0,6)) +#var RR_C D(_RR(3,15,1,15)) +#var RR_CATALOG D(_RR(15,3,15,6)) +#var RR_CLEAR D(_RR(7,1,5,6)) +#var RR_COMMA D(_RR(4,2,7,4)) +#var RR_COS D(_RR(5,15,6,15)) +#var RR_D D(_RR(2,15,2,15)) +#var RR_DIAMOND D(0,_RS(1,6)) +#var RR_DIVIDE D(_RR(5,1,0,4)) +#var RR_DOT D(_RR(9,3,6,0)) +#var RR_DOWN D(0,_RS(7,2)) +#var RR_E D(_RR(2,15,3,15)) +#var RR_EE D(_RR(15,5,15,2)) +#var RR_ENTER1 D(_RR(9,1,1,0)) +#var RR_ENTER2 D(_RR(6,1,6,0)) +#var RR_ENTER D(RR_ENTER1) +#var RR_EQUALS D(15,15) +#var RR_ESC D(_RR(8,6,6,0)) +#var RR_F1 D(_RR(6,5,4,7)) +#var RR_F2 D(4,_RS(4,7)) +#var RR_F3 D(_RR(2,3,4,7)) +#var RR_F4 D(_RR(9,2,4,7)) +#var RR_F5 D(_RR(7,1,4,7)) +#var RR_F6 D(_RR(5,15,4,15)) +#var RR_F7 D(_RR(3,15,4,15)) +#var RR_F8 D(_RR(1,15,4,15)) +#var RR_F D(_RR(3,15,2,15)) +#var RR_G D(_RR(4,15,2,15)) +#var RR_H D(_RR(5,15,2,15)) +#var RR_HAND D(_RR(0,15,3,15)) +#var RR_HOME D(_RR(15,5,15,6)) +#var RR_I D(_RR(7,15,3,15)) +#var RR_J D(_RR(6,15,2,15)) +#var RR_K D(_RR(7,15,2,15)) +#var RR_L D(_RR(8,15,2,15)) +#var RR_LEFT D(0,_RS(4,1)) +#var RR_LN D(_RR(6,15,5,15)) +#var RR_M D(_RR(7,15,1,15)) +#var RR_MINUS D(_RR(9,1,0,2)) +#var RR_MODE D(_RR(8,4,5,6)) +#var RR_MULTIPLY D(_RR(7,1,7,3)) +#var RR_N D(_RR(6,15,1,15)) +#var RR_NEGATE D(_RR(9,2,7,0)) +#var RR_NO_KEY D(15) +#var RR_O D(_RR(8,15,3,15)) +#var RR_P D(_RR(6,15,7,15)) +#var RR_PAREN_CLOSE D(_RR(4,3,6,4)) +#var RR_PAREN_OPEN D(4,_RS(5,4)) +#var RR_PLUS D(_RR(8,1,4,1)) +#var RR_POWER D(_RR(6,1,0,5)) +#var RR_Q D(_RR(9,15,3,15)) +#var RR_R D(_RR(3,15,3,15)) +#var RR_RIGHT D(0,_RS(6,3)) +#var RR_S D(_RR(1,15,2,15)) +#var RR_SHIFT D(0,_RS(2,5)) +#var RR_SIN D(_RR(5,15,5,15)) +#var RR_SPACE D(_RR(4,15,0,15)) +#var RR_STORE D(_RR(3,5,0,1)) +#var RR_T D(_RR(4,2,3,5)) +#var RR_TAN D(_RR(5,15,7,15)) +#var RR_THETA D(_RR(8,15,1,15)) +#var RR_U D(_RR(6,15,3,15)) +#var RR_UP D(0,_RS(5,0)) +#var RR_V D(_RR(4,15,1,15)) +#var RR_W D(_RR(1,15,3,15)) +#var RR_WITH D(_RR(15,5,15,3)) +#var RR_X D(_RR(2,5,1,5)) +#var RR_Y D(_RR(5,4,3,5)) +#var RR_Z D(_RR(1,3,1,5)) +#var TI89 D((CALCULATOR==0)) +#var TI92PLUS D((CALCULATOR==1)) +#var V200 D((CALCULATOR==3)) diff --git a/pch/src/compat.pchsource b/pch/src/compat.pchsource new file mode 100644 index 0000000..85d5387 --- /dev/null +++ b/pch/src/compat.pchsource @@ -0,0 +1,87 @@ +#var RR_0 D((CALCULATOR?9:4),(CALCULATOR?5:0)) +#var RR_1 D((CALCULATOR?1:4),(CALCULATOR?5:1)) +#var RR_2 D((CALCULATOR?1:3),(CALCULATOR?6:1)) +#var RR_3 D((CALCULATOR?1:2),(CALCULATOR?7:1)) +#var RR_4 D((CALCULATOR?2:4),(CALCULATOR?5:2)) +#var RR_5 D((CALCULATOR?2:3),(CALCULATOR?6:2)) +#var RR_6 D(2,(CALCULATOR?7:2)) +#var RR_7 D((CALCULATOR?3:4),(CALCULATOR?5:3)) +#var RR_8 D(3,(CALCULATOR?6:3)) +#var RR_9 D((CALCULATOR?3:2),(CALCULATOR?7:3)) +#var RR_2ND D(0,(CALCULATOR?0:4)) +#var RR_A D((CALCULATOR?9:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_ALPHA D((CALCULATOR?RR_NO_KEY:0),(CALCULATOR?RR_NO_KEY:7)) +#var RR_APPS D((CALCULATOR?7:5),(CALCULATOR?6:0)) +#var RR_B D((CALCULATOR?5:RR_NO_KEY),(CALCULATOR?1:RR_NO_KEY)) +#var RR_BCKSPC D((CALCULATOR?8:2),(CALCULATOR?0:6)) +#var RR_C D((CALCULATOR?3:RR_NO_KEY),(CALCULATOR?1:RR_NO_KEY)) +#var RR_CATALOG D((CALCULATOR?RR_NO_KEY:3),(CALCULATOR?RR_NO_KEY:6)) +#var RR_CLEAR D((CALCULATOR?7:1),(CALCULATOR?5:6)) +#var RR_COMMA D((CALCULATOR?4:2),(CALCULATOR?7:4)) +#var RR_COS D((CALCULATOR?5:RR_NO_KEY),(CALCULATOR?6:RR_NO_KEY)) +#var RR_D D((CALCULATOR?2:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_DIAMOND D(0,(CALCULATOR?1:6)) +#var RR_DIVIDE D((CALCULATOR?5:1),(CALCULATOR?0:4)) +#var RR_DOT D((CALCULATOR?9:3),(CALCULATOR?6:0)) +#var RR_DOWN D(0,(CALCULATOR?7:2)) +#var RR_E D((CALCULATOR?2:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_EE D((CALCULATOR?RR_NO_KEY:5),(CALCULATOR?RR_NO_KEY:2)) +#var RR_ENTER1 D((CALCULATOR?9:1),(CALCULATOR?1:0)) +#var RR_ENTER2 D((CALCULATOR?6:1),(CALCULATOR?6:0)) +#var RR_ENTER D(RR_ENTER1) +#var RR_EQUALS D(RR_NO_KEY,RR_NO_KEY) +#var RR_ESC D((CALCULATOR?8:6),(CALCULATOR?6:0)) +#var RR_F1 D((CALCULATOR?6:5),(CALCULATOR?4:7)) +#var RR_F2 D(4,(CALCULATOR?4:7)) +#var RR_F3 D((CALCULATOR?2:3),(CALCULATOR?4:7)) +#var RR_F4 D((CALCULATOR?9:2),(CALCULATOR?4:7)) +#var RR_F5 D((CALCULATOR?7:1),(CALCULATOR?4:7)) +#var RR_F6 D((CALCULATOR?5:RR_NO_KEY),(CALCULATOR?4:RR_NO_KEY)) +#var RR_F7 D((CALCULATOR?3:RR_NO_KEY),(CALCULATOR?4:RR_NO_KEY)) +#var RR_F8 D((CALCULATOR?1:RR_NO_KEY),(CALCULATOR?4:RR_NO_KEY)) +#var RR_F D((CALCULATOR?3:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_G D((CALCULATOR?4:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_H D((CALCULATOR?5:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_HAND D((CALCULATOR?0:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_HOME D((CALCULATOR?RR_NO_KEY:5),(CALCULATOR?RR_NO_KEY:6)) +#var RR_I D((CALCULATOR?7:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_J D((CALCULATOR?6:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_K D((CALCULATOR?7:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_L D((CALCULATOR?8:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_LEFT D(0,(CALCULATOR?4:1)) +#var RR_LN D((CALCULATOR?6:RR_NO_KEY),(CALCULATOR?5:RR_NO_KEY)) +#var RR_M D((CALCULATOR?7:RR_NO_KEY),(CALCULATOR?1:RR_NO_KEY)) +#var RR_MINUS D((CALCULATOR?9:1),(CALCULATOR?0:2)) +#var RR_MODE D((CALCULATOR?8:4),(CALCULATOR?5:6)) +#var RR_MULTIPLY D((CALCULATOR?7:1),(CALCULATOR?7:3)) +#var RR_N D((CALCULATOR?6:RR_NO_KEY),(CALCULATOR?1:RR_NO_KEY)) +#var RR_NEGATE D((CALCULATOR?9:2),(CALCULATOR?7:0)) +#var RR_NO_KEY D(0xF) +#var RR_O D((CALCULATOR?8:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_P D((CALCULATOR?6:RR_NO_KEY),(CALCULATOR?7:RR_NO_KEY)) +#var RR_PAREN_CLOSE D((CALCULATOR?4:3),(CALCULATOR?6:4)) +#var RR_PAREN_OPEN D(4,(CALCULATOR?5:4)) +#var RR_PLUS D((CALCULATOR?8:1),(CALCULATOR?4:1)) +#var RR_POWER D((CALCULATOR?6:1),(CALCULATOR?0:5)) +#var RR_Q D((CALCULATOR?9:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_R D((CALCULATOR?3:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_RIGHT D(0,(CALCULATOR?6:3)) +#var RR_S D((CALCULATOR?1:RR_NO_KEY),(CALCULATOR?2:RR_NO_KEY)) +#var RR_SHIFT D(0,(CALCULATOR?2:5)) +#var RR_SIN D((CALCULATOR?5:RR_NO_KEY),(CALCULATOR?5:RR_NO_KEY)) +#var RR_SPACE D((CALCULATOR?4:RR_NO_KEY),(CALCULATOR?0:RR_NO_KEY)) +#var RR_STORE D((CALCULATOR?3:5),(CALCULATOR?0:1)) +#var RR_T D((CALCULATOR?4:2),(CALCULATOR?3:5)) +#var RR_TAN D((CALCULATOR?5:RR_NO_KEY),(CALCULATOR?7:RR_NO_KEY)) +#var RR_THETA D((CALCULATOR?8:RR_NO_KEY),(CALCULATOR?1:RR_NO_KEY)) +#var RR_U D((CALCULATOR?6:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_UP D(0,(CALCULATOR?5:0)) +#var RR_V D((CALCULATOR?4:RR_NO_KEY),(CALCULATOR?1:RR_NO_KEY)) +#var RR_W D((CALCULATOR?1:RR_NO_KEY),(CALCULATOR?3:RR_NO_KEY)) +#var RR_WITH D((CALCULATOR?RR_NO_KEY:5),(CALCULATOR?RR_NO_KEY:3)) +#var RR_X D((CALCULATOR?2:5),(CALCULATOR?1:5)) +#var RR_Y D((CALCULATOR?5:4),(CALCULATOR?3:5)) +#var RR_Z D((CALCULATOR?1:3),(CALCULATOR?1:5)) +#var TI89 D((CALCULATOR==0)) +#var TI92PLUS D((CALCULATOR==1)) +#var V200 D((CALCULATOR==3)) diff --git a/pch/src/compiler-internals.pchsource b/pch/src/compiler-internals.pchsource new file mode 100644 index 0000000..da4564f --- /dev/null +++ b/pch/src/compiler-internals.pchsource @@ -0,0 +1,10 @@ +#var __mulsi3 +#var __divsi3 +#var __modsi3 +#var __udivsi3 +#var __umodsi3 +#var __div_entry + +#var __mulsi3_rp +#var __mulsi3ui2_rp +#var __mulsi3si2_rp diff --git a/pch/src/ctype.pchsource b/pch/src/ctype.pchsource new file mode 100644 index 0000000..01dd536 --- /dev/null +++ b/pch/src/ctype.pchsource @@ -0,0 +1,30 @@ + +#var _tolower(c) D(((c)+'a'-'A')) char _extalnum_list[]; char _extpunct_list[]; +#var _toupper(c) D(((c)+'A'-'a')) +#var isalnum(c) D(({register short __c=(c);(__c>='0'&&__c<='9')||(__c>='A'&&__c<='Z')||(__c>='a'&&__c<='z');})) +#var isalpha(c) D(({register short __c=(c);(__c>='A'&&__c<='Z')||(__c>='a'&&__c<='z');})) +#var isascii(c) D(((unsigned short)(c)<128)) +#var iscntrl(c) D(((unsigned short)(c)<14)) +#var isdigit(c) D(({register short __c=(c);__c>='0'&&__c<='9';})) +#var isextalnum(c) D(({register short __c=(c);(unsigned short)__c<256&&_extalnum_list[__c>>3]&(1<<(__c&7));})) +#var isextlower(c) D(({register short __c=(c);(__c>='a'&&__c<='z')||(__c>=224&&__c<=254&&__c!=247);})) +#var isextpunct(c) D(({register short __c=(c);(unsigned short)__c<256&&_extpunct_list[__c>>3]&(1<<(__c&7));})) +#var isextupper(c) D(({register short __c=(c);(__c>='A'&&__c<='Z')||(__c>=192&&__c<=222&&__c!=215);})) +#var isfrgn(c) D(({register short __c=(c);(__c>=128&&__c<148)||(__c==181||__c>=192)&&(__c<=255&&__c!=215&&__c!=247);)}) +#var isfrgnalnum(c) D(({register short __c=(c);(__c>=128&&__c<=148&&__c!=140)||__c==181||(__c>=192&&__c<=255&&__c!=215&&__c!=247);})) +#var isfrgnlower(c) D(({register short __c=(c);__c>=224&&__c<=254&&__c!=247;})) +#var isfrgnupper(c) D(({register short __c=(c);__c>=192&&__c<=222&&__c!=215;})) +#var isgraph(c) D(({register short __c=(c);__c==11||(__c>13&&__c<256&&__c!=32);})) +#var isGreek(c) D(({register short __c=(c);(__c>=128&&__c<=148)||__c==181;})) +#var islower(c) D(({register short __c=(c);__c>='a'&&__c<='z';})) +#var isprint(c) D(({register short __c=(c);__c==11||(__c>13&&__c<256);})) +#var ispunct(c) D(({register short __c=(c);__c>=33&&__c<=127&&!((__c>='0'&&__c<='9')||(__c>='A'&&__c<='Z')||(__c>='a'&&__c<='z'));})) +#var isspace(c) D(({register short __c=(c);(__c>=9&&__c<=13)||__c==32;})) +#var isupper(c) D(({register short __c=(c);__c>='A'&&__c<='Z';})) +#var isxdigit(c) D(({register short __c=(c);(__c>='0'&&__c<='9')||(__c>='A'&&__c<='F')||(__c>='a'&&__c<='f');})) +#var toascii(c) D(((c)&0x7F)) +#var toextlower(c) D(({register short __c=(c);((__c>='A'&&__c<='Z')||(__c>=192&&__c<=222&&__c!=215))?(__c+'a'-'A'):__c;})) +#var toextupper(c) D(({register short __c=(c);((__c>='a'&&__c<='z')||(__c>=224&&__c<=254&&__c!=247))?(__c+'A'-'a'):__c;})) +#var tolower(c) D(({register short __c=(c);(__c>='A'&&__c<='Z')?(__c+'a'-'A'):__c;})) +#var toupper(c) D(({register short __c=(c);(__c>='a'&&__c<='z')?(__c+'A'-'a'):__c;})) + diff --git a/pch/src/dialogs.pchsource b/pch/src/dialogs.pchsource new file mode 100644 index 0000000..8b6cb3f --- /dev/null +++ b/pch/src/dialogs.pchsource @@ -0,0 +1,38 @@ +#var DialogAddScroll(h,x,y,w,g,f,t,p,u,m) D(DialogAdd(h,0,x,y,3,(short)w,(short)g,(short)f,(short)t,(short)p,(short)u,(short)m)) + + +#var CENTER D((-1)) +#var H_NULL D(0) +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var BT_NONE D(0) +#var BT_OK D(1) +#var BT_SAVE D(2) +#var BT_YES D(3) +#var BT_CANCEL D(4) +#var BT_NO D(5) +#var BT_GOTO D(6) + +#var DialogNew_t typedef CALLBACK short(*DialogNew_t)(short x,long y); +#var ESQ typedef unsigned char ESQ; +#var HANDLE typedef unsigned short HANDLE; +#var HSym typedef struct{HANDLE folder;unsigned short offset;}HSym; +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var Dialog D(_rom_call(short,(void*,short,short,char*,__pshort),30)) +#var DialogAdd D(_rom_call(HANDLE,(HANDLE,short,short,short,short,...),33)) +#var DialogAddPulldown(h,x,y,t,p,i) D(DialogAdd(h,2,x,y,14,(const char*)(t),(short)(p),(short)(i))) +#var DialogAddRequest(h,x,y,t,o,m,w) D(DialogAdd(h,0,x,y,2,(const char*)(t),(short)(o),(short)(m),(short)(w))) +#var DialogAddText(h,x,y,t) D(DialogAdd(h,0,x,y,7,(const char*)(t))) +#var DialogAddTitle(h,t,l,r) D(DialogAdd(h,0,0,0,8,(const char*)(t),(short)(l),(short)(r))) +#var DialogDo D(_rom_call(short,(HANDLE,short,short,char*,__pshort),32)) +#var DialogNew D(_rom_call(HANDLE,(short,short,DialogNew_t),34)) +#var DialogNewSimple(w,h) D(DialogNew(w,h,NoCallBack)) +#var DlgMessage D(_rom_call(short,(const char*,const char*,short,short),1B4)) +#var NoCallBack short NoCallBack(short,long)__ATTR_TIOS_CALLBACK__; +#var VarNew D(_rom_call(HSym,(const ESQ*,...),28E)) +#var VarOpen D(_rom_call(HSym,(const ESQ*,...),28C)) +#var VarSaveAs D(_rom_call(HSym,(const ESQ*,const char*,...),28D)) diff --git a/pch/src/dll.pchsource b/pch/src/dll.pchsource new file mode 100644 index 0000000..dfe5f17 --- /dev/null +++ b/pch/src/dll.pchsource @@ -0,0 +1,26 @@ +#var __DLL_SIGNATURE D(0x444C4C20) +#var __DLL_interface_struct typedef struct{unsigned long Signature,ID;unsigned short major,minor;void*jump_table[];}__DLL_interface_struct; + +#var DLL_OK D(0) +#var DLL_NOTINGHOSTSPACE D(1) +#var DLL_NOTFOUND D(2) +#var DLL_LOCKFAILED D(3) +#var DLL_OUTOFMEM D(4) +#var DLL_ALREADYLOADED D(5) +#var DLL_WRONGVERSION D(6) + +#sys __DLL_interface_ptr extern __DLL_interface_struct*__DLL_interface_ptr; +#sys __DLL_body_ptr extern void*__DLL_body_ptr; +#var _DLL_call(type,args,index) D((*(type(*)args)_DLL_entry(index))) +#var _DLL_call_attr(type,args,attr,index) D((*(type(*attr)args)_DLL_entry(index))) +#var _DLL_entry(index) D((__DLL_interface_ptr->jump_table[index])) +#var _DLL_glbvar(type,index) D((*(_DLL_reference(type,index)))) +#var _DLL_reference(type,index) D(((type*const)_DLL_entry(index))) +#var LoadDLL short LoadDLL(const char*,long,short,short)__ATTR_LIB_C__; +#var LoadDLLThrow void LoadDLLThrow(const char*,long,short,short)__ATTR_LIB_C__; +#var UnloadDLL void UnloadDLL(void)__ATTR_LIB_C__; +#var DLL_EXPORTS D(,{) +#var DLL_ID D(__DLL_interface_struct __DLL_interface={__DLL_SIGNATURE,) +#var DLL_IMPLEMENTATION D(,(void*)-1L}};) +#var DLL_INTERFACE #define _nostub_dll +#var DLL_VERSION D(,) diff --git a/pch/src/error-le.pchsource b/pch/src/error-le.pchsource new file mode 100644 index 0000000..c01d5ee --- /dev/null +++ b/pch/src/error-le.pchsource @@ -0,0 +1,37 @@ + +#var FALSE D(0) +#var TRUE D(1) + +#var ERROR_FRAME typedef struct ErrorFrameStruct{unsigned long A2,A3,A4,A5,A6,A7;unsigned long D3,D4,D5,D6,D7;unsigned long NG_control;char*RetIndex;unsigned long PC;struct ErrorFrameStruct*Link;}ERROR_FRAME[1]; +#var ER_OK D(0) +#var ER_OKAY D(0) +#var ER_EXIT D(1) +#var ER_STOP D(2) +#var ER_OFF D(3) +#var ER_PRGM_STOP D(4) +#var ER_NO_MSG D(9) +#var ER_ARGUMENT D(40) +#var ER_BREAK D(180) +#var ER_MEMORY D(670) +#var ER_MEMORY_EXHAUSTION D(670) +#var ER_ESTACK_OVERFLOW D(670) +#var ER_STACK_VIO D(673) +#var ER_SYNTAX D(910) +#var ER_TOO_FEW_ARGS D(930) +#var ER_TOO_MANY_ARGS D(940) + +#var ER_catch D(_rom_call(short,(void*),154)) +#var ER_success D(_rom_call(void,(void),155)) +#var ER_throw(err_no) D(asm volatile{dc.w 0xA000+(err_no)}) +#var ER_throwVar D((*({typedef void(*__temp__type__)(short)__ATTR_TIOS_NORETURN__;(__temp__type__)(_rom_call_addr(153));}))) +#var ERD_dialog D(_rom_call(short,(short,short),151)) +#var ERD_process D(_rom_call(void,(short),152)) +#var ENDFINAL D(}if(errCode)PASS;}) +#var ENDTRY D(;_ONERR_=0;}}) +#var FINALLY D(ER_success();}{) +#var ONERR D(ER_success();}else{register short _ONERR_=1;) +#var PASS D((ER_throwVar(errCode))) +#var TRY D({ERROR_FRAME __errFrame;unsigned short errCode;errCode=ER_catch(__errFrame);if(!errCode){) +#var find_error_message D(_rom_call(const char*,(short),2C1)) + +#var ER_THROW(n) D(ER_throw(n)) diff --git a/pch/src/error.pchsource b/pch/src/error.pchsource new file mode 100644 index 0000000..b704758 --- /dev/null +++ b/pch/src/error.pchsource @@ -0,0 +1,209 @@ + + +#var FALSE D(0) +#var TRUE D(1) + +#var ERROR_FRAME typedef struct ErrorFrameStruct{unsigned long A2,A3,A4,A5,A6,A7;unsigned long D3,D4,D5,D6,D7;unsigned long NG_control;char*RetIndex;unsigned long PC;struct ErrorFrameStruct*Link;}ERROR_FRAME[1]; +#var ER_OK D(0) +#var ER_OKAY D(0) +#var ER_EXIT D(1) +#var ER_STOP D(2) +#var ER_OFF D(3) +#var ER_PRGM_STOP D(4) +#var ER_NO_MSG D(9) +#var ER_FUNC_DID_NOT_RETURN_VALUE D(10) +#var ER_TEST_NOT_TRUE_OR_FALSE D(20) +#var ER_ARG_CANNOT_BE_FOLDER D(30) +#var ER_ARGUMENT D(40) +#var ER_ARG_MISMATCH D(50) +#var ER_EXPECTED_BOOL_OR_AGG D(60) +#var ER_ARG_MUST_BE_DECIMAL D(70) +#var ER_ARG_MUST_BE_LABEL D(80) +#var ER_ARGUMENT_MUST_BE_LIST D(90) +#var ER_ARG_MUST_BE_MATRIX D(100) +#var ER_ARG_MUST_BE_PIC D(110) +#var ER_ARG_MUST_BE_PIC_OR_STR D(120) +#var ER_ARG_MUST_BE_STRING D(130) +#var ER_EXPECTED_VAR D(140) +#var ER_ARG_MUST_BE_EMPTY_FOLDER D(150) +#var ER_EXPECTED_ALGEBRAIC D(160) +#var ER_ASAP_TOO_LONG D(161) +#var ER_ATTRIBUTE_NOT_FOUND D(163) +#var ER_BATT_LOW D(165) +#var ER_BOUND D(170) +#var ER_BREAK D(180) +#var ER_CHECKSUM D(185) +#var ER_CIRCULAR_DEFINITION D(190) +#var ER_INVALID_SUCH_THAT D(200) +#var ER_DATATYPE D(210) +#var ER_DEPENDENT_LIMIT D(220) +#var ER_DIFF_EQ_SETUP D(225) +#var ER_DIMENSION D(230) +#var ER_NOT_ENOUGH_ELEMENTS D(230) +#var ER_NON_CONFORMING_LISTS D(240) +#var ER_DIVBY0 D(250) +#var ER_DOMAIN D(260) +#var ER_DUPLICATE_VAR_NAME D(270) +#var ER_ELSEIF_WITHOUT_IF D(280) +#var ER_ELSE_WITHOUT_IF D(280) +#var ER_ENDTRY_WITHOUT_ELSE D(290) +#var ER_EXCESSIVE_ITERATION D(295) +#var ER_EXPECTED_2OR3_ELEMENTS D(300) +#var ER_EXPIRED D(305) +#var ER_APP_EXT_NOT_FOUND D(307) +#var ER_APP_NOT_FOUND D(308) +#var ER_INVALID_NSOLVE_ARG1 D(310) +#var ER_INVALID_SOLVE_ARG1 D(320) +#var ER_FOLDER D(330) +#var ER_FUNCS_IN_DIFF_EQ D(335) +#var ER_INCONSISTENT_UNITS D(345) +#var ER_INVALID_SUBSCRIPT D(350) +#var ER_INVALID_INDIR_STRING D(360) +#var ER_INDIR_STRING_NOT_VARNAME D(360) +#var ER_INDIR_STRING_NOT_FUNNAME D(360) +#var ER_INVALID_ANS D(380) +#var ER_ILLEGAL_ASSIGNMENT D(390) +#var ER_ILLEGAL_ASSIGNMENT_VALUE D(400) +#var ER_INVALID_AXES D(405) +#var ER_ILLEGAL_COMMAND D(410) +#var ER_INVALID_FOLDER_NAME D(420) +#var ER_GRAPH_MODE D(430) +#var ER_INVALID_GUESS D(435) +#var ER_INVALID_IMPLIED_MULT D(440) +#var ER_ILLEGAL_IN_FUNC D(450) +#var ER_ILLEGAL_IN_CUSTOM D(460) +#var ER_ILLEGAL_IN_DIALOG D(470) +#var ER_ILLEGAL_IN_TOOLBAR D(480) +#var ER_CANNOT_EXIT_FROM_TRY D(490) +#var ER_CANNOT_CYCLE_FROM_TRY D(490) +#var ER_CANNOT_GOTO_FROM_TRY D(490) +#var ER_CANNOT_GOTO_INTO_TRY D(490) +#var ER_INVALID_LABEL D(500) +#var ER_INVALID_LIST_OR_MATRIX D(510) +#var ER_INVAL_OUTSIDE_TB_CM D(520) +#var ER_INVAL_OUTSIDE_DG_TB_CM D(530) +#var ER_INVALID_OUTSIDE_DIALOG D(540) +#var ER_MUST_BE_IN_PRGM_OR_FUNC D(550) +#var ER_CYCLE_NOT_IN_LOOP D(560) +#var ER_EXIT_NOT_IN_LOOP D(560) +#var ER_INVALID_PATHNAME D(570) +#var ER_INVALID_POLAR_COMPLEX D(575) +#var ER_ILLEGAL_PRGM_REF D(580) +#var ER_INVALID_SYNTAX_BLOCK D(590) +#var ER_INVALID_TABLE D(600) + +#var ER_INVALID_USE_OF_UNITS D(605) +#var ER_INVALID_LOCAL_DECLARATION D(610) +#var ER_EXPECTED_VAR_OR_FUNC D(620) +#var ER_INVALID_VAR_REF D(630) +#var ER_INVALID_VECTOR_SYNTAX D(640) +#var ER_LINK_IO D(650) +#var ER_MAT_NOT_DIAGONALIZABLE D(665) +#var ER_MEMORY D(670) +#var ER_MEMORY_EXHAUSTION D(670) +#var ER_ESTACK_OVERFLOW D(670) +#var ER_STACK_VIO D(673) +#var ER_EXPECTED_LPAR D(680) +#var ER_EXPECTED_RPAR D(690) +#var ER_EXPECTED_DOUBLE_QUOTE D(700) +#var ER_EXPECTED_RIGHT_BRACKET D(710) +#var ER_EXPECTED_RIGHT_BRACE D(720) +#var ER_INVALID_BLOCK_STRUCTURE D(730) +#var ER_MISSING_THEN D(740) +#var ER_NOT_FUNC_OR_PRGM D(750) +#var ER_NO_FUNCS_SEL D(765) +#var ER_NO_SOLUTION D(780) +#var ER_NON_ALGEBRAIC_VARIABLE D(790) +#var ER_UNREAL_RESULT D(800) +#var ER_EXPECTED_REAL D(800) +#var ER_MEMORY_DML D(810) +#var ER_RATIONAL_NUMERIC_OVERFLOW D(830) +#var ER_OVERFLOW D(830) +#var ER_STAT_PLOT D(840) +#var ER_PRGM_NOT_FOUND D(850) +#var ER_RECURSION_TOO_DEEP D(860) +#var ER_RESERVED D(870) +#var ER_SYS_FUNC D(870) +#var ER_ROM_ROUTINE_NOT_AVAILABLE D(875) +#var ER_SEQUENCE_SETUP D(880) +#var ER_SIGNATURE_ERR D(885) +#var ER_SINGULARMAT D(890) +#var ER_SLOPE_FIELD_FUNCS D(895) +#var ER_WEIGHTS_SUM_NOT_POS D(900) +#var ER_LISTS_CONTAIN_NEG D(900) +#var ER_LISTS_NOT2DISCREET D(900) +#var ER_EMPTY_GROUP_NOT_VALID D(900) +#var ER_SYNTAX D(910) +#var ER_UNEXPECTED_CHARACTER D(910) +#var ER_EXPECTED_EQUAL D(910) +#var ER_EXPECTED_FACTOR D(910) +#var ER_TOO_FEW_ARGS D(930) +#var ER_TOO_MANY_ARGS D(940) +#var ER_TOO_MANY_SUBSCRIPTS D(950) +#var ER_TOO_MANY_UNDEFINED D(955) +#var ER_UNDEFINED_VAR D(960) +#var ER_UNLICENSED D(965) +#var ER_GRAPH_FUNC_IN_USE D(970) +#var ER_PROG_OR_FUNC_IN_USE D(970) +#var ER_VAR_IN_USE D(970) +#var ER_LOCKED D(980) +#var ER_PROTECTED D(980) +#var ER_NAME_TOO_LONG D(990) +#var ER_RANGE D(1000) +#var ER_ZOOM D(1010) +#var ER_ILLEGAL_TAG D(1020) +#var ER_UNKNOWN_TAG D(1020) +#var ER_DIVISION_BUG D(1020) +#var ER_MEM_VIO D(1030) +#var ER_FP_TEST_FAIL D(4094) +#var EXPECTED_BOOL_OR_AGG_ERROR D(60) +#var EXPECTED_VAR_ERROR D(140) +#var EXPECTED_ALGEBRAIC_ERROR D(160) +#var INVALID_SUCH_THAT_ERROR D(200) +#var NON_CONFORMING_LISTS_ERROR D(240) +#var EXPECTED_2OR3_ELEMENTS_ERROR D(300) +#var INVALID_NSOLVE_ARG1_ERROR D(310) +#var INVALID_SOLVE_ARG1_ERROR D(320) +#var INVALID_PATHNAME_ERROR D(570) +#var EXPECTED_VAR_OR_FUNC_ERROR D(620) +#var MEMORY_EXHAUSTION_ERROR D(670) +#var ESTACK_OVERFLOW_ERROR D(670) +#var EXPECTED_LPAR_ERROR D(680) +#var EXPECTED_RPAR_ERROR D(690) +#var EXPECTED_DOUBLE_QUOTE_ERROR D(700) +#var EXPECTED_RIGHT_BRACKET_ERROR D(710) +#var EXPECTED_RIGHT_BRACE_ERROR D(720) +#var UNREAL_RESULT_ERROR D(800) +#var EXPECTED_REAL_ERROR D(800) +#var RATIONAL_NUMERIC_OVERFLOW_ERROR D(830) + +#var RECURSION_TOO_DEEP_ERROR D(860) +#var SYNTAX_ERROR D(910) +#var UNEXPECTED_CHARACTER_ERROR D(910) +#var EXPECTED_EQUAL_ERROR D(910) +#var EXPECTED_FACTOR_ERROR D(910) +#var TOO_FEW_ARGS_ERROR D(930) +#var TOO_MANY_ARGS_ERROR D(940) +#var TOO_MANY_SUBSCRIPTS_ERROR D(950) +#var TOO_MANY_UNDEFINED_ERROR D(955) +#var GRAPH_FUNC_IN_USE_ERROR D(970) +#var NAME_TOO_LONG_ERROR D(990) +#var ILLEGAL_TAG_ERROR D(1020) +#var UNKNOWN_TAG_ERROR D(1020) +#var DIVISION_BUG_ERROR D(1020) + +#var ER_catch D(_rom_call(short,(void*),154)) +#var ER_success D(_rom_call(void,(void),155)) +#var ER_throw(err_no) D(asm volatile{dc.w 0xA000+(err_no)}) +#var ER_throwVar D((*({typedef void(*__temp__type__)(short)__ATTR_TIOS_NORETURN__;(__temp__type__)(_rom_call_addr(153));}))) +#var ERD_dialog D(_rom_call(short,(short,short),151)) +#var ERD_process D(_rom_call(void,(short),152)) +#var ENDFINAL D(}if(errCode)PASS;}) +#var ENDTRY D(;_ONERR_=0;}}) +#var FINALLY D(ER_success();}{) +#var ONERR D(ER_success();}else{register short _ONERR_=1;) +#var PASS D((ER_throwVar(errCode))) +#var TRY D({ERROR_FRAME __errFrame;unsigned short errCode;errCode=ER_catch(__errFrame);if(!errCode){) +#var find_error_message D(_rom_call(const char*,(short),2C1)) + +#var ER_THROW(n) D(ER_throw(n)) diff --git a/pch/src/estack.pchsource b/pch/src/estack.pchsource new file mode 100644 index 0000000..08b93a4 --- /dev/null +++ b/pch/src/estack.pchsource @@ -0,0 +1,704 @@ +#var _push_zstr(s) D(({register const char*__p=(s);register long __l=_rom_call(long,(const char*),27E)(__p);char __s[__l+2];__s[0]=0;push_expr_quantum(_rom_call(char*,(char*,const char*),26C)(__s+1,__p)+__l,STR_TAG);})) +#var _push_zstr_const(s) D((push_expr_quantum(SYMSTR(s),STR_TAG))) + + +#var H_NULL D(0) +#var NULL_INDEX D(((CESI)0)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var CESI_Callback_t typedef CALLBACK unsigned short(*CESI_Callback_t)(CESI); +#var ESI typedef ESQ*ESI; +#var ESI_Callback_Int_t typedef CALLBACK unsigned short(*ESI_Callback_Int_t)(ESI,unsigned short); +#var ESI_Callback_t typedef CALLBACK void(*ESI_Callback_t)(ESI); +#var EStackIndex D(ESI) +#var INDIR_TAG D(1) +#var GETKEY_TAG D(2) +#var GETFOLD_TAG D(3) +#var SWITCH_TAG D(4) +#var UNITCONV_TAG D(5) +#var ORD_TAG D(6) +#var EXPR_TAG D(7) +#var CHAR_TAG D(8) +#var STRING_TAG D(9) +#var GETTYPE_TAG D(10) +#var GETMODE_TAG D(11) +#var SETFOLD_TAG D(12) +#var PTTEST_TAG D(13) +#var PXLTEST_TAG D(14) +#var SETGRAPH_TAG D(15) +#var SETTABLE_TAG D(16) +#var SETMODE_TAG D(17) +#var FORMAT_TAG D(18) +#var INSTRING_TAG D(19) +#var APPEND_TAG D(20) +#var DD_TAG D(21) +#var EXPR2DMS_TAG D(22) +#var VEC2RECT_TAG D(23) +#var VEC2POLAR_TAG D(24) +#var VEC2CYLIND_TAG D(25) +#var VEC2SPHERE_TAG D(26) +#var PARENTH_START_TAG D(27) +#var PARENTH_END_TAG D(28) +#var MAT_START_TAG D(29) +#var MAT_END_TAG D(30) +#var LIST_START_TAG D(31) +#var LIST_END_TAG D(32) +#var COMMA_TAG D(33) +#var SEMICOLON_TAG D(34) +#var COMPLEX_ANGLE_TAG D(35) +#var SINGLE_QUOTE_TAG D(36) +#var QUOTE_TAG D(37) +#var POLCPLX_TAG D(38) +#var TMPCNV_TAG D(39) +#var DELTA_TMPCNV_TAG D(40) +#var GETUNITS_TAG D(41) +#var SETUNITS_TAG D(42) +#var BIN_TAG D(43) +#var HEX_TAG D(44) +#var INT2BIN_TAG D(45) +#var INT2DEC_TAG D(46) +#var INT2HEX_TAG D(47) +#var DET_TOL_TAG D(48) +#var REF_TOL_TAG D(49) +#var RREF_TOL_TAG D(50) +#var SIMULT_TOL_TAG D(51) +#var GETCONFG_TAG D(52) +#var V_AUGMENT_TAG D(53) +#var VARIANCE_TWOARG_TAG D(58) + +#var HANDLE typedef unsigned short HANDLE; +#var CLRDRAW_ITAG D(1) +#var CLRGRAPH_ITAG D(2) +#var CLRHOME_ITAG D(3) +#var CLRIO_ITAG D(4) +#var CLRTABLE_ITAG D(5) +#var CUSTOM_ITAG D(6) +#var CYCLE_ITAG D(7) +#var DIALOG_ITAG D(8) +#var DISPG_ITAG D(9) +#var DISPTBL_ITAG D(10) +#var ELSE_ITAG D(11) +#var ENDCUSTM_ITAG D(12) +#var ENDDLOG_ITAG D(13) +#var ENDFOR_ITAG D(14) +#var ENDFUNC_ITAG D(15) +#var ENDIF_ITAG D(16) +#var ENDLOOP_ITAG D(17) +#var ENDPRGM_ITAG D(18) +#var ENDTBAR_ITAG D(19) +#var ENDTRY_ITAG D(20) +#var ENDWHILE_ITAG D(21) +#var EXIT_ITAG D(22) +#var FUNC_ITAG D(23) +#var LOOP_ITAG D(24) +#var PRGM_ITAG D(25) +#var SHOWSTAT_ITAG D(26) +#var STOP_ITAG D(27) +#var THEN_ITAG D(28) +#var TOOLBAR_ITAG D(29) +#var TRACE_ITAG D(30) +#var TRY_ITAG D(31) +#var ZOOMBOX_ITAG D(32) +#var ZOOMDATA_ITAG D(33) +#var ZOOMDEC_ITAG D(34) +#var ZOOMFIT_ITAG D(35) +#var ZOOMIN_ITAG D(36) +#var ZOOMINT_ITAG D(37) +#var ZOOMOUT_ITAG D(38) +#var ZOOMPREV_ITAG D(39) +#var ZOOMRCL_ITAG D(40) +#var ZOOMSQR_ITAG D(41) +#var ZOOMSTD_ITAG D(42) +#var ZOOMSTO_ITAG D(43) +#var ZOOMTRIG_ITAG D(44) +#var DRAWFUNC_ITAG D(45) +#var DRAWINV_ITAG D(46) +#var GOTO_ITAG D(47) +#var LBL_ITAG D(48) +#var GET_ITAG D(49) +#var SEND_ITAG D(50) +#var GETCALC_ITAG D(51) +#var SENDCALC_ITAG D(52) +#var NEWFOLD_ITAG D(53) +#var PRINTOBJ_ITAG D(54) +#var RCLGDB_ITAG D(55) +#var STOGDB_ITAG D(56) +#var ELSEIF_ITAG D(57) +#var IF_ITAG D(58) +#var IFTHEN_ITAG D(59) +#var RANDSEED_ITAG D(60) +#var WHILE_ITAG D(61) +#var LINETAN_ITAG D(62) +#var COPYVAR_ITAG D(63) +#var RENAME_ITAG D(64) +#var STYLE_ITAG D(65) +#var FILL_ITAG D(66) +#var REQUEST_ITAG D(67) +#var POPUP_ITAG D(68) +#var PTCHG_ITAG D(69) +#var PTOFF_ITAG D(70) +#var PTON_ITAG D(71) +#var PXLCHG_ITAG D(72) +#var PXLOFF_ITAG D(73) +#var PXLON_ITAG D(74) +#var MOVEVAR_ITAG D(75) +#var DROPDOWN_ITAG D(76) +#var OUTPUT_ITAG D(77) +#var PTTEXT_ITAG D(78) +#var PXLTEXT_ITAG D(79) +#var DRAWSLP_ITAG D(80) +#var PAUSE_ITAG D(81) +#var RETURN_ITAG D(82) +#var INPUT_ITAG D(83) +#var PLOTSOFF_ITAG D(84) +#var PLOTSON_ITAG D(85) +#var TITLE_ITAG D(86) +#var ITEM_ITAG D(87) +#var INPUTSTR_ITAG D(88) +#var LINEHORZ_ITAG D(89) +#var LINEVERT_ITAG D(90) +#var PXLHORZ_ITAG D(91) +#var PXLVERT_ITAG D(92) +#var ANDPIC_ITAG D(93) +#var RCLPIC_ITAG D(94) +#var RPLCPIC_ITAG D(95) +#var XORPIC_ITAG D(96) +#var DRAWPOL_ITAG D(97) +#var TEXT_ITAG D(98) +#var ONEVAR_ITAG D(99) +#var STOPIC_ITAG D(100) +#var GRAPH_ITAG D(101) +#var TABLE_ITAG D(102) +#var NEWPIC_ITAG D(103) +#var DRAWPARM_ITAG D(104) +#var CYCLEPIC_ITAG D(105) +#var CUBICREG_ITAG D(106) +#var EXPREG_ITAG D(107) +#var LINREG_ITAG D(108) +#var LNREG_ITAG D(109) +#var MEDMED_ITAG D(110) +#var POWERREG_ITAG D(111) +#var QUADREG_ITAG D(112) +#var QUARTREG_ITAG D(113) +#var TWOVAR_ITAG D(114) +#var SHADE_ITAG D(115) +#var FOR_ITAG D(116) +#var CIRCLE_ITAG D(117) +#var PXLCRCL_ITAG D(118) +#var NEWPLOT_ITAG D(119) +#var LINE_ITAG D(120) + +#var PXLLINE_ITAG D(121) +#var DISP_ITAG D(122) +#var FNOFF_ITAG D(123) +#var FNON_ITAG D(124) +#var LOCAL_ITAG D(125) +#var DELFOLD_ITAG D(126) +#var DELVAR_ITAG D(127) +#var LOCK_ITAG D(128) +#var PROMPT_ITAG D(129) +#var SORTA_ITAG D(130) +#var SORTD_ITAG D(131) +#var UNLOCK_ITAG D(132) +#var NEWDATA_ITAG D(133) +#var DEFINE_ITAG D(134) +#var ELSE_TRY_ITAG D(135) +#var CLRERR_ITAG D(136) +#var PASSERR_ITAG D(137) +#var DISPHOME_ITAG D(138) +#var EXEC_ITAG D(139) +#var ARCHIVE_ITAG D(140) +#var UNARCHIV_ITAG D(141) +#var LU_ITAG D(142) +#var QR_ITAG D(143) +#var BLDDATA_ITAG D(144) +#var DRWCTOUR_ITAG D(145) +#var NEWPROB_ITAG D(146) +#var SINREG_ITAG D(147) +#var LOGISTIC_ITAG D(148) +#var CUSTMON_ITAG D(149) +#var CUSTMOFF_ITAG D(150) +#var SENDCHAT_ITAG D(151) + +#var MULTI_EXPR typedef struct{unsigned short Size;ESQ Expr[];}MULTI_EXPR; +#var Quantum D(ESQ) +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var SYM_STR typedef CESI SYM_STR; +#var X_BAR_TAG D(1) +#var Y_BAR_TAG D(2) +#var SIGMA_X_TAG D(3) +#var SIGMA_X2_TAG D(4) +#var SIGMA_Y_TAG D(5) +#var SIGMA_Y2_TAG D(6) +#var SIGMA_XY_TAG D(7) +#var SX_TAG D(8) +#var SY_TAG D(9) +#var SMLSIGMA_X_TAG D(10) +#var SMLSIGMA_Y_TAG D(11) +#var NSTAT_TAG D(12) +#var MINX_TAG D(13) +#var MINY_TAG D(14) +#var Q1_TAG D(15) +#var MEDSTAT_TAG D(16) +#var Q3_TAG D(17) +#var MAXX_TAG D(18) +#var MAXY_TAG D(19) +#var CORR_TAG D(20) +#var R2_TAG D(21) +#var MEDX1_TAG D(22) +#var MEDX2_TAG D(23) +#var MEDX3_TAG D(24) +#var MEDY1_TAG D(25) +#var MEDY2_TAG D(26) +#var MEDY3_TAG D(27) +#var XC_TAG D(28) +#var YC_TAG D(29) +#var ZC_TAG D(30) +#var TC_TAG D(31) +#var RC_TAG D(32) +#var THETA_C_TAG D(33) +#var NC_TAG D(34) +#var XFACT_TAG D(35) +#var YFACT_TAG D(36) +#var ZFACT_TAG D(37) +#var XMIN_TAG D(38) +#var XMAX_TAG D(39) +#var XSCL_TAG D(40) +#var YMIN_TAG D(41) +#var YMAX_TAG D(42) +#var YSCL_TAG D(43) +#var DELTA_X_TAG D(44) +#var DELTA_Y_TAG D(45) +#var XRES_TAG D(46) +#var XGRID_TAG D(47) +#var YGRID_TAG D(48) +#var ZMIN_TAG D(49) +#var ZMAX_TAG D(50) +#var ZSCL_TAG D(51) +#var EYE_THETA_TAG D(52) +#var EYE_PHI_TAG D(53) +#var THETA_MIN_TAG D(54) +#var THETA_MAX_TAG D(55) +#var THETA_STEP_TAG D(56) +#var TMIN_TAG D(57) +#var TMAX_TAG D(58) +#var TSTEP_TAG D(59) +#var NMIN_TAG D(60) +#var NMAX_TAG D(61) +#var PLOTSTRT_TAG D(62) +#var PLOTSTEP_TAG D(63) +#var ZXMIN_TAG D(64) +#var ZXMAX_TAG D(65) +#var ZXSCL_TAG D(66) +#var ZYMIN_TAG D(67) +#var ZYMAX_TAG D(68) +#var ZYSCL_TAG D(69) +#var ZXRES_TAG D(70) +#var Z_THETA_MIN_TAG D(71) +#var Z_THETA_MAX_TAG D(72) +#var Z_THETA_STEP_TAG D(73) +#var ZTMIN_TAG D(74) +#var ZTMAX_TAG D(75) +#var ZTSTEP_TAG D(76) +#var ZXGRID_TAG D(77) +#var ZYGRID_TAG D(78) +#var ZZMIN_TAG D(79) +#var ZZMAX_TAG D(80) +#var ZZSCL_TAG D(81) +#var ZEYE_THETA_TAG D(82) +#var ZEYE_PHI_TAG D(83) +#var ZNMIN_TAG D(84) +#var ZNMAX_TAG D(85) +#var ZPLTSTEP_TAG D(86) +#var ZPLTSTRT_TAG D(87) +#var SEED1_TAG D(88) +#var SEED2_TAG D(89) +#var OK_TAG D(90) +#var ERRORNUM_TAG D(91) +#var SYSMATH_TAG D(92) +#var SYSDATA_TAG D(93) +#var REGEQ_TAG D(94) +#var REGCOEF_TAG D(95) +#var TBLINPUT_TAG D(96) +#var TBLSTART_TAG D(97) +#var DELTA_TBL_TAG D(98) +#var FLDPIC_TAG D(99) +#var EYE_PSI_TAG D(100) +#var TPLOT_TAG D(101) +#var DIFTOL_TAG D(102) +#var ZEYE_PSI_TAG D(103) +#var T0_TAG D(104) +#var DTIME_TAG D(105) +#var NCURVES_TAG D(106) +#var FLDRES_TAG D(107) +#var ESTEP_TAG D(108) +#var ZT0DE_TAG D(109) +#var ZTMAXDE_TAG D(110) +#var ZTSTEPDE_TAG D(111) +#var ZTPLOTDE_TAG D(112) +#var NCONTOUR_TAG D(113) + +#var VAR_NAME_TAG D(0) +#var _VAR_Q_TAG D(1) +#var VAR_R_TAG D(2) +#var VAR_S_TAG D(3) +#var VAR_T_TAG D(4) +#var VAR_U_TAG D(5) +#var VAR_V_TAG D(6) +#var VAR_W_TAG D(7) +#var VAR_X_TAG D(8) +#var VAR_Y_TAG D(9) +#var VAR_Z_TAG D(10) +#var VAR_A_TAG D(11) +#var VAR_B_TAG D(12) +#var VAR_C_TAG D(13) +#var VAR_D_TAG D(14) +#var VAR_E_TAG D(15) +#var VAR_F_TAG D(16) +#var VAR_G_TAG D(17) +#var VAR_H_TAG D(18) +#var VAR_I_TAG D(19) +#var VAR_J_TAG D(20) +#var VAR_K_TAG D(21) +#var VAR_L_TAG D(22) +#var VAR_M_TAG D(23) +#var VAR_N_TAG D(24) +#var VAR_O_TAG D(25) +#var VAR_P_TAG D(26) +#var VAR_Q_TAG D(27) +#var EXT_SYSTEM_TAG D(28) +#var ARB_REAL_TAG D(29) +#var ARB_INT_TAG D(30) +#var POSINT_TAG D(31) +#var NEGINT_TAG D(32) +#var POSFRAC_TAG D(33) +#var NEGFRAC_TAG D(34) +#var FLOAT_TAG D(35) +#var BCD_TAG D(35) +#var PI_TAG D(36) +#var EXP_TAG D(37) +#var IM_TAG D(38) +#var NEGINFINITY_TAG D(39) +#var INFINITY_TAG D(40) +#var PN_INFINITY_TAG D(41) +#var UNDEF_TAG D(42) +#var FALSE_TAG D(43) +#var TRUE_TAG D(44) +#var STR_TAG D(45) +#var NOTHING_TAG D(46) +#var ACOSH_TAG D(47) +#var ASINH_TAG D(48) +#var ATANH_TAG D(49) +#var COSH_TAG D(53) +#var SINH_TAG D(54) +#var TANH_TAG D(55) +#var ACOS_TAG D(59) +#var ASIN_TAG D(60) +#var ATAN_TAG D(61) +#var RACOS_TAG D(65) +#var RASIN_TAG D(66) +#var RATAN_TAG D(67) +#var COS_TAG D(68) +#var SIN_TAG D(69) +#var TAN_TAG D(70) +#var ITAN_TAG D(74) +#var ABS_TAG D(75) +#var ANGLE_TAG D(76) +#var CEILING_TAG D(77) +#var FLOOR_TAG D(78) +#var INT_TAG D(79) +#var SIGN_TAG D(80) +#var SQRT_TAG D(81) +#var EXPF_TAG D(82) +#var LN_TAG D(83) +#var LOG_TAG D(84) +#var FPART_TAG D(85) +#var IPART_TAG D(86) +#var CONJ_TAG D(87) +#var IMAG_TAG D(88) +#var REAL_TAG D(89) +#var APPROX_TAG D(90) +#var TEXPAND_TAG D(91) +#var TCOLLECT_TAG D(92) +#var GETDENOM_TAG D(93) +#var GETNUM_TAG D(94) +#var CUMSUM_TAG D(96) +#var DET_TAG D(97) +#var COLNORM_TAG D(98) +#var ROWNORM_TAG D(99) +#var NORM_TAG D(100) +#var MEAN_TAG D(101) +#var MEDIAN_TAG D(102) +#var PRODUCT_TAG D(103) +#var STDDEV_TAG D(104) +#var SUM_TAG D(105) +#var VARIANCE_TAG D(106) +#var UNITV_TAG D(107) +#var DIM_TAG D(108) +#var MAT2LIST_TAG D(109) +#var NEWLIST_TAG D(110) +#var RREF_TAG D(111) +#var REF_TAG D(112) +#var IDENTITY_TAG D(113) +#var DIAG_TAG D(114) +#var COLDIM_TAG D(115) +#var ROWDIM_TAG D(116) +#var TRANSPOSE_TAG D(117) +#var FACTORIAL_TAG D(118) +#var PERCENT_TAG D(119) +#var RADIANS_TAG D(120) +#var NOT_TAG D(121) +#var MINUS_TAG D(122) +#var VEC_POLAR_TAG D(123) +#var VEC_CYLIND_TAG D(124) +#var VEC_SPHERE_TAG D(125) +#var START_TAG D(126) +#var ISTORE_TAG D(127) +#var STORE_TAG D(128) +#var WITH_TAG D(129) +#var XOR_TAG D(130) +#var OR_TAG D(131) +#var AND_TAG D(132) +#var LT_TAG D(133) +#var LE_TAG D(134) +#var EQ_TAG D(135) +#var GE_TAG D(136) +#var GT_TAG D(137) +#var NE_TAG D(138) +#var ADD_TAG D(139) +#var ADDELT_TAG D(140) +#var SUB_TAG D(141) +#var SUBELT_TAG D(142) +#var MUL_TAG D(143) +#var MULELT_TAG D(144) +#var DIV_TAG D(145) + +#var DIVELT_TAG D(146) +#var POW_TAG D(147) +#var POWELT_TAG D(148) +#var SINCOS_TAG D(149) +#var SOLVE_TAG D(150) +#var CSOLVE_TAG D(151) +#var NSOLVE_TAG D(152) +#var ZEROS_TAG D(153) +#var CZEROS_TAG D(154) +#var FMIN_TAG D(155) +#var FMAX_TAG D(156) +#var COMPLEX_TAG D(157) +#var POLYEVAL_TAG D(158) +#var RANDPOLY_TAG D(159) +#var CROSSP_TAG D(160) +#var DOTP_TAG D(161) +#var GCD_TAG D(162) +#var LCM_TAG D(163) +#var MOD_TAG D(164) +#var INTDIV_TAG D(165) +#var REMAIN_TAG D(166) +#var NCR_TAG D(167) +#var NPR_TAG D(168) +#var P2RX_TAG D(169) +#var P2RY_TAG D(170) +#var P2PTHETA_TAG D(171) +#var P2PR_TAG D(172) +#var AUGMENT_TAG D(173) +#var NEWMAT_TAG D(174) +#var RANDMAT_TAG D(175) +#var SIMULT_TAG D(176) +#var PART_TAG D(177) +#var EXP2LIST_TAG D(178) +#var RANDNORM_TAG D(179) +#var MROW_TAG D(180) +#var ROWADD_TAG D(181) +#var ROWSWAP_TAG D(182) +#var ARCLEN_TAG D(183) +#var NINT_TAG D(184) +#var PI_PRODUCT_TAG D(185) +#var SIGMA_SUM_TAG D(186) +#var MROWADD_TAG D(187) +#var ANS_TAG D(188) +#var ENTRY_TAG D(189) +#var EXACT_TAG D(190) +#var LOGB_TAG D(191) +#var COMDENOM_TAG D(192) +#var EXPAND_TAG D(193) +#var FACTOR_TAG D(194) +#var CFACTOR_TAG D(195) +#var INTEGRATE_TAG D(196) +#var DIFFERENTIATE_TAG D(197) +#var AVGRC_TAG D(198) +#var NDERIV_TAG D(199) +#var TAYLOR_TAG D(200) +#var LIMIT_TAG D(201) +#var PROPFRAC_TAG D(202) +#var WHEN_TAG D(203) +#var ROUND_TAG D(204) +#var DMS_TAG D(205) +#var LEFT_TAG D(206) +#var RIGHT_TAG D(207) +#var MID_TAG D(208) +#var SHIFT_TAG D(209) +#var SEQ_TAG D(210) +#var LIST2MAT_TAG D(211) +#var SUBMAT_TAG D(212) +#var SUBSCRIPT_TAG D(213) +#var RAND_TAG D(214) +#var MIN_TAG D(215) +#var MAX_TAG D(216) +#var LIST_TAG D(217) +#var USERFUNC_TAG D(218) +#var MATRIX_TAG D(219) +#var FUNC_TAG D(220) +#var DATA_TAG D(221) +#var GDB_TAG D(222) +#var PIC_TAG D(223) +#var TEXT_TAG D(224) +#var FIG_TAG D(225) +#var MAC_TAG D(226) +#var EXT_TAG D(227) +#var EXT_INSTR_TAG D(228) +#var END_TAG D(229) +#var COMMENT_TAG D(230) +#var NEXTEXPR_TAG D(231) +#var NEWLINE_TAG D(232) +#var ENDSTACK_TAG D(233) +#var PN1_TAG D(234) +#var PN2_TAG D(235) +#var ERROR_MSG_TAG D(236) +#var EIGVC_TAG D(237) +#var EIGVL_TAG D(238) +#var DASH_TAG D(239) +#var LOCALVAR_TAG D(240) +#var DESOLVE_TAG D(241) +#var FDASH_TAG D(242) +#var ASM_TAG D(243) +#var ISPRIME_TAG D(244) +#var OTH_TAG D(248) +#var ROTATE_TAG D(249) + +#var ti_float typedef float ti_float; +#var TSF_FULLY_QUALIFIED D(1) +#var TSF_ALLOW_RESERVED D(2) +#var TSF_PASS_ERRORS D(4) + +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var bottom_estack D((*(AMS_1xx?(CESI*)(&top_estack-2):(CESI*)(_rom_call_addr(432))))) +#var top_estack D((*((ESI*)(_rom_call_addr(109))))) +#var display_statements D(_rom_call(HANDLE,(CESI,short,short),4E)) +#var ESTACK(idx) D((*(idx))) +#var HS_popEStack D(_rom_call(HANDLE,(void),244)) +#var HToESI D(_rom_call(ESI,(HANDLE),247)) +#var next_expression_index D(_rom_call(ESI,(ESI),10A)) +#var NG_approxESI D(_rom_call(void,(CESI),25C)) +#var NG_execute D(_rom_call(void,(HANDLE,short),25D)) +#var NG_graphESI D(_rom_call(void,(CESI,HANDLE),25E)) +#var NG_rationalESI D(_rom_call(void,(CESI),25F)) +#var NG_RPNToText D(_rom_call(HANDLE,(HANDLE,short,short),25B)) +#var NG_tokenize D(_rom_call(short,(HANDLE,__pushort,__pushort),260)) +#var Parms2D D(_rom_call(void,(CESI,__pshort,__pshort,__pshort),4D)) +#var Parse1DExpr D(_rom_call(HANDLE,(CESI,short,short),4F)) +#var Parse2DExpr D(_rom_call(ESI,(CESI,short),4A)) +#var Parse2DMultiExpr D(_rom_call(ESI,(HANDLE,short),4B)) +#var Print2DExpr D(_rom_call(void,(CESI,WINDOW*,short,short),4C)) +#var push_END_TAG D(_rom_call(void,(void),263)) +#var push_LIST_TAG D(_rom_call(void,(void),264)) +#var push_quantum(tag) D((MIN_AMS<101?(void)(*(++top_estack)=tag):_rom_call(void,(ESQ),2EE)(tag))) +#var TokenizeSymName D(_rom_call(ESI,(const char*,short),80)) +#var all_tail D(_rom_call(short,(CESI_Callback_t,ESI),3B5)) +#var any_tail D(_rom_call(short,(CESI_Callback_t,ESI),3B6)) +#var are_expressions_identical D(_rom_call(short,(CESI,CESI),2BF)) +#var can_be_approxed D(_rom_call(short,(CESI,short),2F5)) +#var check_estack_size D(_rom_call(void,(short),2C2)) +#var compare_complex_magnitudes D(_rom_call(short,(CESI,CESI),2F6)) +#var compare_expressions D(_rom_call(short,(CESI,CESI),2C0)) +#var compare_Floats D(_rom_call(long,(CESI,CESI),2F7)) +#var delete_between D(_rom_call(void,(ESI,ESI),2C3)) +#var delete_expression D(_rom_call(void,(ESI),2C5)) +#var deleted_between D(_rom_call(unsigned short,(ESI,ESI),2C4)) +#var deleted_expression D(_rom_call(unsigned short,(ESI),2C6)) +#var did_push_cnvrt_Float_to_integer D(_rom_call(short,(CESI),2F8)) +#var estack_number_to_Float(x) D(_tios_float_1(2F9,x,CESI)) +#var estack_to_short D(_rom_call(short,(CESI,__pshort),2C7)) +#var estack_to_ushort D(_rom_call(short,(CESI,__pushort),2C8)) +#var factor_base_index D(_rom_call(ESI,(CESI),2C9)) +#var factor_exponent_index D(_rom_call(ESI,(CESI),2CA)) +#var gcd_exact_whole_Floats(x,y) D(_tios_float_2(2FC,x,y,CESI,CESI)) +#var get_key_ptr D(_rom_call(char*,(ESQ,ESQ),2B7)) +#var GetValue D(_rom_call(long,(CESI,long,long),2CB)) +#var im_index D(_rom_call(ESI,(CESI),2CC)) +#var index_below_display_expression_aux D(_rom_call(ESI,(CESI),2B6)) +#var index_main_var D(_rom_call(ESI,(CESI),2CF)) +#var index_numeric_term D(_rom_call(ESI,(CESI),2CD)) +#var index_of_lead_base_of_lead_term D(_rom_call(ESI,(CESI),2CE)) +#var is_advanced_tag D(_rom_call(short,(ESQ),2D0)) +#var is_antisymmetric D(_rom_call(short,(CESI,CESI),2D1)) +#var is_complex0 D(_rom_call(short,(CESI),2D3)) +#var is_complex_number D(_rom_call(short,(CESI),2D2)) +#var is_Float_exact_whole_number D(_rom_call(short,(CESI),2FE)) +#var is_free_of_tag D(_rom_call(short,(CESI,ESQ),2D4)) +#var is_independent_of D(_rom_call(short,(CESI,CESI),2D5)) +#var is_independent_of_de_seq_vars D(_rom_call(short,(CESI),2D6)) +#var is_independent_of_elements D(_rom_call(short,(CESI,CESI),2D8)) +#var is_independent_of_tail D(_rom_call(short,(CESI,CESI),2D7)) +#var is_matrix D(_rom_call(short,(CESI),3B7)) +#var is_monomial D(_rom_call(short,(CESI),2D9)) +#var is_monomial_in_kernel D(_rom_call(short,(CESI),2DA)) +#var is_narrowly_independent_of D(_rom_call(short,(CESI,CESI),2DB)) +#var is_square_matrix D(_rom_call(short,(CESI),3B8)) +#var is_symmetric D(_rom_call(short,(CESI,CESI),2DC)) +#var is_tail_independent_of D(_rom_call(short,(CESI,CESI),2DD)) +#var is_valid_smap_aggregate D(_rom_call(short,(CESI),3B9)) +#var last_element_index D(_rom_call(ESI,(CESI),3BA)) +#var lead_base_index D(_rom_call(ESI,(CESI),2DE)) +#var lead_exponent_index D(_rom_call(ESI,(CESI),2DF)) +#var lead_factor_index D(_rom_call(ESI,(CESI),2E0)) +#var lead_term_index D(_rom_call(ESI,(CESI),2E1)) +#var likely_approx_to_complex_number D(_rom_call(short,(CESI),307)) +#var likely_approx_to_number D(_rom_call(short,(CESI),308)) +#var main_gen_var_index D(_rom_call(ESI,(CESI),2E2)) +#var map_tail D(_rom_call(void,(ESI_Callback_t,ESI),3BB)) +#var map_tail_Int D(_rom_call(short,(ESI_Callback_Int_t,ESI,short),3BC)) +#var map_unary_over_comparison D(_rom_call(void,(ESI_Callback_t,ESI),2E3)) +#var min_quantum D(_rom_call(ESQ,(ESQ,ESQ),2E4)) +#var move_between_to_top D(_rom_call(void,(ESI,ESI),2E5)) +#var moved_between_to_top D(_rom_call(unsigned short,(ESI,ESI),2E6)) +#var norm1_complex_Float(x) D(_tios_float_1(309,x,CESI)) +#var numeric_factor_index D(_rom_call(ESI,(CESI),2E7)) +#var push_ANSI_string D(push_zstr) +#var push_between D(_rom_call(void,(void*,void*),2E8)) +#var push_cnvrt_integer_if_whole_nmb D(_rom_call(void,(CESI),30D)) +#var push_expr_quantum D(_rom_call(void,(CESI,ESQ),2E9)) +#var push_expr2_quantum D(_rom_call(void,(CESI,CESI,ESQ),2EA)) +#var push_expression(ptr) D((MIN_AMS<200?({push_expr_quantum(ptr,NOTHING_TAG);(void)(--top_estack);}):_rom_call(void,(CESI),44D)(ptr))) +#var push_Float D(_rom_call(void,(float),30A)) +#var push_Float_to_nonneg_int D(_rom_call(void,(float),30B)) +#var push_Float_to_rat D(_rom_call(void,(CESI),30C)) +#var push_internal_simplify D((*(__push_internal_simplify__type__)(AMS_1xx?(*((void**)((char*)_rom_call_addr(385)+22))):_rom_call(void,(CESI),4F8)))) +#var push_longint void push_longint(long)__ATTR_LIB_ASM__; +#var push_longlongint void push_longlongint(long long)__ATTR_LIB_ASM__; +#var push_next_arb_int D(_rom_call(void,(void),2EB)) +#var push_next_arb_real D(_rom_call(void,(void),2EC)) +#var push_next_internal_var D(_rom_call(void,(ESQ),2ED)) +#var push_offset_array D(_rom_call(unsigned short,(CESI,__pushort*),3C4)) +#var push_overflow_to_infinity D(_rom_call(void,(ESQ),30E)) +#var push_parse_text D(_rom_call(short,(const char*),3CA)) +#var push_quantum_pair D(_rom_call(void,(ESQ,ESQ),2EF)) +#var push_reversed_tail D(_rom_call(void,(CESI),3BF)) +#var push_round_Float D(_rom_call(void,(CESI),310)) +#var push_shortint void push_shortint(short)__ATTR_LIB_ASM__; +#var push_transpose_aux D(_rom_call(void,(CESI,short),3C1)) +#var push_zstr(s) D((MIN_AMS<200?_push_zstr(s):_rom_call(void,(const char*),48A)(s))) +#var re_index D(_rom_call(ESI,(CESI),2F2)) +#var reductum_index D(_rom_call(ESI,(CESI),2F0)) +#var remaining_element_count D(_rom_call(unsigned short,(CESI),3C3)) +#var remaining_factors_index D(_rom_call(ESI,(CESI),2F1)) +#var reset_control_flags D(_rom_call(void,(void),2F4)) +#var reset_estack_size D(_rom_call(void,(short),2F3)) +#var should_and_did_push_approx_arg2 D(_rom_call(short,(CESI,CESI),311)) +#var signum_Float D(_rom_call(long,(CESI),312)) + +#var __push_internal_simplify__type__ typedef void(*__push_internal_simplify__type__)(CESI)__ATTR_TIOS__; diff --git a/pch/src/estackle.pchsource b/pch/src/estackle.pchsource new file mode 100644 index 0000000..3c969e5 --- /dev/null +++ b/pch/src/estackle.pchsource @@ -0,0 +1,167 @@ +#var _push_zstr(s) D(({const char*__p=(s);long __l=_rom_call(long,(const char*),27E)(__p);char *__s=alloca(__l+2);__s[0]=0;push_expr_quantum(_rom_call(char*,(char*,const char*),26C)(__s+1,__p)+__l,STR_TAG);})) +#var _push_zstr_const(s) D((push_expr_quantum(SYMSTR(s),STR_TAG))) + + +#var H_NULL D(0) +#var NULL_INDEX D(((CESI)0)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var CESI_Callback_t typedef CALLBACK unsigned short(*CESI_Callback_t)(CESI); +#var ESI typedef ESQ*ESI; +#var ESI_Callback_Int_t typedef CALLBACK unsigned short(*ESI_Callback_Int_t)(ESI,unsigned short); +#var ESI_Callback_t typedef CALLBACK void(*ESI_Callback_t)(ESI); +#var EStackIndex D(ESI) + +#var MULTI_EXPR typedef struct{unsigned short Size;ESQ Expr[];}MULTI_EXPR; +#var Quantum D(ESQ) +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var SYM_STR typedef CESI SYM_STR; +#var POSINT_TAG D(31) +#var NEGINT_TAG D(32) +#var FLOAT_TAG D(35) +#var BCD_TAG D(35) +#var UNDEF_TAG D(42) +#var FALSE_TAG D(43) +#var TRUE_TAG D(44) +#var STR_TAG D(45) +#var LIST_TAG D(217) +#var USERFUNC_TAG D(218) +#var MATRIX_TAG D(219) +#var FUNC_TAG D(220) +#var DATA_TAG D(221) +#var GDB_TAG D(222) +#var PIC_TAG D(223) +#var TEXT_TAG D(224) +#var FIG_TAG D(225) +#var MAC_TAG D(226) +#var END_TAG D(229) +#var ASM_TAG D(243) +#var OTH_TAG D(248) + +#var ti_float typedef float ti_float; +#var TSF_FULLY_QUALIFIED D(1) +#var TSF_ALLOW_RESERVED D(2) +#var TSF_PASS_ERRORS D(4) + +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var bottom_estack D((*(AMS_1xx?(CESI*)(&top_estack-2):(CESI*)(_rom_call_addr(432))))) +#var top_estack D((*((ESI*)(_rom_call_addr(109))))) +#var display_statements D(_rom_call(HANDLE,(CESI,short,short),4E)) +#var ESTACK(idx) D((*(idx))) +#var HS_popEStack D(_rom_call(HANDLE,(void),244)) +#var HToESI D(_rom_call(ESI,(HANDLE),247)) +#var next_expression_index D(_rom_call(ESI,(ESI),10A)) +#var NG_approxESI D(_rom_call(void,(CESI),25C)) +#var NG_execute D(_rom_call(void,(HANDLE,short),25D)) +#var NG_graphESI D(_rom_call(void,(CESI,HANDLE),25E)) +#var NG_rationalESI D(_rom_call(void,(CESI),25F)) +#var NG_RPNToText D(_rom_call(HANDLE,(HANDLE,short,short),25B)) +#var NG_tokenize D(_rom_call(short,(HANDLE,__pushort,__pushort),260)) +#var Parms2D D(_rom_call(void,(CESI,__pshort,__pshort,__pshort),4D)) +#var Parse1DExpr D(_rom_call(HANDLE,(CESI,short,short),4F)) +#var Parse2DExpr D(_rom_call(ESI,(CESI,short),4A)) +#var Parse2DMultiExpr D(_rom_call(ESI,(HANDLE,short),4B)) +#var Print2DExpr D(_rom_call(void,(CESI,WINDOW*,short,short),4C)) +#var push_END_TAG D(_rom_call(void,(void),263)) +#var push_LIST_TAG D(_rom_call(void,(void),264)) +#var push_quantum(tag) D((MIN_AMS<101?(void)(*(++top_estack)=tag):_rom_call(void,(ESQ),2EE)(tag))) +#var TokenizeSymName D(_rom_call(ESI,(const char*,short),80)) +#var all_tail D(_rom_call(short,(CESI_Callback_t,ESI),3B5)) +#var any_tail D(_rom_call(short,(CESI_Callback_t,ESI),3B6)) +#var are_expressions_identical D(_rom_call(short,(CESI,CESI),2BF)) +#var can_be_approxed D(_rom_call(short,(CESI,short),2F5)) +#var check_estack_size D(_rom_call(void,(short),2C2)) +#var compare_complex_magnitudes D(_rom_call(short,(CESI,CESI),2F6)) +#var compare_expressions D(_rom_call(short,(CESI,CESI),2C0)) +#var compare_Floats D(_rom_call(long,(CESI,CESI),2F7)) +#var delete_between D(_rom_call(void,(ESI,ESI),2C3)) +#var delete_expression D(_rom_call(void,(ESI),2C5)) +#var deleted_between D(_rom_call(unsigned short,(ESI,ESI),2C4)) +#var deleted_expression D(_rom_call(unsigned short,(ESI),2C6)) +#var did_push_cnvrt_Float_to_integer D(_rom_call(short,(CESI),2F8)) +#var estack_number_to_Float(x) D(_tios_float_1(2F9,x,CESI)) +#var estack_to_short D(_rom_call(short,(CESI,__pshort),2C7)) +#var estack_to_ushort D(_rom_call(short,(CESI,__pushort),2C8)) +#var factor_base_index D(_rom_call(ESI,(CESI),2C9)) +#var factor_exponent_index D(_rom_call(ESI,(CESI),2CA)) +#var gcd_exact_whole_Floats(x,y) D(_tios_float_2(2FC,x,y,CESI,CESI)) +#var get_key_ptr D(_rom_call(char*,(ESQ,ESQ),2B7)) +#var GetValue D(_rom_call(long,(CESI,long,long),2CB)) +#var im_index D(_rom_call(ESI,(CESI),2CC)) +#var index_below_display_expression_aux D(_rom_call(ESI,(CESI),2B6)) +#var index_main_var D(_rom_call(ESI,(CESI),2CF)) +#var index_numeric_term D(_rom_call(ESI,(CESI),2CD)) +#var index_of_lead_base_of_lead_term D(_rom_call(ESI,(CESI),2CE)) +#var is_advanced_tag D(_rom_call(short,(ESQ),2D0)) +#var is_antisymmetric D(_rom_call(short,(CESI,CESI),2D1)) +#var is_complex0 D(_rom_call(short,(CESI),2D3)) +#var is_complex_number D(_rom_call(short,(CESI),2D2)) +#var is_Float_exact_whole_number D(_rom_call(short,(CESI),2FE)) +#var is_free_of_tag D(_rom_call(short,(CESI,ESQ),2D4)) +#var is_independent_of D(_rom_call(short,(CESI,CESI),2D5)) +#var is_independent_of_de_seq_vars D(_rom_call(short,(CESI),2D6)) +#var is_independent_of_elements D(_rom_call(short,(CESI,CESI),2D8)) +#var is_independent_of_tail D(_rom_call(short,(CESI,CESI),2D7)) +#var is_matrix D(_rom_call(short,(CESI),3B7)) +#var is_monomial D(_rom_call(short,(CESI),2D9)) +#var is_monomial_in_kernel D(_rom_call(short,(CESI),2DA)) +#var is_narrowly_independent_of D(_rom_call(short,(CESI,CESI),2DB)) +#var is_square_matrix D(_rom_call(short,(CESI),3B8)) +#var is_symmetric D(_rom_call(short,(CESI,CESI),2DC)) +#var is_tail_independent_of D(_rom_call(short,(CESI,CESI),2DD)) +#var is_valid_smap_aggregate D(_rom_call(short,(CESI),3B9)) +#var last_element_index D(_rom_call(ESI,(CESI),3BA)) +#var lead_base_index D(_rom_call(ESI,(CESI),2DE)) +#var lead_exponent_index D(_rom_call(ESI,(CESI),2DF)) +#var lead_factor_index D(_rom_call(ESI,(CESI),2E0)) +#var lead_term_index D(_rom_call(ESI,(CESI),2E1)) +#var likely_approx_to_complex_number D(_rom_call(short,(CESI),307)) +#var likely_approx_to_number D(_rom_call(short,(CESI),308)) +#var main_gen_var_index D(_rom_call(ESI,(CESI),2E2)) +#var map_tail D(_rom_call(void,(ESI_Callback_t,ESI),3BB)) +#var map_tail_Int D(_rom_call(short,(ESI_Callback_Int_t,ESI,short),3BC)) +#var map_unary_over_comparison D(_rom_call(void,(ESI_Callback_t,ESI),2E3)) +#var min_quantum D(_rom_call(ESQ,(ESQ,ESQ),2E4)) +#var move_between_to_top D(_rom_call(void,(ESI,ESI),2E5)) +#var moved_between_to_top D(_rom_call(unsigned short,(ESI,ESI),2E6)) +#var norm1_complex_Float(x) D(_tios_float_1(309,x,CESI)) +#var numeric_factor_index D(_rom_call(ESI,(CESI),2E7)) +#var push_ANSI_string D(push_zstr) +#var push_between D(_rom_call(void,(void*,void*),2E8)) +#var push_cnvrt_integer_if_whole_nmb D(_rom_call(void,(CESI),30D)) +#var push_expr_quantum D(_rom_call(void,(CESI,ESQ),2E9)) +#var push_expr2_quantum D(_rom_call(void,(CESI,CESI,ESQ),2EA)) +#var push_expression(ptr) D((MIN_AMS<200?({push_expr_quantum(ptr,NOTHING_TAG);(void)(--top_estack);}):_rom_call(void,(CESI),44D)(ptr))) +#var push_Float D(_rom_call(void,(float),30A)) +#var push_Float_to_nonneg_int D(_rom_call(void,(float),30B)) +#var push_Float_to_rat D(_rom_call(void,(CESI),30C)) +#var push_internal_simplify D((*(__push_internal_simplify__type__)(AMS_1xx?(*((void**)((char*)_rom_call_addr(385)+22))):_rom_call(void,(CESI),4F8)))) +#var push_longint void push_longint(long)__ATTR_LIB_ASM__; +#var push_longlongint void push_longlongint(long long)__ATTR_LIB_ASM__; +#var push_next_arb_int D(_rom_call(void,(void),2EB)) +#var push_next_arb_real D(_rom_call(void,(void),2EC)) +#var push_next_internal_var D(_rom_call(void,(ESQ),2ED)) +#var push_offset_array D(_rom_call(unsigned short,(CESI,__pushort*),3C4)) +#var push_overflow_to_infinity D(_rom_call(void,(ESQ),30E)) +#var push_parse_text D(_rom_call(short,(const char*),3CA)) +#var push_quantum_pair D(_rom_call(void,(ESQ,ESQ),2EF)) +#var push_reversed_tail D(_rom_call(void,(CESI),3BF)) +#var push_round_Float D(_rom_call(void,(CESI),310)) +#var push_shortint void push_shortint(short)__ATTR_LIB_ASM__; +#var push_transpose_aux D(_rom_call(void,(CESI,short),3C1)) +#var push_zstr(s) D((MIN_AMS<200?_push_zstr(s):_rom_call(void,(const char*),48A)(s))) +#var re_index D(_rom_call(ESI,(CESI),2F2)) +#var reductum_index D(_rom_call(ESI,(CESI),2F0)) +#var remaining_element_count D(_rom_call(unsigned short,(CESI),3C3)) +#var remaining_factors_index D(_rom_call(ESI,(CESI),2F1)) +#var reset_control_flags D(_rom_call(void,(void),2F4)) +#var reset_estack_size D(_rom_call(void,(short),2F3)) +#var should_and_did_push_approx_arg2 D(_rom_call(short,(CESI,CESI),311)) +#var signum_Float D(_rom_call(long,(CESI),312)) + +#var __push_internal_simplify__type__ typedef void(*__push_internal_simplify__type__)(CESI)__ATTR_TIOS__; diff --git a/pch/src/events.pchsource b/pch/src/events.pchsource new file mode 100644 index 0000000..8b02468 --- /dev/null +++ b/pch/src/events.pchsource @@ -0,0 +1,142 @@ + +#var ModeSettings D(((MO_OPTIONS*const)(long)*(short*)((char*)MO_currentOptions+6))) +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var HANDLE typedef unsigned short HANDLE; +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var WIN_RECT typedef struct{short x0,y0,x1,y1;}WIN_RECT; +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var EVENT typedef struct EventStruct{unsigned short Type;unsigned short RunningApp;unsigned short Side;unsigned short StatusFlags;union{WINDOW*w;WIN_RECT*r;char*pasteText;HANDLE hPasteText;struct{unsigned short Mod;unsigned short Code;}Key;}extra;unsigned char StartType;}EVENT; +#var EVENT_HANDLER typedef void(*EVENT_HANDLER)(EVENT*)CALLBACK; +#var CM_IDLE D(1792) +#var CM_INIT D(1793) +#var CM_STARTTASK D(1794) +#var CM_ACTIVATE D(1795) +#var CM_FOCUS D(1796) +#var CM_UNFOCUS D(1797) +#var CM_DEACTIVATE D(1798) +#var CM_ENDTASK D(1799) +#var CM_START_CURRENT D(1800) +#var CM_DEFAULTS D(1803) +#var CM_KEYPRESS D(1808) +#var CM_MENU_CUT D(1824) +#var CM_MENU_COPY D(1825) +#var CM_MENU_PASTE D(1826) +#var CM_STRING D(1827) +#var CM_HSTRING D(1828) +#var CM_DEL D(1829) +#var CM_CLR D(1830) +#var CM_MENU_CLEAR D(1831) +#var CM_MENU_FIND D(1832) +#var CM_INSERT D(1840) +#var CM_BLINK D(1856) +#var CM_STORE D(1872) +#var CM_RECALL D(1873) +#var CM_WPAINT D(1888) +#var CM_MENU_OPEN D(1904) +#var CM_MENU_SAVE D(1905) +#var CM_MENU_NEW D(1906) +#var CM_MENU_FORMAT D(1907) +#var CM_MENU_ABOUT D(1908) +#var CM_MODE_CHANGE D(1920) +#var CM_SWITCH_GRAPH D(1921) +#var CM_GEOMETRY D(1984) + +#var MO_OPTIONS typedef struct{unsigned short CurrentFolder;unsigned short SplitScreen;unsigned short NumGraphs;unsigned short Graph1;unsigned short Graph2;unsigned short Split1App;unsigned short Split2App;unsigned short SplitRatio;unsigned short Angle;unsigned short ExactApprox;unsigned short Fix;unsigned short Exp;unsigned short Vector;unsigned short Complex;unsigned short Pretty;unsigned short Base;unsigned short UnitSystem;unsigned short CustomUnits;}MO_OPTIONS; +#var PAINTING_ENABLED D(0) +#var PAINTING_SUSPENDED D(2) + +#var ACTIVITY_IDLE D(0) +#var ACTIVITY_BUSY D(1) +#var ACTIVITY_PAUSED D(2) +#var ACTIVITY_NORMAL D(3) + +#var AP_NULL D(-3) +#var AP_RUNNING D(-2) +#var AP_CURRENT D(-1) + +#var AP_START_CURRENT D(0) +#var __AP_START_NEW_2 D(1) +#var __AP_START_OPEN_2 D(2) +#var __AP_START_ERROR_2 D(3) +#var __AP_START_NEW_1 D(16) +#var __AP_START_OPEN_1 D(32) +#var __AP_START_ERROR_1 D(48) + +#var SDT_EXPR D(0) +#var SDT_LIST D(1) +#var SDT_MAT D(2) +#var SDT_FUNC D(3) +#var SDT_PRGM D(4) +#var SDT_PIC D(5) +#var SDT_STR D(6) +#var SDT_TEXT D(7) +#var SDT_GDB D(8) +#var SDT_DATA D(9) +#var SDT_FIG D(10) +#var SDT_MAC D(11) +#var SDT_OTH D(12) +#var SDT_SYS D(13) +#var SDT_ALL D(14) +#var SDT_ASM D(15) + +#var WF_SYS_ALLOC D(1) +#var WF_STEAL_MEM D(2) +#var WF_DONT_REALLOC D(4) +#var WF_ROUNDEDBORDER D(8) +#var WF_SAVE_SCR D(16) +#var WF_DUP_SCR D(32) +#var WF_TTY D(64) +#var WF_ACTIVE D(128) +#var WF_NOBORDER D(256) +#var WF_NOBOLD D(512) +#var WF_DUP_ON D(1024) +#var WF_VIRTUAL D(2048) +#var WF_TITLE D(4096) +#var WF_DIRTY D(8192) +#var WF_TRY_SAVE_SCR D(16400) +#var WF_VISIBLE D(-32768) + +#var EV_hook D((*((EVENT_HANDLER*)(_rom_call_addr(2A3))))) +#var ABT_dialog D(_rom_call(void,(void),10D)) +#var CAT_dialog D(_rom_call(void,(void),125)) +#var EV_captureEvents D(_rom_call(EVENT_HANDLER,(EVENT_HANDLER),C6)) +#var EV_centralDispatcher D(_rom_call(void,(void),156)) +#var EV_clearPasteString D(_rom_call(void,(void),C7)) +#var EV_defaultHandler D(_rom_call(void,(EVENT*),157)) +#var EV_eventLoop D(_rom_call(void,(void),158)) +#var EV_getAppID short EV_getAppID(const char*)__ATTR_LIB_ASM__; +#var EV_getc D(_rom_call(unsigned short,(short,EVENT*),C8)) +#var EV_getSplitRect D(_rom_call(WIN_RECT*,(short),C9)) +#var EV_notifySwitchGraph D(_rom_call(void,(void),CA)) +#var EV_paintOneWindow D(_rom_call(short,(void),CB)) +#var EV_paintWindows D(_rom_call(void,(void),CC)) +#var EV_registerMenu D(_rom_call(void,(void*),159)) +#var EV_restorePainting D(_rom_call(short,(short),CD)) +#var EV_sendEvent D(_rom_call(void,(short,EVENT*),CE)) +#var EV_sendEventSide D(_rom_call(void,(short,EVENT*,short),CF)) +#var EV_sendString D(_rom_call(void,(short),D0)) +#var EV_setCmdCheck D(_rom_call(void,(short,short),D1)) +#var EV_setCmdState D(_rom_call(void,(short,short),D2)) +#var EV_setFKeyState D(_rom_call(void,(short,short,short),D3)) +#var EV_startApp D(_rom_call(void,(short,short),D4)) +#var EV_startSide D(_rom_call(void,(__pshort,short,short),D5)) +#var EV_startTask D(_rom_call(void,(short),D6)) +#var EV_suspendPainting D(_rom_call(short,(void),D7)) +#var EV_switch D(_rom_call(void,(void),D8)) +#var handleRclKey D(_rom_call(void,(short),14F)) +#var MO_currentOptions D(_rom_call(void,(void),D9)) +#var MO_defaults D(_rom_call(void,(void),DA)) +#var MO_digestOptions D(_rom_call(void,(short),DB)) +#var MO_isMultigraphTask D(_rom_call(short,(short),DC)) +#var MO_modeDialog D(_rom_call(void,(void),DD)) +#var MO_notifyModeChange D(_rom_call(void,(short),DE)) +#var MO_sendQuit D(_rom_call(void,(short,short),DF)) + + +#var AP_START_NEW D((AMS_1xx?__AP_START_NEW_1:__AP_START_NEW_2)) +#var AP_START_OPEN D((AMS_1xx?__AP_START_OPEN_1:__AP_START_OPEN_2)) +#var AP_START_ERROR D((AMS_1xx?__AP_START_ERROR_1:__AP_START_ERROR_2)) diff --git a/pch/src/flash.pchsource b/pch/src/flash.pchsource new file mode 100644 index 0000000..27a7b37 --- /dev/null +++ b/pch/src/flash.pchsource @@ -0,0 +1,24 @@ +#var __EM_findEmptySlot D(_rom_call(void*,(long,short),15F)) + + +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var HANDLE typedef unsigned short HANDLE; +#var HARDWARE_PARM_BLOCK typedef struct{unsigned short len;unsigned long hardwareID;unsigned long hardwareRevision;unsigned long bootMajor;unsigned long bootRevision;unsigned long bootBuild;unsigned long gateArray;unsigned long physDisplayBitsWide;unsigned long physDisplayBitsTall;unsigned long LCDBitsWide;unsigned long LCDBitsTall;}HARDWARE_PARM_BLOCK; +#var size_t typedef unsigned long size_t; +#var EM_abandon D(_rom_call(void,(HANDLE),15B)) +#var EM_blockVerifyErase D(_rom_call(short,(void*),15D)) +#var EM_findEmptySlot(s) D((__EM_findEmptySlot((s),0))) +#var EM_GC D(_rom_call(short,(short),160)) +#var EM_survey D(_rom_call(void,(__pulong,__pulong,__pulong,__pulong,__pulong,__pulong),165)) +#var EM_write D(_rom_call(void,(const void*,void*,long),167)) +#var FL_addCert D(_rom_call(unsigned short,(void*,long),169)) +#var FL_download D(_rom_call(void,(long),16A)) +#var FL_getCert D(_rom_call(void,(HANDLE*,__pulong,short),16C)) +#var FL_getHardwareParmBlock() D((TIOS_entries<0x3CC?(const void*)"\0\x6\0\0\0\x1":_rom_call(const void*,(void),16B)())) +#var FL_getVerNum D(_rom_call(unsigned short,(void),16D)) +#var FL_write D(_rom_call(void,(const void*,void*,long),171)) +#var GetAMSSize unsigned long GetAMSSize(void); + diff --git a/pch/src/float.pchsource b/pch/src/float.pchsource new file mode 100644 index 0000000..241ddb5 --- /dev/null +++ b/pch/src/float.pchsource @@ -0,0 +1,41 @@ + +#var DBL_DIG D(16) +#var DBL_EPSILON D((1e-15)) +#var DBL_MANT_BITS D(64) +#var DBL_MANT_DIG D(16) +#var DBL_MAX D((9.999999999999999e999)) +#var DBL_MAX_10_EXP D(999) +#var DBL_MAX_2_EXP D(3321) +#var DBL_MAX_EXP D(999) +#var DBL_MIN D((1e-999)) +#var DBL_MIN_10_EXP D((-999)) +#var DBL_MIN_2_EXP D((-3318)) +#var DBL_MIN_EXP D((-999)) +#var FLT_DIG D(16) +#var FLT_EPSILON D((1e-15)) +#var FLT_MANT_BITS D(64) +#var FLT_MANT_DIG D(16) +#var FLT_MAX D((9.999999999999999e999)) +#var FLT_MAX_10_EXP D(999) +#var FLT_MAX_2_EXP D(3321) +#var FLT_MAX_EXP D(999) +#var FLT_MIN D((1e-999)) +#var FLT_MIN_10_EXP D((-999)) +#var FLT_MIN_2_EXP D((-3318)) +#var FLT_MIN_EXP D((-999)) +#var FLT_NORMALIZE D(1) +#var FLT_RADIX D(10) +#var FLT_ROUNDS D(1) +#var LDBL_DIG D(16) +#var LDBL_EPSILON D((1e-15)) +#var LDBL_MANT_BITS D(64) +#var LDBL_MANT_DIG D(16) +#var LDBL_MAX D((9.999999999999999e999)) +#var LDBL_MAX_10_EXP D(999) +#var LDBL_MAX_2_EXP D(3321) +#var LDBL_MAX_EXP D(999) +#var LDBL_MIN D((1e-999)) +#var LDBL_MIN_10_EXP D((-999)) +#var LDBL_MIN_2_EXP D((-3318)) +#var LDBL_MIN_EXP D((-999)) + diff --git a/pch/src/gdraw.pchsource b/pch/src/gdraw.pchsource new file mode 100644 index 0000000..8c41d57 --- /dev/null +++ b/pch/src/gdraw.pchsource @@ -0,0 +1,17 @@ + +#var GR_FUNC D(1) +#var GR_PAR D(2) +#var GR_POL D(3) +#var GR_SEQ D(4) +#var GR_3D D(5) +#var GR_DE D(6) + +#var GD_Circle D(_rom_call(void,(void),176)) +#var GD_Contour D(_rom_call(void,(void),17D)) +#var GD_Eraser D(_rom_call(void,(void),17A)) +#var GD_HVLine D(_rom_call(void,(short),178)) +#var GD_Line D(_rom_call(void,(void),177)) +#var GD_Pen D(_rom_call(void,(void),179)) +#var GD_Select D(_rom_call(void,(void),17C)) +#var GD_Text D(_rom_call(void,(void),17B)) + diff --git a/pch/src/graph.pchsource b/pch/src/graph.pchsource new file mode 100644 index 0000000..e686dac --- /dev/null +++ b/pch/src/graph.pchsource @@ -0,0 +1,87 @@ + +#var BITMAP_HDR_SIZE D(4) +#var LCD_MEM D(((void*)0x4C00)) +#var LCD_SIZE D(3840) +#var A_REVERSE D(0) +#var A_NORMAL D(1) +#var A_XOR D(2) +#var A_SHADED D(3) +#var A_REPLACE D(4) +#var A_OR D(5) +#var A_AND D(6) +#var A_THICK1 D(7) +#var A_SHADE_V D(8) +#var A_SHADE_H D(9) +#var A_SHADE_NS D(10) +#var A_SHADE_PS D(11) + +#var BITMAP typedef struct{unsigned short NumRows,NumCols;unsigned char Data[];}BITMAP; +#var FALSE D(0) +#var TRUE D(1) + +#var B_NORMAL D(16) +#var B_ROUNDED D(32) +#var B_DOUBLE D(64) +#var B_CUT D(128) + +#var F_4x6 D(0) +#var F_6x8 D(1) +#var F_8x10 D(2) + +#var ICON typedef struct{unsigned short i[16];}ICON; +#var LCD_BUFFER typedef char LCD_BUFFER[LCD_SIZE]; +#var MULTI_LINE typedef struct{unsigned char Count;struct{unsigned char Attr,x0,y0,x1,y1;}Data[];}MULTI_LINE; +#var pICON typedef unsigned short*pICON; +#var SCR_COORDS typedef unsigned char SCR_COORDS; +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var WIN_COORDS typedef short WIN_COORDS; +#var WIN_RECT typedef struct{short x0,y0,x1,y1;}WIN_RECT; +#var ScrRect D(((SCR_RECT*const)(_rom_call_addr(2F)))) +#var BitmapGet D(_rom_call(void,(const SCR_RECT*,void*),185)) +#var BitmapInit D(_rom_call(void,(const SCR_RECT*,void*),186)) +#var BitmapPut D(_rom_call(void,(short,short,const void*,const SCR_RECT*,short),187)) +#var BitmapSize D(_rom_call(unsigned short,(const SCR_RECT*),188)) +#var ClrScr D(_rom_call(void,(void),19E)) +#var ClearScreen D(ClrScr) +#var DisplayOff() D((pokeIO_bclr(0x600015,0))) +#var DisplayOn() D((pokeIO_bset(0x600015,0))) +#var DrawChar D(_rom_call(void,(short,short,char,short),1A4)) +#var DrawClipChar D(_rom_call(void,(short,short,short,const SCR_RECT*,short),191)) +#var DrawClipEllipse D(_rom_call(void,(short,short,short,short,const SCR_RECT*,short),192)) +#var DrawClipLine D(_rom_call(void,(const WIN_RECT*,const SCR_RECT*,short),193)) +#var DrawClipPix D(_rom_call(void,(short,short),194)) +#var DrawClipRect D(_rom_call(void,(const WIN_RECT*,const SCR_RECT*,short),195)) +#var DrawFkey D(_rom_call(void,(short,short,short,short),1A5)) +#var DrawIcon D(_rom_call(void,(short,short,const void*,short),1A6)) +#var DrawLine D(_rom_call(void,(short,short,short,short,short),1A7)) +#var DrawMultiLines D(_rom_call(void,(short,short,const void*),196)) +#var DrawPix D(_rom_call(void,(short,short,short),1A8)) +#var DrawStr D(_rom_call(void,(short,short,const char*,short),1A9)) +#var DrawStrXY D(DrawStr) +#var DrawStrWidth D(_rom_call(short,(const char*,short),197)) +#var DrawTo D(_rom_call(void,(short,short),19C)) +#var FillLines2 D(_rom_call(void,(const WIN_RECT*,const WIN_RECT*,const SCR_RECT*,short),199)) +#var FillTriangle D(_rom_call(void,(short,short,short,short,short,short,const SCR_RECT*,short),198)) +#var FontCharWidth D(_rom_call(short,(short),190)) +#var FontGetSys D(_rom_call(unsigned char,(void),18E)) +#var FontSetSys D(_rom_call(unsigned char,(short),18F)) +#var GetPix D(_rom_call(short,(short,short),19F)) +#var LCD_restore(b) D(((void)(_rom_call(void,(),26A)(LCD_MEM,(const void*)(b),(long)LCD_SIZE)))) +#var LCD_save(b) D(((void)(_rom_call(void,(),26A)((void*)(b),LCD_MEM,(long)LCD_SIZE)))) +#var LineTo D(_rom_call(void,(short,short),19C)) +#var MakeWinRect D(_rom_call(WIN_RECT*,(short,short,short,short),2C)) +#var MoveTo D(_rom_call(void,(short,short),19D)) +#var PortRestore D(_rom_call(void,(void),1A3)) +#var PortSet D(_rom_call(void,(void*,short,short),1A2)) +#var QScrRectOverlap D(_rom_call(short,(const SCR_RECT*,const SCR_RECT*),18D)) +#var RestoreScrState D(_rom_call(void,(const void*),1A1)) +#var SaveScrState D(_rom_call(void,(void*),1A0)) +#var ScrRectFill D(_rom_call(void,(const SCR_RECT*,const SCR_RECT*,short),189)) +#var ScrRectOverlap D(_rom_call(short,(const SCR_RECT*,const SCR_RECT*,SCR_RECT*),18A)) +#var ScrRectScroll D(_rom_call(void,(const SCR_RECT*,const SCR_RECT*,short,short),18B)) +#var ScrRectShift D(_rom_call(void,(const SCR_RECT*,const SCR_RECT*,short,short),18C)) +#var ScrToHome D(_rom_call(SCR_RECT*,(SCR_RECT*),2E)) +#var ScrToWin D(_rom_call(WIN_RECT*,(const SCR_RECT*),2D)) +#var SetCurAttr D(_rom_call(short,(short),19A)) +#var SetCurClip D(_rom_call(void,(const SCR_RECT*),19B)) diff --git a/pch/src/gray.pchsource b/pch/src/gray.pchsource new file mode 100644 index 0000000..d2835ad --- /dev/null +++ b/pch/src/gray.pchsource @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + +#var __L_plane extern void* __L_plane; +#var __D_plane extern void* __D_plane; +#var __L_plane2 extern void* __L_plane2; +#var __D_plane2 extern void* __D_plane2; + +#var __gray_hw_type extern short __gray_hw_type; +#var __gray_dbl_offset extern unsigned short __gray_dbl_offset; +#var __switch_cnt extern volatile unsigned long __switch_cnt; +#var __gray_old_int1_hw1 extern volatile void *__gray_old_int1_hw1; +#var __gray_old_int1_hw2 extern volatile void *__gray_old_int1_hw2; +#var __gray_version extern const char __gray_version[]; + + + + + + +#var GRAYDBUFFER_SIZE D(7688) +#var FALSE D(0) +#var TRUE D(1) + +#var GRAY_OFF D(0) +#var GRAY_ON D(1) +#var GRAY_HW1 D(1) +#var GRAY_HW2 D(1) + +#var LIGHT_PLANE D(0) +#var DARK_PLANE D(1) + +#var _DEREF_INT_HANDLER typedef struct{short foo;}_DEREF_INT_HANDLER; +#var INT_HANDLER typedef _DEREF_INT_HANDLER *INT_HANDLER; +#var GrayAdjust(x) D(((void)(*(volatile unsigned char*)0x600013=128-(signed char)(x)))) +#var GrayCheckRunning() D((!!__gray_handle)) +#var __gray_handle extern unsigned short __gray_handle; +#var IsGrayMode D(GrayCheckRunning) +#var GrayDBufCleanup() D(((void)(__gray_dbl_offset=0,__D_plane2=__D_plane,__L_plane2=__L_plane))) +#var GrayDBufGetActiveIdx() D((!!__gray_dbl_offset)) +#var GrayDBufGetActivePlane(x) D((GrayDBufGetPlane(GrayDBufGetActiveIdx(),x))) +#var GrayDBufGetHiddenIdx() D((!__gray_dbl_offset)) +#var GrayDBufGetHiddenPlane(x) D((GrayDBufGetPlane(GrayDBufGetHiddenIdx(),x))) +#var GrayDBufGetPlane(i,x) D(((i)?((x)?__D_plane2:__L_plane2):GrayGetPlane(x))) +#var GrayDBufInit(p) D(({void*aptr=(void*)((((long)p)+7)&0xfffffff8L);__gray_dbl_offset=0;__D_plane2=aptr;(void)(__L_plane2=aptr+3840);})) +#var GrayDBufSetActiveAMSPlane(x) D(GrayDBufSetAMSPlane(GrayDBufGetActiveIdx(),x)) +#var GrayDBufSetActiveIdx(i) D(((void)(__gray_dbl_offset=((i)?8:0)))) +#var GrayDBufSetActiveIdxSync(i) D(((void)(GrayWaitNSwitches(1),GrayDBufSetActiveIdx(i)))) +#var GrayDBufSetAMSPlane(i,x) D((_rom_call(void,(void*,long),1A2)(GrayDBufGetPlane(i,x),0xEF007F))) +#var GrayDBufSetHiddenAMSPlane(x) D(GrayDBufSetAMSPlane(GrayDBufGetHiddenIdx(),x)) +#var GrayDBufToggle() D(((void)(__gray_dbl_offset=(__gray_dbl_offset?0:8)))) +#var GrayDBufToggleSync() D((GrayWaitNSwitches(1),GrayDBufToggle())) +#var GrayGetInt1Handler() D(((INT_HANDLER)(__gray_hw_type?__gray_old_int1_hw2:__gray_old_int1_hw1))) +#var GetGrayInt1Handler D(GrayGetInt1Handler) +#var GrayGetPlane(x) D(((x)?__D_plane:__L_plane)) +#var GetPlane D(GrayGetPlane) +#var GrayGetSwitchCount() D((__switch_cnt)) +#var GetGraySwitchCount D(GrayGetSwitchCount) +#var GrayGetVersionString() D(((const char*)__gray_version)) +#var GrayMode(x) D(((x)?GrayOn():(GrayOff(),(short)1))) +#var GrayOff void GrayOff(void)__ATTR_LIB_ASM__; +#var GrayOn short GrayOn(void)__ATTR_LIB_ASM__; +#var GraySetAMSPlane(x) D((_rom_call(void,(void*,long),1A2)(GrayGetPlane(x),0xEF007F))) +#var SetPlane D(GraySetAMSPlane) +#var GraySetInt1Handler(p) D(((void)(__gray_hw_type?((INT_HANDLER)__gray_old_int1_hw2=(p)):((INT_HANDLER)__gray_old_int1_hw1=(p))))) +#var SetGrayInt1Handler D(GraySetInt1Handler) +#var GraySetSwitchCount(val) D((__switch_cnt=(val))) +#var SetGraySwitchCount D(GraySetSwitchCount) +#var GrayWaitNSwitches(n) D(({unsigned long __w=__switch_cnt+(n);while(__switch_cnt<__w);})) + + +#var _GrayIsRealHW2() D((__gray_hw_type)) diff --git a/pch/src/gtc.pchsource b/pch/src/gtc.pchsource new file mode 100644 index 0000000..b67eece --- /dev/null +++ b/pch/src/gtc.pchsource @@ -0,0 +1,5 @@ +#var _RC_INDEX_romcall(t,a,i) D(0x##i) +#var _RC_INDEX_romcall_addr(i) D(0x##i) +#var _ROMCALL_INDEX(name) D(_RC_INDEX##name) +#var ROMCALL_INDEX(name) D(_ROMCALL_INDEX(name)) +#var ROMCALL_OFFSET(name) D((_ROMCALL_INDEX(name)*4)) diff --git a/pch/src/homescr.pchsource b/pch/src/homescr.pchsource new file mode 100644 index 0000000..d1b5a9c --- /dev/null +++ b/pch/src/homescr.pchsource @@ -0,0 +1,29 @@ +#var __HS_pushEmptyFIFONode__type__ typedef void(*__HS_pushEmptyFIFONode__type__)(short)__ATTR_TIOS__; + + + +#var H_NULL D(0) +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var HANDLE typedef unsigned short HANDLE; +#var MULTI_EXPR typedef struct{unsigned short Size;ESQ Expr[];}MULTI_EXPR; +#var FIFO_ELEMENT typedef struct{short ScreenLeft;long ScreenBottom;long XStart;unsigned short Width;unsigned short Height;short Top;HANDLE Expr;short TooLong;short PrettyPrint;unsigned short Exp;unsigned short Fix;}FIFO_ELEMENT; +#var FIFO_NODE typedef struct{FIFO_ELEMENT Entry;FIFO_ELEMENT Ans;HANDLE Prev;HANDLE Next;}FIFO_NODE; +#var HomeExecute D(_rom_call(void,(const char*,short),10E)) +#var HomePushEStack D(_rom_call(void,(void),10F)) +#var HomeStore void HomeStore(void)__ATTR_LIB_ASM__; +#var HomeStorePair void HomeStorePair(HANDLE,HANDLE)__ATTR_LIB_C__; +#var HS_chopFIFO D(_rom_call(void,(void),23C)) +#var HS_countFIFO D(_rom_call(unsigned short,(void),23D)) +#var HS_deleteFIFONode D(_rom_call(HANDLE,(HANDLE),23E)) +#var HS_freeAll D(_rom_call(void,(void),23F)) +#var HS_freeFIFONode D(_rom_call(void,(HANDLE),240)) +#var HS_getAns D(_rom_call(HANDLE,(short),241)) +#var HS_getEntry D(_rom_call(HANDLE,(short),242)) +#var HS_getFIFONode D(_rom_call(HANDLE,(short),243)) +#var HS_newFIFONode D(_rom_call(HANDLE,(void),245)) +#var HS_popEStack D(_rom_call(HANDLE,(void),244)) +#var HS_pushEmptyFIFONode D((*(__get_HS_pushEmptyFIFONode()))) __HS_pushEmptyFIFONode__type__ __get_HS_pushEmptyFIFONode(void)__ATTR_LIB_C__; +#var HS_pushFIFONode D(_rom_call(void,(HANDLE),246)) diff --git a/pch/src/intr.pchsource b/pch/src/intr.pchsource new file mode 100644 index 0000000..0ef942c --- /dev/null +++ b/pch/src/intr.pchsource @@ -0,0 +1,73 @@ + + + +#var AUTO_INT_COUNT D((LAST_AUTO_INT-FIRST_AUTO_INT+1)) +#var FIRST_AUTO_INT D(1) +#var FIRST_TRAP D(0) +#var LAST_AUTO_INT D(7) +#var LAST_TRAP D(15) +#var TRAP_COUNT D((LAST_TRAP-FIRST_TRAP+1)) +#var AutoInts D(IntVecs) +#var FALSE D(0) +#var TRUE D(1) + +#var _DEREF_INT_HANDLER typedef struct{short foo;}_DEREF_INT_HANDLER; +#var INT_HANDLER typedef _DEREF_INT_HANDLER *INT_HANDLER; +#var AUTO_INT_1 D(100) +#var AUTO_INT_2 D(104) +#var AUTO_INT_3 D(108) +#var AUTO_INT_4 D(112) +#var AUTO_INT_5 D(116) +#var AUTO_INT_6 D(120) +#var AUTO_INT_7 D(124) +#var TRAP_0 D(128) +#var TRAP_1 D(132) +#var TRAP_2 D(136) +#var TRAP_3 D(140) +#var TRAP_4 D(144) +#var TRAP_5 D(148) +#var TRAP_6 D(152) +#var TRAP_7 D(156) +#var TRAP_8 D(160) +#var TRAP_9 D(164) +#var TRAP_10 D(168) +#var TRAP_11 D(172) +#var TRAP_12 D(176) +#var TRAP_13 D(180) +#var TRAP_14 D(184) +#var TRAP_15 D(188) +#var INT_VEC_RESET D(4) +#var INT_VEC_BUS_ERROR D(8) +#var INT_VEC_ADDRESS_ERROR D(12) +#var INT_VEC_ILLEGAL_INSTRUCTION D(16) +#var INT_VEC_ZERO_DIVIDE D(20) +#var INT_VEC_CHK_INS D(24) +#var INT_VEC_TRAPV_INS D(28) +#var INT_VEC_PRIVILEGE_VIOLATION D(32) +#var INT_VEC_TRACE D(36) +#var INT_VEC_LINE_1010 D(40) +#var INT_VEC_LINE_1111 D(44) +#var INT_VEC_UNINITIALIZED_INT D(60) +#var INT_VEC_SPURIOUS_INT D(96) +#var INT_VEC_KEY_PRESS D(104) +#var INT_VEC_LINK D(112) +#var INT_VEC_ON_KEY_PRESS D(120) +#var INT_VEC_STACK_OVERFLOW D(124) +#var INT_VEC_INT_MASK D(132) +#var INT_VEC_MANUAL_RESET D(136) +#var INT_VEC_OFF D(144) +#var INT_VEC_SELF_TEST D(168) +#var INT_VEC_ARCHIVE D(172) +#var INT_VEC_ER_THROW D(188) + +#var AUTO_INT(IntNo) D(((long)(IntNo)*4+0x60)) +#var DisableAutoInt3() D((pokeIO_bclr(0x600015,2))) +#var DUMMY_HANDLER D(((INT_HANDLER)(__dummy_handler__))) +#var __dummy_handler__ void __dummy_handler__(); +#var EnableAutoInt3() D((pokeIO_bset(0x600015,2))) +#var ExecuteHandler void _(INT_HANDLER h)__ATTR_TIOS__;asm{ExecuteHandler:move.l 4(a7),a0;move.w sr,-(a7);jmp (a0)}; +#var GetIntVec(i) D((*(INT_HANDLER*)(i))) +#var SetIntVec(i,h) D(((void)(pokeIO_bclr(0x600001,2),*(INT_HANDLER*)(i)=(h),pokeIO_bset(0x600001,2)))) +#var TRAP(TrapNo) D(((long)(TrapNo)*4+0x80)) +#var DEFINE_INT_HANDLER(name) D(extern _DEREF_INT_HANDLER name[]; asm{name: move.w #0x2700,sr;movem.l d0-d7/a0-a6,-(sp);move.l 0xC8,a5;jsr __##name##_body__;movem.l (sp)+,d0-d7/a0-a6;rte}; void __##name##_body__(void)) + diff --git a/pch/src/kbd.pchsource b/pch/src/kbd.pchsource new file mode 100644 index 0000000..881c7ac --- /dev/null +++ b/pch/src/kbd.pchsource @@ -0,0 +1,66 @@ +#var __keytest(row,col) D((!!(_rowread_inverted(1<<(row))&(1<<(col))))) + +#var __keytest_optimized(row,col) D((!!((__current_row==row?__current_rowread_result:(__current_row=row,__current_rowread_result=_rowread_inverted(1<<(row))))&(1<<(col))))) + + +#var NULL D(((void*)0)) +#var ARROW_UP D(1) +#var ARROW_LEFT D(2) +#var ARROW_DOWN D(3) +#var ARROW_RIGHT D(4) + +#var FALSE D(0) +#var TRUE D(1) + +#var KEY_F1 D(268) +#var KEY_F2 D(269) +#var KEY_F3 D(270) +#var KEY_F4 D(271) +#var KEY_F5 D(272) +#var KEY_F6 D(273) +#var KEY_F7 D(274) +#var KEY_F8 D(275) +#var KEY_ESC D(264) +#var KEY_QUIT D(4360) +#var KEY_APPS D(265) +#var KEY_SWITCH D(4361) +#var KEY_MODE D(266) +#var KEY_BACKSPACE D(257) +#var KEY_INS D(4353) +#var KEY_CLEAR D(263) +#var KEY_VARLNK D(4141) +#var KEY_CHAR D(4139) +#var KEY_ENTER D(13) +#var KEY_ENTRY D(4109) +#var KEY_STO D(258) +#var KEY_RCL D(4354) +#var KEY_SIGN D(173) +#var KEY_MATH D(4149) +#var KEY_MEM D(4150) +#var KEY_ON D(267) +#var KEY_OFF D(4363) + +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var STAT_2ND D(1) +#var STAT_DIAMOND D(2) +#var STAT_SHIFT D(3) +#var STAT_HAND D(4) + +#var OSFastArrows D((*(AMS_1xx?((unsigned char*)(unsigned long)(*((unsigned short*)(_rom_call_addr(51))+0x80))):((unsigned char*)(_rom_call_addr(15C)))))) +#var _keytest(rowcol...) D((__keytest(rowcol))) +#var _keytest_optimized(rowcol...) D((__keytest_optimized(rowcol))) +#var _rowread unsigned short _rowread(short)__ATTR_LIB_ASM__; +#var _rowread_internal(row) D((~(_rowread(row)))) +#var _rowread_inverted(row) D((_rowread(~((short)(row))))) +#var GKeyDown D(_rom_call(short,(void),17F)) +#var GKeyFlush D(_rom_call(void,(void),180)) +#var GKeyIn D(_rom_call(short,(SCR_RECT*,short),17E)) +#var kbhit D(_rom_call(short,(void),52)) +#var ngetchx D(_rom_call(short,(void),51)) +#var OSGetStatKeys D(_rom_call(short,(void),299)) +#var OSInitBetweenKeyDelay(rate) D(({short __oldRate=_OSInitBetweenKeyDelay(48);(__oldRate*48-1)/_OSInitBetweenKeyDelay((rate))+1;})) +#var _OSInitBetweenKeyDelay D(_rom_call(short,(short),249)) +#var OSInitKeyInitDelay D(_rom_call(short,(short),248)) +#var pushkey D(_rom_call(void,(short),50)) +#var BEGIN_KEYTEST D({register short __current_row=RR_NO_KEY;register unsigned short __current_rowread_result=0;) +#var END_KEYTEST D(}) diff --git a/pch/src/keywords.pchsource b/pch/src/keywords.pchsource new file mode 100644 index 0000000..599c33f --- /dev/null +++ b/pch/src/keywords.pchsource @@ -0,0 +1,42 @@ +#var #define +#var #undef +#var #macro +#var #endm +#var #include +#var #pragma +#var #pragma.lang +#var #if +#var #ifndef +#var #ifdef +#var #endif +#var #elif +#var #else +#var defined +#var void +#var short +#var int +#var char +#var long +#var unsigned +#var const +#var extern +#var volatile +#var static +#var struct +#var union +#var asm +#var incbin +#var sizeof +#var typedef +#var typedef.struct +#var return +#var break +#var continue +#var goto +#var case +#var default +#var switch +#var __attribute__ +#var regparm +#var stkparm +#var alloca diff --git a/pch/src/lex.txt b/pch/src/lex.txt new file mode 100644 index 0000000..7b555fc --- /dev/null +++ b/pch/src/lex.txt @@ -0,0 +1,74 @@ + *) +*) +*, +int x +int y +int z +int a +int b +int c +register +unsigned +signed +volatile +void _( +int _( +short _( +BOOL _( +long _( + *_( +*_( +const +void,( +char,( +int,( +short,( +long,( +float,( +void +char +int +short +long +float +typedef struct +typedef +Gray +_RR( +,15 +,( +), +({ +}) +_rom_call( +_rom_call_addr( +FILE* +__ATTR_LIB_ASM__ +__ATTR_LIB_C__ +__ATTR_TIOS__ +__ATTR_ + __ +__ + * +0x +0xFFF +CALCULATOR +SCR_RECT +WIN_RECT +@@move +move +.l +.w +.b +999 +_rowread +__gray_ +HANDLE +HSym +SYM_ENTRY +SYM_STR +ESI +c>= +c<= +c== +addr \ No newline at end of file diff --git a/pch/src/limits.pchsource b/pch/src/limits.pchsource new file mode 100644 index 0000000..1989d3f --- /dev/null +++ b/pch/src/limits.pchsource @@ -0,0 +1,18 @@ +#var CHAR_MAX D(255) +#var CHAR_MIN D(0) + +#var INT_MAX D(0x7FFF) +#var INT_MIN D(((int)0x8000)) +#var UINT_MAX D(0xFFFFU) + +#var CHAR_BIT D(8) +#var LONG_MAX D(0x7FFFFFFFL) +#var LONG_MIN D(((long)0x80000000L)) +#var SCHAR_MAX D(127) +#var SCHAR_MIN D((-128)) +#var SHRT_MAX D(0x7FFF) +#var SHRT_MIN D(((short)0x8000)) +#var UCHAR_MAX D(255) +#var ULONG_MAX D(0xFFFFFFFFUL) +#var USHRT_MAX D(0xFFFFU) + diff --git a/pch/src/link.pchsource b/pch/src/link.pchsource new file mode 100644 index 0000000..e427943 --- /dev/null +++ b/pch/src/link.pchsource @@ -0,0 +1,36 @@ + +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var ESI typedef ESQ*ESI; +#var LIO_CTX typedef struct{unsigned short hVar;union{const void*pVar;struct{unsigned short FindFlags;unsigned short NameSym;}DirVars;}extra;const char*VarName;unsigned short VarSize;unsigned short Index;unsigned short Unknown;unsigned char VarType;unsigned char VarCompat;}LIO_CTX; +#var size_t typedef unsigned long size_t; +#var SYM_STR typedef CESI SYM_STR; +#var flush_link D(_rom_call(void,(void),24D)) +#var getcalc D(_rom_call(void,(SYM_STR),54)) +#var LIO_Get D(_rom_call(unsigned short,(LIO_CTX*),57)) +#var LIO_GetMultiple D(_rom_call(short,(LIO_CTX*),59)) +#var LIO_Receive D(_rom_call(unsigned short,(LIO_CTX*,short,short),58)) +#var LIO_RecvData D(_rom_call(unsigned short,(void*,long,long),5B)) +#var LIO_Send D(_rom_call(unsigned short,(LIO_CTX*,short),56)) +#var LIO_SendData D(_rom_call(unsigned short,(const void*,long),5A)) +#var LIO_SendProduct D(_rom_call(unsigned short,(LIO_CTX*,short),253)) +#var OSCheckSilentLink D(_rom_call(short,(void),24A)) +#var OSLinkClose D(_rom_call(void,(void),24E)) +#var OSLinkCmd D(_rom_call(void,(short),24B)) +#var OSLinkOpen D(_rom_call(void,(void),24D)) +#var OSLinkReset D(_rom_call(void,(void),24C)) +#var OSLinkTxQueueActive D(_rom_call(short,(void),252)) +#var OSLinkTxQueueInquire D(_rom_call(unsigned short,(void),251)) +#var OSReadLinkBlock D(_rom_call(unsigned short,(char*,short),24F)) +#var OSWriteLinkBlock D(_rom_call(short,(const char*,short),250)) +#var receive D(_rom_call(unsigned short,(char*,short),24F)) +#var reset_link D(_rom_call(void,(void),24C)) +#var sendcalc D(_rom_call(unsigned short,(SYM_STR,short,short,unsigned char*),55)) +#var transmit D(_rom_call(short,(const char*,short),250)) +#var tx_free D(_rom_call(unsigned short,(void),252)) + + diff --git a/pch/src/math.pchsource b/pch/src/math.pchsource new file mode 100644 index 0000000..d015b9b --- /dev/null +++ b/pch/src/math.pchsource @@ -0,0 +1,67 @@ + +#var HALF_PI D((1.570796326794897)) +#var NAN D((*(float*)&(bcd){0x7FFF,0xAA00000000000000})) +#var NEGATIVE_INF D((*(float*)&(bcd){0xFFFF,0xAA00BB0000000000})) +#var NEGATIVE_ZERO D((*(float*)&(bcd){0x8000,0})) +#var PI D((3.141592653589793)) +#var POSITIVE_INF D((*(float*)&(bcd){0x7FFF,0xAA00BB0000000000})) +#var POSITIVE_ZERO D((*(float*)&(bcd){0,0})) +#var UNSIGNED_INF D((*(float*)&(bcd){0x7FFF,0xAA00CC0000000000})) +#var UNSIGNED_ZERO D((0.0)) +#var ZERO D((0.0)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var FALSE D(0) +#var TRUE D(1) + +#var abs(x) D(({typeof(x) __x = (x); __x >= 0 ? __x : -__x;})) +#var acos(x) D(_tios_float_1(F5,x,float)) +#var acosh(x) D(_tios_float_1(288,x,float)) +#var asin(x) D(_tios_float_1(F6,x,float)) +#var asinh(x) D(_tios_float_1(287,x,float)) +#var atan2(x,y) D(_tios_float_2(F8,x,y,float,float)) +#var atan(x) D(_tios_float_1(F7,x,float)) +#var atanh(x) D(_tios_float_1(289,x,float)) +#var cacos D(_rom_call(void,(float,float,float*,float*),13A)) +#var cacosh D(_rom_call(void,(float,float,float*,float*),13D)) +#var casin D(_rom_call(void,(float,float,float*,float*),13B)) +#var casinh D(_rom_call(void,(float,float,float*,float*),13E)) +#var catan D(_rom_call(void,(float,float,float*,float*),13C)) +#var catanh D(_rom_call(void,(float,float,float*,float*),13F)) +#var ccos D(_rom_call(void,(float,float,float*,float*),140)) +#var ccosh D(_rom_call(void,(float,float,float*,float*),143)) +#var ceil(x) D(_tios_float_1(105,x,float)) +#var cexp D(_rom_call(void,(float,float,float*,float*),149)) +#var cln D(_rom_call(void,(float,float,float*,float*),147)) +#var clog10 D(_rom_call(void,(float,float,float*,float*),148)) +#var cos(x) D(_tios_float_1(F9,x,float)) +#var cosh(x) D(_tios_float_1(FC,x,float)) +#var csin D(_rom_call(void,(float,float,float*,float*),141)) +#var csinh D(_rom_call(void,(float,float,float*,float*),144)) +#var csqrt D(_rom_call(void,(float,float,float*,float*),146)) +#var ctan D(_rom_call(void,(float,float,float*,float*),142)) +#var ctanh D(_rom_call(void,(float,float,float*,float*),145)) +#var exp(x) D(_tios_float_1(FF,x,float)) +#var fabs(x) D(_tios_float_1(106,x,float)) +#var floor(x) D(_tios_float_1(107,x,float)) +#var fmod(x,y) D(_tios_float_2(108,x,y,float,float)) +#var hypot(x,y) D(({float __x=(x),__y=(y);sqrt(fadd(fmul((__x),(__x)),fmul((__y),(__y))));})) +#var ldexp10(x,e) D(({float __f=x;((bcd*)&__f)->exponent+=e;__f;})) +#var log(x) D(_tios_float_1(100,x,float)) +#var log10(x) D(_tios_float_1(101,x,float)) +#var modf(x,y) D(_tios_float_2(102,x,y,float,float*)) +#var pow(x,y) D(_tios_float_2(103,x,y,float,float)) +#var sin(x) D(_tios_float_1(FA,x,float)) +#var sinh(x) D(_tios_float_1(FD,x,float)) +#var sqrt(x) D(_tios_float_1(104,x,float)) +#var tan(x) D(_tios_float_1(FB,x,float)) +#var tanh(x) D(_tios_float_1(FE,x,float)) +#var atof float atof(const char*)__ATTR_LIB_ASM__; +#var frexp10(x,y) D(_tios_float_2(2FB,x,y,float,__pshort)) +#var is_inf D(_rom_call(short,(float),2FF)) +#var is_nan D(_rom_call(short,(float),306)) +#var is_nzero D(_rom_call(short,(float),300)) +#var is_pzero D(_rom_call(short,(float),301)) +#var is_sinf D(_rom_call(short,(float),302)) +#var is_transfinite D(_rom_call(short,(float),303)) +#var is_uinf_or_nan D(_rom_call(short,(float),304)) +#var is_uzero D(_rom_call(short,(float),305)) diff --git a/pch/src/mem.pchsource b/pch/src/mem.pchsource new file mode 100644 index 0000000..ce6a5dd --- /dev/null +++ b/pch/src/mem.pchsource @@ -0,0 +1,9 @@ + +#var NULL D(((void*)0)) +#var size_t typedef unsigned long size_t; +#var _memset D(_rom_call(void*,(void*,short,long),27B)) +#var memchr D(_rom_call(void*,(const void*,short,long),273)) +#var memcmp D(_rom_call(short,(const void*,const void*,long),270)) +#var memcpy D(_rom_call(void*,(void*,const void*,long),26A)) +#var memmove D(_rom_call(void*,(void*,const void*,long),26B)) +#var memset D(_rom_call(void*,(void*,short,long),27C)) diff --git a/pch/src/menus.pchsource b/pch/src/menus.pchsource new file mode 100644 index 0000000..ac39eba --- /dev/null +++ b/pch/src/menus.pchsource @@ -0,0 +1,105 @@ +#var CENTER D((-1)) +#var H_NULL D(0) +#var NULL D(((void*)0)) +#var BITMAP typedef struct{unsigned short NumRows,NumCols;unsigned char Data[];}BITMAP; +#var FALSE D(0) +#var TRUE D(1) + +#var KEY_F1 D(268) +#var KEY_F2 D(269) +#var KEY_F3 D(270) +#var KEY_F4 D(271) +#var KEY_F5 D(272) +#var KEY_F6 D(273) +#var KEY_F7 D(274) +#var KEY_F8 D(275) +#var KEY_ESC D(264) +#var KEY_QUIT D(4360) +#var KEY_APPS D(265) +#var KEY_SWITCH D(4361) +#var KEY_MODE D(266) +#var KEY_BACKSPACE D(257) +#var KEY_INS D(4353) +#var KEY_CLEAR D(263) +#var KEY_VARLNK D(4141) +#var KEY_CHAR D(4139) +#var KEY_ENTER D(13) +#var KEY_ENTRY D(4109) +#var KEY_STO D(258) +#var KEY_RCL D(4354) +#var KEY_SIGN D(173) +#var KEY_MATH D(4149) +#var KEY_MEM D(4150) +#var KEY_ON D(267) +#var KEY_OFF D(4363) + +#var DMF_TEXT D(1) +#var DMF_ICON D(2) +#var DMF_BITMAP D(4) +#var DMF_CHILD_SUB D(4096) +#var DMF_CHILD D(8192) +#var DMF_TOP_SUB D(16384) +#var DMF_TOP D(-32768) + +#var HANDLE typedef unsigned short HANDLE; +#var ICON typedef struct{unsigned short i[16];}ICON; +#var MT_TEXT D(-32768) +#var MT_XREF D(-28672) +#var MT_ICON D(-24576) +#var MT_CASCADE D(16384) + +#var MBF_WITHICON D(1) +#var MBF_REDEF D(2) +#var MBF_SYS_ALLOC D(4) +#var MBF_MAX_MENU_WIDTH D(8) +#var MBF_STRIKEOUT D(16) +#var MBF_HMENU D(32) +#var MBF_NO_DRAWTOP D(64) + +#var MC_CHECK D(0) +#var MC_UNCHECK D(1) +#var MC_STATUS D(2) +#var MC_FLIP D(3) + +#var MF_POPUP D(1) +#var MF_TOOLBOX D(2) +#var MF_NONSEQ D(4) +#var MF_ICON_TITLE D(8) +#var MF_TEXT_TITLE D(16) +#var MF_NO_NUMS D(32) +#var MF_NO_UNAMED D(64) +#var MF_DYN_POPUP D(128) +#var MF_ALT_ICONS D(256) +#var MF_BITMAP_TITLE D(512) +#var MF_ERROR D(2048) +#var MF_ICONS_OVERLAP D(4096) +#var MF_TITLE D(536) + +#var M_NOITEM D(0) +#var M_NOTMENUKEY D(-2) + +#var pICON typedef unsigned short*pICON; +#var VCFP_ALL D(1) +#var VCFP_SKIP_CURDIR D(2) + +#var MenuAddIcon D(_rom_call(HANDLE,(HANDLE,short,const void*,short,short),42)) +#var MenuAddText D(_rom_call(HANDLE,(HANDLE,short,const char*,short,short),41)) +#var MenuBegin D(_rom_call(HANDLE,(const void*,short,short,short,...),36)) +#var MenuCheck D(_rom_call(short,(HANDLE,short,short),37)) +#var MenuEnd D(_rom_call(void,(HANDLE),38)) +#var MenuGetTopRedef D(_rom_call(short,(HANDLE,short),40)) +#var MenuKey D(_rom_call(short,(HANDLE,short),39)) +#var MenuNew D(_rom_call(HANDLE,(short,short,short),43)) +#var MenuOn D(_rom_call(void,(HANDLE),3A)) +#var MenuPopup D(_rom_call(unsigned short,(const void*,short,short,short),3B)) +#var MenuSubStat D(_rom_call(void,(HANDLE,short,short),3C)) +#var MenuTopRedef D(_rom_call(void,(HANDLE,short,short),3F)) +#var MenuTopSelect D(_rom_call(void,(HANDLE,short),3E)) +#var MenuTopStat D(_rom_call(void,(HANDLE,short,short),3D)) +#var MenuUpdate D(_rom_call(void,(void),49)) +#var PopupAddText D(_rom_call(HANDLE,(HANDLE,short,const char*,short),44)) +#var PopupClear D(_rom_call(HANDLE,(HANDLE),46)) +#var PopupDo D(_rom_call(short,(HANDLE,short,short,short),47)) +#var PopupNew D(_rom_call(HANDLE,(const char*,short),45)) +#var PopupText D(_rom_call(const char*,(HANDLE,short),48)) +#var VarCreateFolderPopup D(_rom_call(HANDLE,(__pushort,short),28F)) diff --git a/pch/src/pchlog.pchsource b/pch/src/pchlog.pchsource new file mode 100644 index 0000000..245b297 --- /dev/null +++ b/pch/src/pchlog.pchsource @@ -0,0 +1,236 @@ +DialogAdd(h,0,x,y,3)w)g)f)t)p)u)m) +(-1) +0 +((0) +0 +1 +0 +1 +2 +3 +4 +5 +6 + + + + + + + +,,p30) +,,,,,...33) +DialogAdd(h,2,x,y,14(t()(p()(i)) +DialogAdd(h,0,x,y,2(t()(o()(m()(w)) +DialogAdd(h,0,x,y,7(t)) +DialogAdd(h,0,0,0,8(t()(l()(r)) +,,,p32) +,,DialogNew_t34) +DialogNew(w,h,NoCallBack) +,1B4) + +ESQ...28E) +ESQ...28C) +ESQ...28D) +(-1) +0 +((0) + +0 +1 +268 +269 +270 +271 +272 +273 +274 +275 +264 +4360 +265 +4361 +266 +257 +4353 +263 +4141 +4139 +13 +4109 +258 +4354 +173 +4149 +4150 +267 +4363 +1 +2 +4 +4096 +8192 +16384 +-32768 + + +-32768 +-28672 +-24576 +16384 +1 +2 +4 +8 +16 +32 +64 +0 +1 +2 +3 +1 +2 +4 +8 +16 +32 +64 +128 +256 +512 +2048 +4096 +536 +0 +-2 + +1 +2 +,,,42) +,,,41) +,,,...36) +,,37) +38) +,40) +,39) +,,43) +3A) +,,3B) +,,3C) +,,3F) +,3E) +,,3D) +49) +,,44) +46) +,,,47) +45) +(,48) +pu,28F) +4 +((0) +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 + +0 +1 +16 +32 +64 +128 +0 +1 +2 +3 +4 +5 +6 +0 +1 +2 + + + + + + + + + +1 +2 +4 +8 +16 +32 +64 +128 +256 +512 +1024 +2048 +4096 +8192 +16400 +-32768 +((WINDOW*const)((((0)))+1)) +(*((WINDOW*(0)))) +WINDOW,35) +WINDOW,27) +(,,,2C) +(,2A) +(,29) +WINDOW,1) +WINDOW2) +WINDOW4) +WINDOW,3) +WINDOW,5) +WINDOW,6) +WINDOW,,7) +WINDOW,8) +WINDOWA) +WINDOW,,,9) +WINDOW,B) +WINDOW,C) +WINDOW,D) +WINDOWE) +WINDOW,,,F) +(()0) +WINDOW10) +WINDOW11) +WINDOW,,,,,,12) +WINDOW13) +WINDOWp,p14) +WINDOW,292) +WINDOW) +WINDOW,16) +WINDOW,17) +WINDOW,18) +WINDOW,1A) +WINDOW,19) +WINDOW,1B) +WINDOW,1D) +WINDOW,1C) +WINDOW,...1E) +WINDOW,1F) +WINDOW,20) +WINDOW21) +WINDOW,...22) +WINDOW23) +WINDOW24) +()((w)->CursorX=xw)->CursorY=y) +()((w)->Flags|=WF_VISIBLE) +WINDOW,25) +WINDOW,,,26) +WINDOW,291) diff --git a/pch/src/peekpoke.pchsource b/pch/src/peekpoke.pchsource new file mode 100644 index 0000000..5862830 --- /dev/null +++ b/pch/src/peekpoke.pchsource @@ -0,0 +1,21 @@ + +#var peek(addr) D((*((unsigned char*)(long)(addr)))) +#var peek_bit(addr,bit) D((!!(*((unsigned char*)(long)(addr))&(1<<(bit))))) +#var peek_l(addr) D((*((unsigned long*)(long)(addr)))) +#var peek_w(addr) D((*((unsigned short*)(long)(addr)))) +#var peekIO(port) D((*((volatile unsigned char*)(long)(port)))) +#var peekIO_bit(port,bit) D((!!(*((volatile unsigned char*)(long)(port))&(1<<(bit))))) +#var peekIO_w(port) D((*((volatile unsigned short*)(long)(port)))) +#var poke(addr,val) D((void)(*((unsigned char*)(long)(addr))=(val))) +#var poke_bclr(addr,bit) D((void)(*(unsigned char *)(addr)&=~(1<<(bit)))) +#var poke_bset(addr,bit) D((void)(*(unsigned char *)(addr)|=(1<<(bit)))) +#var poke_l(addr,val) D((void)(*((unsigned long*)(long)(addr))=(val))) +#var poke_w(addr,val) D((void)(*((unsigned short*)(long)(addr))=(val))) +#var pokeIO(port,val) D((void)(*((volatile unsigned char*)(long)(port))=(val))) +#var pokeIO_bclr(addr,bit) D((void)(*(volatile unsigned char *)(addr)&=~(1<<(bit)))) +#var pokeIO_bset(addr,bit) D((void)(*(volatile unsigned char *)(addr)|=(1<<(bit)))) +#var pokeIO_w(port,val) D((void)(*((volatile unsigned short*)(long)(port))=(val))) +#var speek(addr) D((*((signed char*)(long)(addr)))) +#var speek_l(addr) D((*((signed long*)(long)(addr)))) +#var speek_w(addr) D((*((signed short*)(long)(addr)))) + diff --git a/pch/src/rsa.pchsource b/pch/src/rsa.pchsource new file mode 100644 index 0000000..fa18da9 --- /dev/null +++ b/pch/src/rsa.pchsource @@ -0,0 +1,12 @@ + +#var BN typedef struct{unsigned char Len;unsigned char Data[];}BN; +#var MD5_CTX typedef struct{unsigned long state[4];unsigned long count[2];unsigned char buffer[64];}MD5_CTX; +#var BN_power17Mod D(_rom_call(void,(BN*,const BN*,const BN*),122)) +#var BN_powerMod D(_rom_call(void,(BN*,const BN*,const BN*,const BN*),123)) +#var BN_prodMod D(_rom_call(void,(BN*,const BN*,const BN*),124)) +#var cdecrypt D(_rom_call(void,(BN*,char*,long,BN*),127)) +#var MD5Done D(_rom_call(void,(BN*,MD5_CTX*),257)) +#var MD5Final D(_rom_call(void,(unsigned char*,MD5_CTX*),256)) +#var MD5Init D(_rom_call(void,(MD5_CTX*),254)) +#var MD5Update D(_rom_call(void,(MD5_CTX*,unsigned char*,short),255)) + diff --git a/pch/src/setjmp.pchsource b/pch/src/setjmp.pchsource new file mode 100644 index 0000000..729d08d --- /dev/null +++ b/pch/src/setjmp.pchsource @@ -0,0 +1,5 @@ + +#var JMP_BUF typedef struct{unsigned long D2,D3,D4,D5,D6,D7;unsigned long A2,A3,A4,A5,A6,A7;unsigned long PC;}JMP_BUF[1]; +#var longjmp D(_rom_call(void,(void*,short),267)) +#var setjmp D(_rom_call(short,(void*),266)) +#var jmp_buf D(JMP_BUF) diff --git a/pch/src/sprites.pchsource b/pch/src/sprites.pchsource new file mode 100644 index 0000000..fee6b53 --- /dev/null +++ b/pch/src/sprites.pchsource @@ -0,0 +1,9 @@ + +#var SPRT_XOR D(0) +#var SPRT_OR D(1) +#var SPRT_AND D(2) + +#var Sprite8 void Sprite8(short,short,short,unsigned char*,void*,short)__ATTR_LIB_C__; +#var Sprite16 void Sprite16(short,short,short,__pushort,void*,short)__ATTR_LIB_C__; +#var Sprite32 void Sprite32(short,short,short,__pulong,void*,short)__ATTR_LIB_C__; + diff --git a/pch/src/statline-vle.pchsource b/pch/src/statline-vle.pchsource new file mode 100644 index 0000000..6a54fde --- /dev/null +++ b/pch/src/statline-vle.pchsource @@ -0,0 +1,15 @@ + +#var FALSE D(0) +#var TRUE D(1) + +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; + +#var WIN_RECT typedef struct{short x0,y0,x1,y1;}WIN_RECT; +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var ST_busy D(_rom_call(void,(short),E2)) +#var ST_eraseHelp D(_rom_call(short,(void),E3)) +#var ST_folder D(_rom_call(void,(const char*),E4)) +#var ST_helpMsg D(_rom_call(void,(const char*),E6)) +#var ST_refDsp D(_rom_call(void,(short),EB)) +#var ST_showHelp D(_rom_call(void,(const char*),E6)) diff --git a/pch/src/statline.pchsource b/pch/src/statline.pchsource new file mode 100644 index 0000000..8cba281 --- /dev/null +++ b/pch/src/statline.pchsource @@ -0,0 +1,56 @@ + +#var FALSE D(0) +#var TRUE D(1) + +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var ACTIVITY_IDLE D(0) +#var ACTIVITY_BUSY D(1) +#var ACTIVITY_PAUSED D(2) +#var ACTIVITY_NORMAL D(3) + +#var ST_IDLE D(0) +#var ST_BUSY D(1) +#var ST_PAUSE D(2) +#var ST_CLEAR D(3) +#var ST_NORMAL D(3) +#var ST_NOTHING D(0) +#var ST_BATT D(1) +#var ST_BATT_DARK D(2) +#var ST_BATT_OK D(0) +#var ST_BATT_LOW D(1) +#var ST_BATT_REPLACE D(2) +#var ST_RAD D(0) +#var ST_DEG D(1) +#var ST_FUNC D(0) +#var ST_PAR D(2) +#var ST_POL D(3) +#var ST_SEQ D(4) +#var ST_3D D(5) +#var ST_DE D(6) +#var ST_NONE D(0) +#var ST_2ND D(1) +#var ST_SHIFT D(2) +#var ST_DIAMOND D(4) +#var ST_ALPHA D(8) +#var ST_SH_A_LOCK D(16) +#var ST_A_LOCK D(32) +#var ST_AUTO D(0) +#var ST_EXACT D(1) +#var ST_APPROX D(2) + +#var WIN_RECT typedef struct{short x0,y0,x1,y1;}WIN_RECT; +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var ST_angle D(_rom_call(void,(short),E0)) +#var ST_batt D(_rom_call(void,(short),E1)) +#var ST_busy D(_rom_call(void,(short),E2)) +#var ST_eraseHelp D(_rom_call(short,(void),E3)) +#var ST_folder D(_rom_call(void,(const char*),E4)) +#var ST_graph D(_rom_call(void,(short),E5)) +#var ST_helpMsg D(_rom_call(void,(const char*),E6)) +#var ST_modKey D(_rom_call(void,(short),E7)) +#var ST_precision D(_rom_call(void,(short),E8)) +#var ST_readOnly D(_rom_call(void,(short),E9)) +#var ST_refDsp D(_rom_call(void,(short),EB)) +#var ST_showHelp D(_rom_call(void,(const char*),E6)) +#var ST_stack D(_rom_call(void,(short,short),EA)) diff --git a/pch/src/stdarg.pchsource b/pch/src/stdarg.pchsource new file mode 100644 index 0000000..d5ba350 --- /dev/null +++ b/pch/src/stdarg.pchsource @@ -0,0 +1,6 @@ + +#var va_list typedef void*va_list; +#var va_arg(ap,type) D((*(type*)(((*(char**)&(ap))+=((sizeof(type)+1)&0xFFFE))-(((sizeof(type)+1)&0xFFFE))))) +#var va_end(ap) D(((void)0)) +#var va_start(ap,parmN) D(((void)((ap)=(va_list)((char*)(&parmN)+((sizeof(parmN)+1)&0xFFFE))))) + diff --git a/pch/src/stdhead-ams2.pchmerge b/pch/src/stdhead-ams2.pchmerge new file mode 100644 index 0000000..11c9cc8 --- /dev/null +++ b/pch/src/stdhead-ams2.pchmerge @@ -0,0 +1,6 @@ +ams2.pchsource + +ams2-basfunc.pchsource +ams2-basop.pchsource +ams2-kbd.pchsource +ams2-menus.pchsource diff --git a/pch/src/stdhead-light.pchmerge b/pch/src/stdhead-light.pchmerge new file mode 100644 index 0000000..f7d7935 --- /dev/null +++ b/pch/src/stdhead-light.pchmerge @@ -0,0 +1,31 @@ +stdhead.pchsource + +compiler-internals.pchsource +alloc.pchsource +args-le.pchsource +asmtypes.pchsource +assert.pchsource +compat-x.pchsource +ctype.pchsource +error-le.pchsource +flash.pchsource +float.pchsource +graph.pchsource +gray.pchsource +intr.pchsource +kbd.pchsource +limits.pchsource +link.pchsource +mem.pchsource +peekpoke.pchsource +setjmp.pchsource +sprites.pchsource +statline-vle.pchsource +stdarg.pchsource +stdio.pchsource +stdlib.pchsource +string.pchsource +system.pchsource +values.pchsource +vat-le.pchsource +version.pchsource diff --git a/pch/src/stdhead.pchmerge b/pch/src/stdhead.pchmerge new file mode 100644 index 0000000..6435eb6 --- /dev/null +++ b/pch/src/stdhead.pchmerge @@ -0,0 +1,41 @@ +stdhead.pchsource + +compiler-internals.pchsource +gtc.pchsource +alloc.pchsource +args-le.pchsource +asmtypes.pchsource +assert.pchsource +cert.pchsource +compat-x.pchsource +ctype.pchsource +dialogs.pchsource +dll.pchsource +error-le.pchsource +events.pchsource +flash.pchsource +float.pchsource +gdraw.pchsource +graph.pchsource +gray.pchsource +homescr.pchsource +intr.pchsource +kbd.pchsource +limits.pchsource +link.pchsource +mem.pchsource +peekpoke.pchsource +rsa.pchsource +setjmp.pchsource +sprites.pchsource +statline.pchsource +stdarg.pchsource +stdio.pchsource +stdlib.pchsource +string.pchsource +system.pchsource +textedit.pchsource +values.pchsource +vat-le.pchsource +version.pchsource +wingraph.pchsource diff --git a/pch/src/stdio.pchsource b/pch/src/stdio.pchsource new file mode 100644 index 0000000..7fbbe7f --- /dev/null +++ b/pch/src/stdio.pchsource @@ -0,0 +1,69 @@ +#var vcbprintf_callback_t typedef void(*vcbprintf_callback_t)(char,void**)__ATTR_TIOS_CALLBACK__; +#var __vcbprintf__type__ typedef void(*__vcbprintf__type__)(vcbprintf_callback_t,void**,const char*,void*)__ATTR_TIOS__; + + +#var EOF D((-1)) +#var NULL D(((void*)0)) +#var TMP_MAX D(152587890625) +#var FILE typedef struct{char*fpos;void*base;unsigned short handle;short flags;short unget;unsigned long alloc;unsigned short buffincrement;}FILE; +#var _F_READ D(1) +#var _F_WRIT D(2) +#var _F_RDWR D(3) +#var _F_ERR D(16) +#var _F_EOF D(32) +#var _F_BIN D(64) + +#var fpos_t typedef unsigned long fpos_t; +#var SEEK_SET D(0) +#var SEEK_CUR D(1) +#var SEEK_END D(2) + +#var size_t typedef unsigned long size_t; +#var va_list typedef void*va_list; +#var vcbprintf_Callback_t D(vcbprintf_callback_t) +#var clearerr(f) D(((void)(((f)->flags)&=~(_F_EOF|_F_ERR)))) +#var clrscr void clrscr(void)__ATTR_LIB_ASM__; +#var fclose short fclose(FILE*)__ATTR_LIB_C__; +#var feof(f) D((((f)->flags)&_F_EOF)) +#var ferror(f) D((((f)->flags)&_F_ERR)) +#var fflush(f) D(((f)->unget=0)) +#var fgetc short fgetc(FILE*)__ATTR_LIB_C__; +#var fgetchar() D(({register short __c=_rom_call(short,(void),51)();fputchar((__c=='\r')?'\n':__c);})) +#var fgetpos(f,p) D(((*(p)=ftell(f))==EOF)) +#var fgets char *fgets(char*,short,FILE*)__ATTR_LIB_C__; +#var fopen FILE *fopen(const char*,const char*)__ATTR_LIB_C__; +#var fprintf short fprintf(FILE*,const char*,...)__ATTR_TIOS__; +#var fputc short fputc(short,FILE*)__ATTR_TIOS_CALLBACK__; +#var fputchar short fputchar(short)__ATTR_TIOS_CALLBACK__; +#var fputs short fputs(const char*,FILE*)__ATTR_LIB_ASM__; +#var fread unsigned short fread(void*,short,short,FILE*)__ATTR_LIB_C__; +#var freopen(n,m,f) D((fclose(f),(f)=fopen((n),(m)),(f))) +#var fseek short fseek(FILE*,long,short)__ATTR_LIB_C__; +#var fsetbufsize void fsetbufsize(short,FILE*)__ATTR_LIB_C__; +#var fsetpos(f,p) D(fseek((f),*(p),SEEK_SET)) +#var ftell long ftell(const FILE*)__ATTR_LIB_C__; +#var fwrite unsigned short fwrite(const void*,short,short,FILE*)__ATTR_LIB_C__; +#var getc D(fgetc) +#var getchar D(fgetchar) +#var gets(s) D(({register short __c;register char*__p=s;while((*__p++=fputchar(((__c=_rom_call(short,(void),51)())=='\r')?'\n':__c))!='\n');__p[-1]=0;s;})) +#var printf void printf(const char*,...)__ATTR_TIOS__; +#var printf_xy(x,y,f...) D(({char __s[200];_rom_call(short,(char*,const char*,...),53)(__s ,##f);_rom_call(void,(short,short,const char*,short),1A9)(x,y,__s,4);})) +#var putc D(fputc) +#var putchar D(fputchar) +#var puts void puts(const char*)__ATTR_LIB_ASM__; +#var remove D(unlink) +#var rename short rename(const char*,const char*)__ATTR_LIB_C__; +#var rewind(f) D(((void)(fseek((f),0,SEEK_SET),(f)->flags&=~_F_ERR))) +#var sprintf D(_rom_call(short,(char*,const char*,...),53)) +#var strerror D(_rom_call(char*,(short),27D)) +#var strputchar void strputchar(char,void**)__ATTR_TIOS_CALLBACK__; +#var tmpnam char *tmpnam(char*)__ATTR_LIB_C__; +#var ungetc(c,f) D(((f)->unget=((c)|0x8000))) +#var unlink short unlink(const char*)__ATTR_LIB_C__; +#var vcbprintf D(({register long __a=32+(long)(_rom_call_addr(53));(__vcbprintf__type__)(__a+*(short*)__a);})) +#var vfprintf(s,f,a) D(vcbprintf((vcbprintf_callback_t)fputc,(void**)(s),(f),(a))) +#var vprintf(f,a) D(vcbprintf((vcbprintf_callback_t)fputchar,NULL,(f),(a))) +#var vsprintf(b,f,a) D(((void)({void*__p=(b);vcbprintf((vcbprintf_callback_t)strputchar,&__p,(f),(a));*(char*)__p=0;}))) + + +#var __FERROR(f) D(({(f)->flags|=_F_ERR; return EOF;})) diff --git a/pch/src/stdlib.pchsource b/pch/src/stdlib.pchsource new file mode 100644 index 0000000..a162bc6 --- /dev/null +++ b/pch/src/stdlib.pchsource @@ -0,0 +1,35 @@ +#var ldiv(n,d) D(({ldiv_t __r;long __n=(n),__d=(d);asm("move.l 0xC8,%%a5;move.l %2,%%d1;move.l %3,%%d0;move.l (%%a5,2720),%%a0;jsr (%%a0);move.l %%d1,%0;move.l %2,%%d1;move.l %3,%%d0;move.l (%%a5,2724),%%a0;jsr (%%a0);move.l %%d1,%1" : "=g"(__r.quot),"=g"(__r.rem) : "g"(__n),"g"(__d) : "a0","a1","a5","d0","d1","d2");__r;})) + +#var NULL D(((void*)0)) +#var RAND_MAX D(32767) +#var atexit_t typedef CALLBACK void(*atexit_t)(void); +#var compare_t typedef CALLBACK short(*compare_t)(const void*elem1,const void*elem2); +#var div_t typedef struct{short quot,rem;}div_t; +#var ldiv_t typedef struct{long quot,rem;}ldiv_t; +#var size_t typedef unsigned long size_t; +#var abort() D((_rom_call(void,(const char*),E6)("ABNORMAL PROGRAM TERMINATION"),exit(0))) +#var abs(x) D(({typeof(x) __x = (x); __x >= 0 ? __x : -__x;})) +#var atexit short atexit(atexit_t)__ATTR_LIB_ASM__; +#var atoi short atoi(const char*)__ATTR_LIB_C__; +#var atol long atol(const char*)__ATTR_LIB_C__; +#var bsearch void *bsearch(const void*,const void*,short,short,compare_t)__ATTR_LIB_C__; +#var calloc void *calloc(short,short)__ATTR_LIB_ASM__; +#var div(n,d) D(({short __n=(n),__d=(d);div_t __r;__r.quot=__n/__d;__r.rem=__n%__d;__r;})) +#var exit(n) D(({(n)?_rom_call(void,(short),152)(n):0;__exit();})) +#var __exit volatile void __exit(void)__ATTR_LIB_ASM_NORETURN__; +#var fabs(x) D(_tios_float_1(106,x,float)) +#var free D(_rom_call(void,(void*),A3)) +#var malloc D(_rom_call(void*,(long),A2)) +#var max(a,b) D(({typeof(a) __a = (a); typeof(b) __b = (b); (__a > __b) ? __a : __b;})) +#var min(a,b) D(({typeof(a) __a = (a); typeof(b) __b = (b); (__a < __b) ? __a : __b;})) +#var qsort void qsort(void*,short,short,compare_t)__ATTR_LIB_C__; +#var rand short rand(void)__ATTR_LIB_ASM__; +#var random(x) D(((short)((long)(unsigned short)rand()*(unsigned short)(x)/32768))) +#var randomize() D(srand(*(volatile char*)0x600017)) +#var realloc void *realloc(void*,long)__ATTR_LIB_ASM__; +#var __randseed extern long __randseed; +#var srand(x) D((__randseed=(x))) +#var strtol long strtol(const char*,char**,short)__ATTR_LIB_C__; +#var strtoul unsigned long strtoul(const char*,char**,short)__ATTR_LIB_C__; +#var atof float atof(const char*)__ATTR_LIB_ASM__; + diff --git a/pch/src/string.pchsource b/pch/src/string.pchsource new file mode 100644 index 0000000..9ef95c2 --- /dev/null +++ b/pch/src/string.pchsource @@ -0,0 +1,26 @@ + +#var NULL D(((void*)0)) +#var size_t typedef unsigned long size_t; +#var _memset D(_rom_call(void*,(void*,short,long),27B)) +#var cmpstri D(_rom_call(short,(const unsigned char*,const unsigned char*),16F)) +#var memchr D(_rom_call(void*,(const void*,short,long),273)) +#var memcmp D(_rom_call(short,(const void*,const void*,long),270)) +#var memcpy D(_rom_call(void*,(void*,const void*,long),26A)) +#var memmove D(_rom_call(void*,(void*,const void*,long),26B)) +#var memset D(_rom_call(void*,(void*,short,long),27C)) +#var sprintf D(_rom_call(short,(char*,const char*,...),53)) +#var strcat D(_rom_call(char*,(char*,const char*),26E)) +#var strchr D(_rom_call(char*,(const char*,short),274)) +#var strcmp D(_rom_call(short,(const unsigned char*,const unsigned char*),271)) +#var strcpy D(_rom_call(char*,(char*,const char*),26C)) +#var strcspn D(_rom_call(unsigned long,(const char*,const char*),275)) +#var strerror D(_rom_call(char*,(short),27D)) +#var strlen D(_rom_call(unsigned long,(const char*),27E)) +#var strncat D(_rom_call(char*,(char*,const char*,long),26F)) +#var strncmp D(_rom_call(short,(const unsigned char*,const unsigned char*,long),272)) +#var strncpy D(_rom_call(char*,(char*,const char*,long),26D)) +#var strpbrk D(_rom_call(char*,(const char*,const char*),276)) +#var strrchr D(_rom_call(char*,(const char*,short),277)) +#var strspn D(_rom_call(unsigned long,(const char*,const char*),278)) +#var strstr D(_rom_call(char*,(const char*,const char*),279)) +#var strtok D(_rom_call(char*,(char*,const char*),27A)) diff --git a/pch/src/system.pchsource b/pch/src/system.pchsource new file mode 100644 index 0000000..fb76054 --- /dev/null +++ b/pch/src/system.pchsource @@ -0,0 +1,63 @@ + +#var FALSE D(0) +#var TRUE D(1) +#var Bool enum Bool {}; + +#var DEF_QUEUE typedef struct{unsigned short Head;unsigned short Tail;unsigned short Size;unsigned short Used;unsigned short Buffer[];}DEF_QUEUE; +#var HANDLE typedef unsigned short HANDLE; +#var QUEUE(n) D(struct{unsigned short Head,Tail,Size,Used,Buffer[n/2];}) +#var Timer_Callback_t typedef CALLBACK void(*Timer_Callback_t)(void); +#var BATT_TIMER D(1) +#var APD_TIMER D(2) +#var LIO_TIMER D(3) +#var CURSOR_TIMER D(4) +#var MISC_TIMER D(5) +#var USER_TIMER D(6) + +#var AB_prodid D(_rom_call(void,(char*),29D)) +#var AB_prodname D(_rom_call(void,(char*),29E)) +#var AB_serno D(_rom_call(short,(char*),29F)) +#var ASM_call(x) D(({asm volatile{movem.l d0-d7/a0-a6,-(sp)};ASM_fastcall(x);asm volatile{movem.l (sp)+,d0-d7/a0-a6};})) +#var ASM_fastcall(x) D((((void(*)())(x))())) +#var CB_fetchTEXT D(_rom_call(short,(HANDLE*,__pulong),C2)) +#var CB_replaceTEXT D(_rom_call(short,(char*,long,short),C1)) +#var CU_restore D(_rom_call(void,(short),C3)) +#var CU_start D(_rom_call(short,(void),C4)) +#var CU_stop D(_rom_call(short,(void),C5)) + +#var EX_patch D(_rom_call(void,(void*,void*),15A)) +#var HelpKeys D(_rom_call(void,(void),181)) +#var idle D(_rom_call(void,(void),29B)) +#var kbd_queue void *kbd_queue(void)__ATTR_LIB_ASM__; +#var NeedStack D(_rom_call(void,(short),A4)) +#var off D(_rom_call(void,(void),29A)) +#var OSCheckBreak D(_rom_call(short,(void),EC)) +#var OSClearBreak D(_rom_call(void,(void),ED)) +#var OSContrastDn() D(({asm{move.l d3,-(a7);move.l d4,-(a7)};_rom_call(void,(void),297) ();asm{move.l (a7)+,d4;move.l (a7)+,d3};})) +#var OSContrastUp() D(({asm{move.l d3,-(a7);move.l d4,-(a7)};_rom_call(void,(void),296) ();asm{move.l (a7)+,d4;move.l (a7)+,d3};})) +#var OSDisableBreak D(_rom_call(void,(void),EF)) +#var OSEnableBreak D(_rom_call(void,(void),EE)) +#var OSFreeTimer D(_rom_call(short,(short),F1)) +#var OSRegisterTimer D(_rom_call(short,(short,long),F0)) +#var OSReset D(_rom_call(void,(void),294)) +#var OSSetSR D(_rom_call(short,(short),29C)) +#var OSTimerCurVal D(_rom_call(unsigned long,(short),F2)) +#var OSTimerExpired D(_rom_call(short,(short),F3)) +#var OSTimerRestart D(_rom_call(unsigned long,(short),F4)) +#var OSVFreeTimer short OSVFreeTimer(short)__ATTR_LIB_ASM__; +#var OSVRegisterTimer short OSVRegisterTimer(short,long,Timer_Callback_t)__ATTR_LIB_ASM__; +#var QModeKey D(_rom_call(short,(short),182)) +#var QSysKey D(_rom_call(short,(short),183)) +#var SumStoChkMem D(_rom_call(short,(void),295)) +#var WordInList D(_rom_call(short,(short,__pushort),184)) +#var XR_stringPtr(strno) D((AMS_1xx?_rom_call(const char*,(short),293)(strno):_rom_call(const char*,(long),293)(strno))) +#var OSdequeue D(_rom_call(short,(__pushort,void*),3AA)) +#var OSenqueue D(_rom_call(short,(short,void*),3A9)) +#var OSqclear D(_rom_call(void,(void*),3AD)) +#var OSqhead D(_rom_call(unsigned short,(__pushort,void*),3AC)) +#var OSqinquire D(_rom_call(short,(__pushort,void*),3AB)) +#var ReleaseDate D(((const char*const)(_rom_call_addr(43F)))) +#var ReleaseVersion D(((const char*const)(_rom_call_addr(440)))) + + +#var enter_ghost_space() D(({extern unsigned long *__save__sp__;enter_ghost_space();(*__save__sp__)|=0x40000;})) void @@enter_ghost_space(void)__ATTR_LIB_ASM__; diff --git a/pch/src/textedit.pchsource b/pch/src/textedit.pchsource new file mode 100644 index 0000000..ae58a4c --- /dev/null +++ b/pch/src/textedit.pchsource @@ -0,0 +1,29 @@ + +#var FALSE D(0) +#var TRUE D(1) + +#var HANDLE typedef unsigned short HANDLE; +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var WIN_RECT typedef struct{short x0,y0,x1,y1;}WIN_RECT; +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var EVENT typedef struct EventStruct{unsigned short Type;unsigned short RunningApp;unsigned short Side;unsigned short StatusFlags;union{WINDOW*w;WIN_RECT*r;char*pasteText;HANDLE hPasteText;struct{unsigned short Mod;unsigned short Code;}Key;}extra;unsigned char StartType;}EVENT; +#var size_t typedef unsigned long size_t; +#var TEXT_EDIT typedef struct TextEditStruct{WINDOW*Parent;unsigned short ReadOnly;WIN_RECT Rect;unsigned short BufSize;unsigned short CurSize;unsigned short CursorOffset;unsigned short StartOffset;unsigned short PreChars;unsigned short CharWidth;unsigned short CharHeight;unsigned short LineNum;unsigned short CursorX;unsigned short Flags;union{HANDLE h;const char*p;}Text;}TEXT_EDIT; +#var TE_checkSlack D(_rom_call(void,(TEXT_EDIT*),A6)) +#var TE_close D(_rom_call(void,(TEXT_EDIT*),A5)) +#var TE_empty D(_rom_call(void,(TEXT_EDIT*),A7)) +#var TE_focus D(_rom_call(short,(TEXT_EDIT*),A8)) +#var TE_handleEvent D(_rom_call(short,(TEXT_EDIT*,EVENT*),A9)) +#var TE_indicateReadOnly D(_rom_call(void,(TEXT_EDIT*),AA)) +#var TE_isBlank D(_rom_call(short,(TEXT_EDIT*),AB)) +#var TE_open D(_rom_call(short,(TEXT_EDIT*,WINDOW*,WIN_RECT*,HANDLE,short,short,short),AC)) +#var TE_openFixed D(_rom_call(short,(TEXT_EDIT*,WINDOW*,WIN_RECT*,char*,short,short),AD)) +#var TE_pasteText D(_rom_call(void,(TEXT_EDIT*,const char*,long),AE)) +#var TE_reopen D(_rom_call(void,(TEXT_EDIT*,short),AF)) +#var TE_reopenPlain D(_rom_call(void,(TEXT_EDIT*,short),B0)) +#var TE_select D(_rom_call(void,(TEXT_EDIT*,short,short),B1)) +#var TE_shrinkWrap D(_rom_call(HANDLE,(TEXT_EDIT*),B2)) +#var TE_unfocus D(_rom_call(short,(TEXT_EDIT*),B3)) +#var TE_updateCommand D(_rom_call(void,(TEXT_EDIT*,char),B4)) + diff --git a/pch/src/tigcc-archive/COMPILING b/pch/src/tigcc-archive/COMPILING new file mode 100644 index 0000000..0d45516 --- /dev/null +++ b/pch/src/tigcc-archive/COMPILING @@ -0,0 +1,13 @@ +You can recompile this on a TIGCC system by patching the system +include file and replacing the line: + #define __ATTR_LIB_C__ __attribute__((__regparm__(4))) +with the lines + #ifdef REGPARM1_STDLIB + #define __ATTR_LIB_C__ __attribute__((__regparm__(1))) + #define CONFIRM_REGPARM1_ENABLED + #else + #define __ATTR_LIB_C__ __attribute__((__regparm__(4))) + #endif + +This has been tested with TIGCC 0.94SP4. Newer versions will likely require +adaptation of this source code and/or toolchain. diff --git a/pch/src/tigcc-archive/License.txt b/pch/src/tigcc-archive/License.txt new file mode 100644 index 0000000..98ae2cc --- /dev/null +++ b/pch/src/tigcc-archive/License.txt @@ -0,0 +1,27 @@ +TIGCC Library Routines +Copyright (C) 2000-2001 Zeljko Juric, Thomas Nussbaumer, and + Kevin Kofler + +This file is part of TIGCC. + +TIGCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +TIGCC Team gives you unlimited permission to link the compiled +versions of these files with other programs, and to distribute +those programs without any restriction coming from the use of this +file. (The General Public License restrictions do apply in other +respects; for example, they cover modification of the files, and +distribution when not linked into another program.) + +These files are distributed in the hope that they will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. diff --git a/pch/src/tigcc-archive/addbf.s b/pch/src/tigcc-archive/addbf.s new file mode 100644 index 0000000..41b63a9 --- /dev/null +++ b/pch/src/tigcc-archive/addbf.s @@ -0,0 +1,6 @@ +.data + .xdef __addbf3 + .even +__addbf3: + clr.l %d0 + bra __fp_entry diff --git a/pch/src/tigcc-archive/ashldi.s b/pch/src/tigcc-archive/ashldi.s new file mode 100644 index 0000000..bde9a77 --- /dev/null +++ b/pch/src/tigcc-archive/ashldi.s @@ -0,0 +1,24 @@ +|ashldi3 routine copyright (C) 2002, Kevin Kofler + +.data + xdef __ashldi3 + .even +__ashldi3: + tst.w 12(%a7) + bne.s .L__ashldi3_return0 + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + move.w 14(%a7),%d2 + beq.s .L__ashldi3_returnn + subq.w #1,%d2 +.L__ashldi3_loop: + add.l %d1,%d1 + addx.l %d0,%d0 + dbra.w %d2,.L__ashldi3_loop +.L__ashldi3_returnn: + rts + +.L__ashldi3_return0: + moveq.l #0,%d0 + moveq.l #0,%d1 + rts diff --git a/pch/src/tigcc-archive/ashrdi.s b/pch/src/tigcc-archive/ashrdi.s new file mode 100644 index 0000000..b7a52e1 --- /dev/null +++ b/pch/src/tigcc-archive/ashrdi.s @@ -0,0 +1,31 @@ +|ashrdi3 routine copyright (C) 2002, Kevin Kofler + +.data + xdef __ashrdi3 + .even +__ashrdi3: + tst.w 12(%a7) + bne.s .L__ashrdi3_return0 + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + move.w 14(%a7),%d2 + beq.s .L__ashrdi3_returnn + subq.w #1,%d2 +.L__ashrdi3_loop: + asr.l #1,%d0 + roxr.l #1,%d1 + dbra.w %d2,.L__ashrdi3_loop +.L__ashrdi3_returnn: + rts + +.L__ashrdi3_return0: + tst.b 4(%a7) + blt.s .L__ashrdi3_return_neg1 + moveq.l #0,%d0 + moveq.l #0,%d1 + rts + +.L__ashrdi3_return_neg1: + moveq.l #-1,%d0 + moveq.l #-1,%d1 + rts diff --git a/pch/src/tigcc-archive/assert.s b/pch/src/tigcc-archive/assert.s new file mode 100644 index 0000000..8f557e5 --- /dev/null +++ b/pch/src/tigcc-archive/assert.s @@ -0,0 +1,59 @@ +.data + .xdef __assertion_failed + .even +__assertion_failed: + link.w %a6,#-1044 + move.l 0xC8,%a2 + move.w 16(%a6),(%sp) + move.l 12(%a6),-(%sp) + move.l 8(%a6),-(%sp) + pea .L__assert_fmt + lea -1000(%a6),%a4 + move.l %a4,-(%sp) + move.l 332(%a2),%a0 + jsr (%a0) + move.l 188(%a2),%a0 + clr.l %d0 + move.b 2(%a0),%d0 + swap %d0 + move.b 3(%a0),%d0 + add.l #0xFFF5FFF1,%d0 + move.l %d0,(%sp) + move.l #0xA000A,-(%sp) + move.l 176(%a2),%a0 + jsr (%a0) + pea .L__assert_ttl + move.w #0x1058,-(%sp) + move.l %a0,-(%sp) + pea -1042(%a6) + move.l 120(%a2),%a0 + jsr (%a0) + move.l 4(%a2),%a0 + jsr (%a0) + clr.w 4(%sp) + move.l 76(%a2),%a0 + jsr (%a0) + move.l %a4,4(%sp) + move.l 148(%a2),%a0 + jsr (%a0) + move.l #0x10008,4(%sp) + move.l 212(%a2),%a0 + jsr (%a0) +.L__assert_wkey: + move.l 324(%a2),%a0 + jsr (%a0) + cmp.w #13,%d0 + jbne .L__assert_wkey + move.l 44(%a2),%a0 + jsr (%a0) + movea.l __save__sp__:l,%a7 + rts +.L__assert_ttl: + .ascii "ASSERTION FAILED" + .word 0 +.L__assert_fmt: + .byte 10 + .ascii " Condition: %s" + .byte 10,10 + .ascii " File: %s Line: %d" + .word 0 diff --git a/pch/src/tigcc-archive/atexit.s b/pch/src/tigcc-archive/atexit.s new file mode 100644 index 0000000..66b66c1 --- /dev/null +++ b/pch/src/tigcc-archive/atexit.s @@ -0,0 +1,107 @@ +|atexit function copyright (C) 2002, Kevin Kofler +|requires new exit support (__save__sp__) +|Many thanks to Patrick Plissier and Stephan Effelsberg for ideas on how to +|implement this. Stephan Effelsberg's C implementation inspired this mostly, +|but I have changed it so that exit and atexit will not be included if not +|used. There is only a small 20-byte exit support needed. + +.data + +.equ __malloc,0xa2 |HeapAllocPtr +.equ __free,0xa3 |HeapFreePtr +.equ __num_regs,10 |number of registers saved by the exit support + + .xdef atexit +atexit: +|find the return address: + movea.l __save__sp__:l,%a0 |stack pointer before restoring the registers + |(NOT PC-relative because of programs >32 KB) +|The return address is now at (a0). + +|check if the return address is .L__atexit__new__return + cmpi.l #.L__atexit__new__return:l,(%a0) + beq.s .L__atexit__return__address__ok |if it is, skip ahead +|Else: +|- move the current return address to .L__atexit__return+2 + move.l (%a0),.L__atexit__return+2 +|- change the return address to .L__atexit__new__return + move.l #.L__atexit__new__return:l,(%a0) + clr.l .L__atexit__num__funcs |initialize the number of atexit functions to 0 + +|allocate a handle for the functions + pea.l 4:w + movea.l 0xc8,%a0 + move.l (__malloc*4,%a0),%a0 + jsr (%a0) |a0=malloc(4); + addq.l #4,%a7 + bra.s .L__atexit__handle__allocated + +.L__atexit__return__address__ok: +|reallocate the handle for the functions + move.l (.L__atexit__num__funcs,%PC),%d0 + lsl.l #2,%d0 + addq.l #4,%d0 + move.l %d0,-(%a7) + move.l (.L__atexit__ptr__funcs,%PC),-(%a7) + jsr realloc |a0=realloc(.L__atexit__ptr__funcs,.L__atexit__num__funcs*4+4); + addq.l #8,%a7 + +.L__atexit__handle__allocated: +|If a0 is NULL, there was not enough memory, so we return an error code. + moveq #0,%d0 + cmpa.l %d0,%a0 |if (!a0) + seq.b %d0 + beq.s .L__atexit__rts |return 255; + + move.l %a0,.L__atexit__ptr__funcs |save a0 to .L__atexit__ptr__funcs +|Now we store the function given as an argument into the allocated memory. + move.l (.L__atexit__num__funcs,%PC),%d1 + lsl.l #2,%d1 + move.l (4,%a7),(0,%a0,%d1:l) |.L__atexit__ptr__funcs[.L__atexit__num__funcs]=4(a7); + +|And there is 1 more atexit function now: + addq.l #1,.L__atexit__num__funcs + +.L__atexit__rts: + rts + +|This will be executed when the _main function or the exit function tries to +|return: +.L__atexit__new__return: + move.l (.L__atexit__num__funcs,%PC),%d0 |if there are no functions to call, return + beq.s .L__atexit__no__funcs |immediately + +| movem.l %a2/%a5/%d3,-(%a7) +|no need to save and restore the registers, the exit support will do it for us + movea.l 0xc8,%a5 + movea.l (.L__atexit__ptr__funcs,%PC),%a2 + move.l %d0,%d3 |save d0 to d3 + lsl.l #2,%d0 |point a2 to the address of the last function + 4 + add.l %d0,%a2 |that is, .L__atexit__ptr__funcs[.L__atexit__num__funcs] + + subq.l #1,%d3 |subtract 1 from the number of functions for the dbra loop + +|call all atexit functions now +.L__atexit__loop: + movea.l -(%a2),%a0 + jsr (%a0) + dbra.w %d3,.L__atexit__loop + +|a2 now points to the beginning of the allocated memory for the pointers +|free this memory + pea.l (%a2) + move.l (__free*4,%a5),%a0 + jsr (%a0) |free(.L__atexit__ptr__funcs); + addq.l #4,%a7 + +| movem.l (%a7)+,%a2/%a5/%d3 +|no need to save and restore the registers, the exit support will do it for us +.L__atexit__no__funcs: + +|This will return to the actual return address (which will be patched in +|instead of the 0 by the first call to atexit). +.L__atexit__return: jmp.l 0:l + +|data: +.L__atexit__ptr__funcs: .long 0 |pointer to the atexit functions +.L__atexit__num__funcs: .long 0 |number of atexit functions diff --git a/pch/src/tigcc-archive/atof.s b/pch/src/tigcc-archive/atof.s new file mode 100644 index 0000000..8089e6c --- /dev/null +++ b/pch/src/tigcc-archive/atof.s @@ -0,0 +1,44 @@ +.data + .xdef atof + .even +atof: + link.w %a6,#-80 + movem.l %d3-%d7/%a2-%a5,-(%sp) + move.l 0xC8,%a4 + move.l 1060(%a4),%a3 + move.l (%a3),%d4 + pea -80(%a6) + move.l 1360(%a4),%a0 + jsr (%a0) /* ER_catch */ + tst.w %d0 + jbeq .L__atof_1 + move.l #0x7FFFAA00,%d0 + clr.l %d1 + clr.w %d2 + jbra .L__atof_3 +.L__atof_1: + move.l 8(%a6),(%sp) + move.l 3880(%a4),%a0 + jsr (%a0) /* push_parse_text */ + move.l (%a3),%a0 + move.b (%a0),%d5 + cmpi.b #0x7A,%d5 + bne.s .L__atof_2 + subq #1,%a0 +.L__atof_2: + move.l %a0,(%sp) + move.l 3044(%a4),%a0 + jsr (%a0) /* estack_number_to_Float */ + move.l %d4,(%a3) + move.l 1364(%a4),%a0 + jsr (%a0) /* ER_success */ + move.l (%a6,-10),%d0 + move.l (%a6,-6),%d1 + move.w (%a6,-2),%d2 + cmpi.b #0x7A,%d5 + bne.s .L__atof_3 + bset #31,%d0 +.L__atof_3: + movem.l -116(%a6),%d3-%d7/%a2-%a5 + unlk %a6 + rts diff --git a/pch/src/tigcc-archive/atoi.c b/pch/src/tigcc-archive/atoi.c new file mode 100644 index 0000000..bceb36d --- /dev/null +++ b/pch/src/tigcc-archive/atoi.c @@ -0,0 +1,16 @@ +#include +#include + +#ifndef CONFIRM_REGPARM1_ENABLED +#error You need to patch as described in the 'COMPILING' file. +#endif + +__ATTR_LIB_C__ short atoi(const char *s) +{ + unsigned short c,value=0,neg=0; + while(*s==' ') ++s; + if(*s=='-'||*(const unsigned char*)s==0xAD) ++s,neg=-1; + else if(*s=='+') ++s; + while(isdigit(c=*(const unsigned char*)s++)) value=10*value+c-'0'; + return neg?-value:value; +} diff --git a/pch/src/tigcc-archive/atol.c b/pch/src/tigcc-archive/atol.c new file mode 100644 index 0000000..07854d6 --- /dev/null +++ b/pch/src/tigcc-archive/atol.c @@ -0,0 +1,13 @@ +#include +#include + +__ATTR_LIB_C__ long atol(const char *s) +{ + unsigned short c,neg=0; + long value=0; + while(*s==' ') ++s; + if(*s=='-'||*(const unsigned char*)s==0xAD) ++s,neg=-1; + else if(*s=='+') ++s; + while(isdigit(c=*(const unsigned char*)s++)) value=(value<<3)+(value<<1)+c-'0'; + return neg?-value:value; +} diff --git a/pch/src/tigcc-archive/bc.s b/pch/src/tigcc-archive/bc.s new file mode 100644 index 0000000..9994c35 --- /dev/null +++ b/pch/src/tigcc-archive/bc.s @@ -0,0 +1,19 @@ +.data + .xdef __BC + .even +__BC: + link %a6,#-10 + move.l (%a6,26),-(%sp) + move.l (%a6,22),-(%sp) + move.l (%a6,18),-(%sp) + move.l (%a6,14),-(%sp) + move.l (%a6,10),-(%sp) + move.w (%a6,8),%d0 + move.l 0xC8,%a0 + move.l (%a0,%d0.w),%a0 + jsr (%a0) + move.l (%a6,-10),%d0 + move.l (%a6,-6),%d1 + move.w (%a6,-2),%d2 + unlk %a6 + rts diff --git a/pch/src/tigcc-archive/bcopy.s b/pch/src/tigcc-archive/bcopy.s new file mode 100644 index 0000000..7004348 --- /dev/null +++ b/pch/src/tigcc-archive/bcopy.s @@ -0,0 +1,13 @@ +.data + .xdef bcopy + .even +bcopy: + move.w (12,%sp),-(%sp) + clr.w -(%sp) + move.l (8,%sp),-(%sp) + move.l (16,%sp),-(%sp) + movea.l 0xC8,%a0 + movea.l (%a0,0x26A*4),%a0 + jsr (%a0) /* memcpy */ + lea (%sp,12),%sp + rts diff --git a/pch/src/tigcc-archive/bsearch.c b/pch/src/tigcc-archive/bsearch.c new file mode 100644 index 0000000..df480a8 --- /dev/null +++ b/pch/src/tigcc-archive/bsearch.c @@ -0,0 +1,19 @@ +#include + +// Do not use register a5; callback function might need it. +register long __tbl asm ("a5"); + +__ATTR_LIB_C__ void *bsearch(const void *key, const void *bptr, short n, short w, compare_t cmp_func) +{ + unsigned short left=0,right=n-1,index; + short rcmp; + void *rptr; + do + { + index=(left+right)>>1; + if((rcmp=cmp_func(key,rptr=(char*)bptr+(long)index*(unsigned short)w))>0) left=index+1; + else if(rcmp<0) right=index-1; + else return rptr; + } while(left<=right); + return 0; +} diff --git a/pch/src/tigcc-archive/bzero.s b/pch/src/tigcc-archive/bzero.s new file mode 100644 index 0000000..b2c0c13 --- /dev/null +++ b/pch/src/tigcc-archive/bzero.s @@ -0,0 +1,12 @@ +.data + .xdef bzero + .even +bzero: + move.w (8,%sp),-(%sp) + clr.l -(%sp) + move.l (10,%sp),-(%sp) + movea.l 0xC8,%a0 + movea.l (%a0,0x27C*4),%a0 + jsr (%a0) /* memset */ + lea (%sp,10),%sp + rts diff --git a/pch/src/tigcc-archive/calloc.s b/pch/src/tigcc-archive/calloc.s new file mode 100644 index 0000000..d51a4ff --- /dev/null +++ b/pch/src/tigcc-archive/calloc.s @@ -0,0 +1,24 @@ +.data + .xdef calloc + .even +calloc: + link.w %a6,#0 + move.w 8(%a6),%d0 + mulu.w 10(%a6),%d0 + move.l %d0,-(%sp) + move.l 0xC8,%a0 + move.l 648(%a0),%a0 + jsr (%a0) + move.l %a0,%d0 + jbeq .L__calloc_1 + clr.w -(%sp) + move.l %a0,-(%sp) + move.l 0xC8,%a0 + move.l 2544(%a0),%a0 + jsr (%a0) + jbra .L__calloc_2 +.L__calloc_1: + move.l #0,%a0 +.L__calloc_2: + unlk %a6 + rts diff --git a/pch/src/tigcc-archive/calloc_throw.s b/pch/src/tigcc-archive/calloc_throw.s new file mode 100644 index 0000000..916b836 --- /dev/null +++ b/pch/src/tigcc-archive/calloc_throw.s @@ -0,0 +1,12 @@ +.data + .even + .xdef calloc_throw +calloc_throw: + lea.l .L__finished+2,%a0 + move.l (%sp)+,(%a0) + jbsr calloc + move.l %a0,%d0 + jbne .L__finished + .word 0xA000+670 +.L__finished: + jmp.l 0:l diff --git a/pch/src/tigcc-archive/clrscr.s b/pch/src/tigcc-archive/clrscr.s new file mode 100644 index 0000000..e61ca4e --- /dev/null +++ b/pch/src/tigcc-archive/clrscr.s @@ -0,0 +1,12 @@ +.data + .xdef clrscr + .even +clrscr: + move.l 0xC8,%a0 + move.l (%a0,0x674),%a0 + clr.l -(%sp) + jsr (%a0) + addq.l #4,%sp + move.l 0xC8,%a0 + move.l (%a0,0x678),%a0 + jmp (%a0) diff --git a/pch/src/tigcc-archive/cmpbf.s b/pch/src/tigcc-archive/cmpbf.s new file mode 100644 index 0000000..90d76f1 --- /dev/null +++ b/pch/src/tigcc-archive/cmpbf.s @@ -0,0 +1,12 @@ +.data + .xdef __cmpbf2,__nebf2,__eqbf2,__gebf2,__ltbf2,__gtbf2,__lebf2 + .even +__cmpbf2: +__nebf2: +__eqbf2: +__gebf2: +__ltbf2: +__gtbf2: +__lebf2: + moveq.l #20,%d0 + bra __fp_entry_1 diff --git a/pch/src/tigcc-archive/contrastdn.s b/pch/src/tigcc-archive/contrastdn.s new file mode 100644 index 0000000..74a9df3 --- /dev/null +++ b/pch/src/tigcc-archive/contrastdn.s @@ -0,0 +1,10 @@ +.data + .xdef OSContrastDn + .even +OSContrastDn: + movem.l %d3-%d4,-(%sp) + move.l 0xC8,%a0 + move.l (%a0,2652),%a0 + jsr (%a0) + movem.l (%sp)+,%d3-%d4 + rts diff --git a/pch/src/tigcc-archive/contrastup.s b/pch/src/tigcc-archive/contrastup.s new file mode 100644 index 0000000..73aaf06 --- /dev/null +++ b/pch/src/tigcc-archive/contrastup.s @@ -0,0 +1,10 @@ +.data + .xdef OSContrastUp + .even +OSContrastUp: + movem.l %d3-%d4,-(%sp) + move.l 0xC8,%a0 + move.l (%a0,2648),%a0 + jsr (%a0) + movem.l (%sp)+,%d3-%d4 + rts diff --git a/pch/src/tigcc-archive/divbf.s b/pch/src/tigcc-archive/divbf.s new file mode 100644 index 0000000..51ee2da --- /dev/null +++ b/pch/src/tigcc-archive/divbf.s @@ -0,0 +1,6 @@ +.data + .xdef __divbf3 + .even +__divbf3: + moveq.l #12,%d0 + bra __fp_entry diff --git a/pch/src/tigcc-archive/divdi.s b/pch/src/tigcc-archive/divdi.s new file mode 100644 index 0000000..91de237 --- /dev/null +++ b/pch/src/tigcc-archive/divdi.s @@ -0,0 +1,37 @@ +|divdi3 routine copyright (C) 2002, Kevin Kofler +|WARNING: Division by 0 will be handled the same way as in the unsigned variant. +| For my __udivdi3, this means: +| A division by 0 will not cause an exception, but just crash in an +| infinite loop! +|ANOTHER WARNING: This will ONLY work with an __udivdi3 which does NOT destroy a1! +| Mine works of course. + +.data + xdef __divdi3 + .even +__divdi3: + tst.b 4(%a7) + blt.s .L__divdi3_numer_negative + tst.b 12(%a7) + blt.s .L__divdi3_denom_negative +.L__divdi3_udivdi3: + jbra __udivdi3 + +.L__divdi3_numer_negative: + neg.l 8(%a7) + negx.l 4(%a7) + tst.b 12(%a7) + bge.s .L__divdi3_denom_positive + neg.l 16(%a7) + negx.l 12(%a7) + bra.s .L__divdi3_udivdi3 + +.L__divdi3_denom_negative: + neg.l 16(%a7) + negx.l 12(%a7) +.L__divdi3_denom_positive: + move.l (%a7)+,%a1 + bsr.s .L__divdi3_udivdi3 + neg.l %d1 + negx.l %d0 + jmp (%a1) diff --git a/pch/src/tigcc-archive/diventry.s b/pch/src/tigcc-archive/diventry.s new file mode 100644 index 0000000..4140663 --- /dev/null +++ b/pch/src/tigcc-archive/diventry.s @@ -0,0 +1,11 @@ +.data + .xdef __div_entry + .even +__div_entry: + move.l (4,%sp),%d1 + move.l (8,%sp),%d0 + movea.l 0xC8,%a0 + movea.l (%a0,%d2.w),%a0 + jsr (%a0) + move.l %d1,%d0 + rts diff --git a/pch/src/tigcc-archive/divsi.s b/pch/src/tigcc-archive/divsi.s new file mode 100644 index 0000000..df82ae1 --- /dev/null +++ b/pch/src/tigcc-archive/divsi.s @@ -0,0 +1,6 @@ +.data + .xdef __divsi3 + .even +__divsi3: + move.w #0x2A8*4,%d2 /* _ds32s32 */ + jra __div_entry diff --git a/pch/src/tigcc-archive/dll.c b/pch/src/tigcc-archive/dll.c new file mode 100644 index 0000000..d26b097 --- /dev/null +++ b/pch/src/tigcc-archive/dll.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + +/* These functions are in the same file, so that they + can access their global variables in a pc-relative + fashion. */ + +__ATTR_LIB_C__ short LoadDLL(const char *DLL_name, long ID, short major, short minor) +{ + SYM_ENTRY *entry; + HANDLE h; + unsigned char *bptr,*sptr; + unsigned short len,offset=0,wrongver=0; + unsigned long pc; + unsigned long signature[]={__DLL_SIGNATURE,ID}; + asm volatile("bsr 0f; 0:move.l (%%sp)+,%0":"=g"(pc)); + if(pc<0x40000) return DLL_NOTINGHOSTSPACE; + if(__DLL_body_ptr) return DLL_ALREADYLOADED; + entry=SymFindFirst(NULL,2); + do + { + if(!strcmp(entry->name,DLL_name)&&entry->handle&&!entry->flags.bits.twin + &&(entry->flags.bits.archived||!HeapGetLock(entry->handle))) + { + len=peek_w(bptr=HeapDeref(entry->handle))+2; + if(!memcmp(bptr+len-5,"DLL\x00\xF8",5)) + { + offset=0; + for(sptr=bptr+2;(sptrmajor + ||(unsigned short)minor>((__DLL_interface_struct*)sptr)->minor) + wrongver=1; + else + offset=sptr-bptr,wrongver=0; + } + if(offset) break; + } + } + } while((entry=SymFindNext())); + if(wrongver) return DLL_WRONGVERSION; + if(!entry) return DLL_NOTFOUND; + if(!HeapLock(h=entry->handle)) return DLL_LOCKFAILED; + if(!(__DLL_body_ptr=malloc(len=peek_w(bptr=HeapDeref(h)+2)+2))) + { + HeapUnlock(h); + return DLL_OUTOFMEM; + } + memcpy(__DLL_body_ptr,bptr,len); + EX_patch((char*)__DLL_body_ptr+0x40000+2,(char*)__DLL_body_ptr+0x40000+len-1); + __DLL_interface_ptr=(__DLL_interface_struct*)((char*)__DLL_body_ptr+offset-2); + HeapUnlock(h); + return DLL_OK; +} + +__ATTR_LIB_C__ void UnloadDLL(void) +{ + if(!__DLL_body_ptr) return; + free(__DLL_body_ptr); + __DLL_body_ptr=0; + __DLL_interface_ptr=0; +} + +__DLL_interface_struct *__DLL_interface_ptr=0; +void *__DLL_body_ptr=0; diff --git a/pch/src/tigcc-archive/dummyhandler.s b/pch/src/tigcc-archive/dummyhandler.s new file mode 100644 index 0000000..d0be223 --- /dev/null +++ b/pch/src/tigcc-archive/dummyhandler.s @@ -0,0 +1,5 @@ +.data + .even + .xdef __dummy_handler__ +__dummy_handler__: + rte diff --git a/pch/src/tigcc-archive/enter_ghost_space.s b/pch/src/tigcc-archive/enter_ghost_space.s new file mode 100644 index 0000000..b0fbf12 --- /dev/null +++ b/pch/src/tigcc-archive/enter_ghost_space.s @@ -0,0 +1,36 @@ +.data + .xdef enter_ghost_space + .even +enter_ghost_space: + bsr.w .L__ghost_space_0 +.L__ghost_space_0: + move.l (%sp)+,%d0 + cmpi.l #0x40000,%d0 + bcc.s .L__ghost_space_2 + movea.l 0xC8,%a0 + cmpi.l #1000,(%a0,-4) + bcs.s .L__ghost_space_2 + movem.l %a2-%a6/%d3-%d7,-(%sp) + lea (%sp,-20),%sp + move.l #0x3E000,%a3 + move.l %a0,%d0 + andi.l #0x600000,%d0 + addi.l #0x20000,%d0 + move.l %d0,(%sp,12) + move.l %d0,(%sp,16) + trap #0xC + move.w #0x2700,%sr + move.l #0xF,%d3 + pea .L__ghost_space_1(%pc) + bset.b #2,(%sp,1) + clr.w -(%sp) + move.l 0xAC,%a0 + jmp (%a0) +.L__ghost_space_1: + lea (%sp,20),%sp + movem.l (%sp)+,%a2-%a6/%d3-%d7 +.L__ghost_space_2: + move.l (%sp)+,%d0 + bset.l #18,%d0 + movea.l %d0,%a0 + jmp (%a0) diff --git a/pch/src/tigcc-archive/exit.s b/pch/src/tigcc-archive/exit.s new file mode 100644 index 0000000..71d8297 --- /dev/null +++ b/pch/src/tigcc-archive/exit.s @@ -0,0 +1,10 @@ +|exit function copyright (C) 2002, Kevin Kofler +|requires new exit support (__save__sp__) +|Thanks to Patrick Plissier for the code. I have just changed it from a patch +|to an archive function, so it won't be there when not needed. + +.data + .xdef __exit +__exit: + movea.l __save__sp__:l,%a7 |(NOT PC-relative because of programs >32 KB) + rts diff --git a/pch/src/tigcc-archive/fclose.c b/pch/src/tigcc-archive/fclose.c new file mode 100644 index 0000000..8a74d39 --- /dev/null +++ b/pch/src/tigcc-archive/fclose.c @@ -0,0 +1,16 @@ +#include +#include + +__ATTR_LIB_C__ short fclose(FILE *f) +{ + short s; + + if(!f) return EOF; + s=(f->flags&_F_ERR)?EOF:0; + + HeapRealloc(f->handle,(*(unsigned short*)(f->base))+2); + HeapUnlock(f->handle); + free(f); + + return s; +} diff --git a/pch/src/tigcc-archive/fgetc.c b/pch/src/tigcc-archive/fgetc.c new file mode 100644 index 0000000..1e2288d --- /dev/null +++ b/pch/src/tigcc-archive/fgetc.c @@ -0,0 +1,18 @@ +#include +#include + +__ATTR_LIB_C__ short fgetc(FILE *f) +{ + short c,tmode=!(f->flags&_F_BIN); + if(f->flags&_F_ERR) return EOF; + if(!(f->flags&_F_READ)) __FERROR(f); + if((c=f->unget)<0) + { + f->unget=0; return c&0xFF; + } + if(feof(f)) return EOF; + c=peek(f->fpos++); + if(c=='\r'&&tmode) fgetc(f); + if(f->base+peek_w(f->base)+(tmode?0:2)==f->fpos) f->flags|=_F_EOF; + return c; +} diff --git a/pch/src/tigcc-archive/fgets.c b/pch/src/tigcc-archive/fgets.c new file mode 100644 index 0000000..926d38d --- /dev/null +++ b/pch/src/tigcc-archive/fgets.c @@ -0,0 +1,14 @@ +#include + +__ATTR_LIB_C__ char *fgets(char *s, short n, FILE *fp) +{ + short c=EOF; + char *cs=s; + while(--n>0&&(c=fgetc(fp))!=EOF) + { + if(c=='\r'&&!(fp->flags&_F_BIN)) c='\n'; + if ((*cs++=c)=='\n') break; + } + *cs=0; + return ((c==EOF&&cs==s)?0:s); +} diff --git a/pch/src/tigcc-archive/fixbf.s b/pch/src/tigcc-archive/fixbf.s new file mode 100644 index 0000000..1ee5a1a --- /dev/null +++ b/pch/src/tigcc-archive/fixbf.s @@ -0,0 +1,7 @@ +.data + .xdef __fixbfsi,__fixunsbfsi + .even +__fixbfsi: +__fixunsbfsi: + moveq.l #24,%d0 + bra __fp_entry_1 diff --git a/pch/src/tigcc-archive/floatbf.s b/pch/src/tigcc-archive/floatbf.s new file mode 100644 index 0000000..ee5e792 --- /dev/null +++ b/pch/src/tigcc-archive/floatbf.s @@ -0,0 +1,6 @@ +.data + .xdef __floatsibf + .even +__floatsibf: + moveq.l #28,%d0 + bra __fp_entry diff --git a/pch/src/tigcc-archive/fopen.c b/pch/src/tigcc-archive/fopen.c new file mode 100644 index 0000000..740d249 --- /dev/null +++ b/pch/src/tigcc-archive/fopen.c @@ -0,0 +1,68 @@ +#include +#include + +__ATTR_LIB_C__ FILE *fopen(const char *name, const char *mode) +{ + char str[50],*fpos,*epos,*base=0,*sptr=str,chmode=mode[0]; + short bmode=(mode[1]=='b'|| mode[2]=='b'),flags=0,ferr; + SYM_ENTRY *sym_entry; + FILE *f; + + *sptr=0; while((*++sptr=*name++)); + + if((sym_entry=DerefSym(SymFind(sptr)))) + if(sym_entry->flags.flags_n&0x8218 && strpbrk(mode,"wa+")) + return 0; + + if(!(f=malloc(sizeof(FILE)))) return 0; + + if(chmode=='r'|| chmode=='a') + { + flags=_F_READ; + if(!sym_entry) + if(chmode=='r') + { + free(f); + return 0; + } + else chmode='w'; + else + { + base=HLock(f->handle=sym_entry->handle); + f->alloc=HeapSize(f->handle); + } + } + if(chmode=='w') + { + SCR_STATE scr_state; + flags=_F_WRIT; + SaveScrState(&scr_state); + ferr=!(sym_entry=DerefSym(SymAdd(sptr))); + RestoreScrState(&scr_state); + if(!ferr) ferr=!(f->handle=sym_entry->handle=HeapAlloc(128)); + if(ferr) + { + SymDel(sptr); + free(f); + return 0; + } + + f->buffincrement=f->alloc=128; + + base=HLock(f->handle); + if(bmode) poke_w(base,0); + else + { + poke_l(base,0x00050001); + poke_l(base+4,0x2000E000); + } + } + epos=base+peek_w(base)+(bmode?2:0); + if(chmode=='a') flags=_F_WRIT,fpos=epos; + else fpos=base+(bmode?2:5); + if(epos==fpos) flags|=_F_EOF; + if(mode[1]=='+'||mode[2]=='+') flags|=_F_RDWR; + if(bmode) flags|=_F_BIN; + f->flags=flags; f->base=base; f->fpos=fpos; f->unget=0; + return f; +} diff --git a/pch/src/tigcc-archive/fpcall.s b/pch/src/tigcc-archive/fpcall.s new file mode 100644 index 0000000..bab4d28 --- /dev/null +++ b/pch/src/tigcc-archive/fpcall.s @@ -0,0 +1,17 @@ +.data + .xdef __fp_entry_1,__fp_call + .even +__fp_entry_1: + lea (%sp,24),%a1 +__fp_call: + add.w #728,%d0 + move.l -(%a1),-(%sp) + move.l -(%a1),-(%sp) + move.l -(%a1),-(%sp) + move.l -(%a1),-(%sp) + move.l -(%a1),-(%sp) + move.l 0xC8,%a0 + move.l (%a0,%d0.w),%a0 + jsr (%a0) + lea (%sp,20),%sp + rts diff --git a/pch/src/tigcc-archive/fpentry.s b/pch/src/tigcc-archive/fpentry.s new file mode 100644 index 0000000..1303710 --- /dev/null +++ b/pch/src/tigcc-archive/fpentry.s @@ -0,0 +1,11 @@ +.data + .xdef __fp_entry + .even +__fp_entry: + link %a6,#-10 + lea (%a6,28),%a1 + bsr __fp_call + movem.l (%a6,-10),%d0-%d1 + move.w (%a6,-2),%d2 + unlk %a6 + rts diff --git a/pch/src/tigcc-archive/fprintf.s b/pch/src/tigcc-archive/fprintf.s new file mode 100644 index 0000000..187d894 --- /dev/null +++ b/pch/src/tigcc-archive/fprintf.s @@ -0,0 +1,17 @@ +| Warning: This routine has the attribute __ATTR_TIOS__! + +.data + .xdef fprintf + .even +fprintf: + movea.l 0xC8,%a0 + movea.l (%a0,0x14C),%a0 /* vcbprintf */ + lea (%a0,32),%a0 + movea.w (%a0),%a1 + pea (%sp,12) + move.l (%sp,12),-(%sp) + move.l (%sp,12),-(%sp) + pea fputc + jsr (%a0.l,%a1) + lea (%sp,16),%sp + rts diff --git a/pch/src/tigcc-archive/fputc.c b/pch/src/tigcc-archive/fputc.c new file mode 100644 index 0000000..e54f4d3 --- /dev/null +++ b/pch/src/tigcc-archive/fputc.c @@ -0,0 +1,33 @@ +#include +#include +#include + +__ATTR_TIOS_CALLBACK__ short fputc(short c, FILE *f) +{ + short tmode=!(f->flags&_F_BIN); + char *base=f->base,*oldbase=base; + if(f->flags&_F_ERR) return EOF; + if(!(f->flags&_F_WRIT)) __FERROR(f); + if(peek_w(base)+10>f->alloc) + { + HeapUnlock(f->handle); + if(!HeapRealloc(f->handle,f->alloc+=f->buffincrement)) __FERROR(f); + base=f->base=HLock(f->handle); + f->fpos+=base-oldbase; + oldbase=base; + } + if(feof(f)) (*(short*)base)++; + if(c=='\n'&&tmode) c='\r'; + poke(f->fpos++,c); + if(c=='\r'&&tmode) fputc(' ',f); + if(base+peek_w(base)+(tmode?0:2)==f->fpos) + { + f->flags|=_F_EOF; + if(tmode) + { + poke(f->fpos,0); + poke(f->fpos+1,0xE0); + } + } + return c; +} diff --git a/pch/src/tigcc-archive/fputchar.s b/pch/src/tigcc-archive/fputchar.s new file mode 100644 index 0000000..2f7b199 --- /dev/null +++ b/pch/src/tigcc-archive/fputchar.s @@ -0,0 +1,68 @@ +| Warning: This routine has the attribute __ATTR_TIOS_CALLBACK__! + +.data + .xdef fputchar + .even +fputchar: + link.w %a6,#-20 + movem.l %d3-%d7/%a2-%a5,-(%sp) + clr.w %d0 + move.b (%a6,9),%d6 + move.l 0xC8,%a5 + move.l (%a5,1592),%a0 + jsr (%a0) + move.w %d0,%d4 + lsl.w #1,%d4 + addq.w #6,%d4 + move.l (%a5,188),%a3 + pea (%a6,-18) + move.l (%a5,1664),%a0 + jsr (%a0) + move.w (%a6,-8),%d5 + move.w (%a6,-6),%d3 + move.w %d6,-(%sp) + move.l (%a5,1600),%a0 + jsr (%a0) + move.w %d0,%d7 + cmp.b #10,%d6 + jbeq .L__fputchar_1 + move.w %d5,%d0 + add.w %d7,%d0 + clr.w %d1 + move.b (%a3,2),%d1 + cmp.w %d0,%d1 + jbge .L__fputchar_2 +.L__fputchar_1: + clr.w %d5 + add.w %d4,%d3 +.L__fputchar_2: + move.w %d3,%d0 + add.w %d4,%d0 + clr.w %d1 + move.b (%a3,3),%d1 + cmp.w %d0,%d1 + jbge .L__fputchar_3 + clr.w (%sp) + move.w %d4,-(%sp) + move.l %a3,-(%sp) + move.l %a3,-(%sp) + move.l (%a5,1580),%a0 + jsr (%a0) + sub.w %d4,%d3 +.L__fputchar_3: + move.w #4,(%sp) + move.w %d6,-(%sp) + move.w %d3,-(%sp) + move.w %d5,-(%sp) + cmp.b #10,%d6 + jbeq .L__fputchar_4 + move.l (%a5,1680),%a0 + jsr (%a0) + add.w %d7,(%sp) +.L__fputchar_4: + move.l (%a5,1652),%a0 + jsr (%a0) + move.w %d6,%d0 + movm.l -56(%a6),%d3-%d7/%a2-%a5 + unlk %a6 + rts diff --git a/pch/src/tigcc-archive/fputs.s b/pch/src/tigcc-archive/fputs.s new file mode 100644 index 0000000..9e5b75d --- /dev/null +++ b/pch/src/tigcc-archive/fputs.s @@ -0,0 +1,15 @@ +.data + .xdef fputs + .even +.L__fputs_1: + move.l %a0,(%sp,4) + move.l (%sp,8),-(%sp) + move.w %d1,-(%sp) + jsr fputc + addq.l #6,%sp +fputs: + move.l (%sp,4),%a0 + clr.w %d1 + move.b (%a0)+,%d1 + jbne .L__fputs_1 + rts diff --git a/pch/src/tigcc-archive/fread.c b/pch/src/tigcc-archive/fread.c new file mode 100644 index 0000000..0190bb0 --- /dev/null +++ b/pch/src/tigcc-archive/fread.c @@ -0,0 +1,17 @@ +#include + +__ATTR_LIB_C__ unsigned short fread(void *ptr, short size, short n, FILE *f) +{ + unsigned short i,j; + short c,saveflags=f->flags; + f->flags|=_F_BIN; + for(i=0;i<(unsigned short)n;i++) + for(j=0;j<(unsigned short)size;j++) + { + if((c=fgetc(f))<0) goto exit; + *(unsigned char*)ptr++=c; + } +exit: + f->flags=saveflags; + return i; +} diff --git a/pch/src/tigcc-archive/freetimer.s b/pch/src/tigcc-archive/freetimer.s new file mode 100644 index 0000000..4745c2b --- /dev/null +++ b/pch/src/tigcc-archive/freetimer.s @@ -0,0 +1,24 @@ +.data + .xdef OSVFreeTimer + .even +OSVFreeTimer: + move.w (%sp,4),%d0 + subq.w #1,%d0 + cmpi.w #2,%d0 + bcc.s .L__timer_ffai + muls.w #12,%d0 + move.l 0x74,%a0 + cmp.l #132133782,(%a0,-4) + bne.s .L__timer_fok + move.l #-1,-32(%a0,%d0.w) + move.l (%a0,-32),%d0 + and.l (%a0,-20),%d0 + addq.l #1,%d0 + bne.s .L__timer_fok + move.l (%a0,-8),0x40074 +.L__timer_fok: + moveq #1,%d0 + rts +.L__timer_ffai: + clr.w %d0 + rts diff --git a/pch/src/tigcc-archive/fseek.c b/pch/src/tigcc-archive/fseek.c new file mode 100644 index 0000000..c18e26b --- /dev/null +++ b/pch/src/tigcc-archive/fseek.c @@ -0,0 +1,17 @@ +#include +#include + +__ATTR_LIB_C__ short fseek(FILE *f, long offset, short wh) +{ + short bmode=f->flags&_F_BIN; + char *start=(char*)f->base+(bmode?2:5); + char *end=(char*)f->base+peek_w(f->base)+(bmode?2:0); + char *pos=((wh==SEEK_SET)?start:((wh==SEEK_CUR)?(f->fpos):end))+offset; + if(f->flags&_F_ERR) return EOF; + if(posend||(unsigned short)wh>SEEK_END) __FERROR(f); + f->fpos=pos; + f->unget=0; + if(pos==end) f->flags|=_F_EOF; + else f->flags&=~_F_EOF; + return 0; +} diff --git a/pch/src/tigcc-archive/fsetbufsize.c b/pch/src/tigcc-archive/fsetbufsize.c new file mode 100644 index 0000000..7d2d9bd --- /dev/null +++ b/pch/src/tigcc-archive/fsetbufsize.c @@ -0,0 +1,7 @@ +#include + +__ATTR_LIB_C__ void fsetbufsize(short newsize, FILE *f) +{ + if(newsize && f) + f->buffincrement=newsize; +} diff --git a/pch/src/tigcc-archive/ftell.c b/pch/src/tigcc-archive/ftell.c new file mode 100644 index 0000000..371a928 --- /dev/null +++ b/pch/src/tigcc-archive/ftell.c @@ -0,0 +1,7 @@ +#include + +__ATTR_LIB_C__ long ftell(const FILE *f) +{ + if(f->flags&_F_ERR) return EOF; + return f->fpos-(char*)f->base-((f->flags&_F_BIN)?2:5); +} diff --git a/pch/src/tigcc-archive/fwrite.c b/pch/src/tigcc-archive/fwrite.c new file mode 100644 index 0000000..5124bab --- /dev/null +++ b/pch/src/tigcc-archive/fwrite.c @@ -0,0 +1,14 @@ +#include + +__ATTR_LIB_C__ unsigned short fwrite(const void *ptr, short size, short n, FILE *f) +{ + unsigned short i,j; + short saveflags=f->flags; + f->flags|=_F_BIN; + for(i=0;i<(unsigned short)n;i++) + for(j=0;j<(unsigned short)size;j++) + if(fputc(*(unsigned char*)ptr++,f)<0) goto exit; +exit: + f->flags=saveflags; + return i; +} diff --git a/pch/src/tigcc-archive/getappid.s b/pch/src/tigcc-archive/getappid.s new file mode 100644 index 0000000..20fd0a1 --- /dev/null +++ b/pch/src/tigcc-archive/getappid.s @@ -0,0 +1,57 @@ +.data + .xdef EV_getAppID + .even +EV_getAppID: + link.w %a6,#0 + movem.l %d3-%d4/%a2-%a3,-(%sp) + move.l 8(%a6),%d4 + lea .L__appid_tb(%pc),%a2 + moveq.l #9,%d3 + move.l 0xC8,%a3 + cmp.l #1000,-4(%a3) + jbls .L__appid_lp + move.l %d4,-(%sp) + move.l 4432(%a3),%a0 + jsr (%a0) + tst.w %d0 + jbne .L__appid_end + moveq.l #-1,%d0 + jbra .L__appid_end +.L__appid_lp: + move.l %a2,-(%sp) + move.l %d4,-(%sp) + move.l 2500(%a3),%a0 + jsr (%a0) + addq.l #8,%sp + tst.w %d0 + jbeq .L__appid_fnd +.L__appid_skp: + tst.b (%a2)+ + dbne %d3,.L__appid_lp + jbne .L__appid_skp +.L__appid_fnd: + move.w %d3,%d0 + move.l %a3,%d1 + and.l #0x600000,%d1 + cmp.l #0x400000,%d1 + jbne .L__appid_end + cmp.w #6,%d0 + jble .L__appid_end + addq.w #1,%d0 +.L__appid_end: + movem.l -16(%a6),%d3-%d4/%a2-%a3 + unlk %a6 + rts +.data + .even +.L__appid_tb: + .asciz "TISLFTST" + .asciz "TIINSLVR" + .asciz "TITEXTED" + .asciz "TIPRGMED" + .asciz "TIDMED" + .asciz "TITABLED" + .asciz "TIGRAPH" + .asciz "TIWINDED" + .asciz "TIEQUED" + .asciz "TIHOME" diff --git a/pch/src/tigcc-archive/gray.s b/pch/src/tigcc-archive/gray.s new file mode 100644 index 0000000..6369811 --- /dev/null +++ b/pch/src/tigcc-archive/gray.s @@ -0,0 +1,675 @@ +|****************************************************************************** +| +| project name: GrayScale-Support for TIGCC +| author: thomas.nussbaumer@gmx.net +| Julien Muchembled (original implementation for UniversalOS) +| +| +| compatible with HW1/HW2 on all AMS versions up to 2.05 +| +|****************************************************************************** + +|------------------------------------------------------------------------------ +| uncomment the following global to simulate HW2 on the VTI +| (this will not use port 70001D, therefore it flickers extremely; additionally +| the complete HW detection is bypassed and always reports HW2) +|------------------------------------------------------------------------------ +|.globl ALWAYS_HW2_TESTING + + + .xdef GrayOn,GrayOff,__D_plane,__L_plane,__gray_handle,__gray_hw_type + .xdef __switch_cnt,__gray_old_int1_hw1,__gray_old_int1_hw2 + .xdef __gray_sync_n_count,__gray_plane_index + .xdef __gray_dbl_offset,__L_plane2,__D_plane2 + +.even +|============================================================================== +| EXPORTED: GrayOn function (turn grayscales on) - trashes d1/a0/a1 +|============================================================================== +GrayOn: + move.w (__gray_handle,%pc),%d0 | if __gray_handle is not 0 we have + bne __gray_return_immediately | already allocated memory -> out here + move.l %a5,-(%sp) | we have more than 2 ROM_CALLs + move.l 0xc8.w,%a5 | so we should optimize + lea (__switch_cnt,%pc),%a0 | reset plane switch counter to 0 + clr.l (%a0) + bsr.s __gray_check_hw_version | evaluate HW version and store it + lea (__gray_hw_type,%pc),%a0 + move.w %d0,(%a0) + bsr __gray_init_mem | allocate and initialize memory + move.l (%sp)+,%a5 + move.w (__gray_handle,%pc),%d0 + bne __gray_init_handler | jump to interrupt handler setup if + | memory was allocated correctly + |moveq #0x0,%d0 | otherwise return 0 (GrayOn failed) + rts +|============================================================================== +| checks for HW version (VTI is treated as HW1, because port 0x70001D is not +| emulated by the VTI and this would cause NEVER switch +| planes behaviour if we would use the HW2 support) +| +| returns 0 in d0.w for HW1 and 1 for HW2 +| +| IMPORTANT NOTE: This function patches 2 locations in the code of the +| grayscale support depending on the HW version. Patching the +| locations for both types IS necessary, because if a program +| is transfered from one calc to another one the default values +| got already overwritten (if program was not archived) +|============================================================================== +__gray_check_hw_version: +.ifdef ALWAYS_HW2_TESTING + bra.s __always_hw2_proceed +.endif + move.l %a5,%d0 + and.l #0xE00000,%d0 | get the ROM base + move.l %d0,%a0 + moveq #0,%d0 + move.l 260(%a0),%a1 | get pointer to the hardware param block + add.l #0x10000,%a0 + cmp.l %a0,%a1 | check if the HW parameter block is near + bcc.s __gray_patches_for_hw1 | if it is too far, it is HW1 + cmp.w #22,(%a1) | check if the parameter block contains HW + bls.s __gray_patches_for_hw1 | if it is too small, it is HW1 + cmp.l #1,22(%a1) | check the hardware version + beq.s __gray_patches_for_hw1 | if not 1, it is HW2 (or an unknown HW) + |-------------------------------------------------------------------------- + | check for VTI (trick suggested by Julien Muchembled) + | optimized by Lionel Debroux + |-------------------------------------------------------------------------- + trap #12 | enter supervisor mode. returns old (%sr) in %d0.w + move.w #0x3000,%sr | set a non-existing flag in %sr (but keep s-flag !!) + move.w %d0,%d1 | save %d0.w content in %d1 + move.w %sr,%d0 | get %sr content and check for non-existing flag + move.w %d1,%sr | restore old %sr. + lsl.w #3,%d0 + bpl.s __gray_hw2type_detected | flag not set -> no VTI + |-------------------------------------------------------------------------- + | HW1 detected + |-------------------------------------------------------------------------- + moveq #0,%d0 + |-------------------------------------------------------------------------- + | patches code for HW1 version + | + | necessary memory == 1 plane + 8 Bytes == 3848 + | + | the additionally 8 bytes are necessary for rounding later to a multiple + | of 8 + |-------------------------------------------------------------------------- +__gray_patches_for_hw1: + lea (__gray_size_to_allocate,%pc),%a0 + move.w #0x0f08,(%a0) + clr.w (__gray_size_to_add-__gray_size_to_allocate,%a0) + rts + |-------------------------------------------------------------------------- + | HW2 detected + |-------------------------------------------------------------------------- +__gray_hw2type_detected: +.ifdef ALWAYS_HW2_TESTING +__always_hw2_proceed: +.endif + moveq #1,%d0 + |-------------------------------------------------------------------------- + | patches code for HW2 version + | + | necessary memory == 2 planes + 8 Bytes == 7688 + | + | the additionally 8 bytes are necessary for rounding later to a multiple + | of 8 + |-------------------------------------------------------------------------- + lea (__gray_size_to_allocate,%pc),%a0 + move.w #0x1e08,(%a0) + move.w #0xf00,(__gray_size_to_add - __gray_size_to_allocate,%a0) + rts +__gray_hw_type: | stores HW type (0==HW1 or VTI 1==HW2) + .word 0 +|============================================================================== +| Interrupt 1 handler for HW1 +|============================================================================== +__gray_int1_handler_hw1: + movem.l %d0/%a0,-(%a7) + |-------------------------------------------------------------------------- + | Load skip counter and increment it (count = (count+1)&0x3). Skip any + | further operation if count is 1, 2 or 3. This means that every 4th call + | of the INT1 handler is a candidate for a plane switch + |-------------------------------------------------------------------------- + lea (__gray_skipcount,%pc),%a0 + addq.b #1,(%a0) + andi.b #0x3,(%a0)+ | IMPORTANT: a0 points now to __gray_phase! + bne.s __gray_proceed_old + |-------------------------------------------------------------------------- + | to evaluate which plane we use counter __gray_phase. This counter + | performs the following counting 8->4->0->8. + | 0 will use D_plane pointer + | 4 will use L_plane pointer + | (8 will be skipped, so it stays at D_plane) + |-------------------------------------------------------------------------- + move.w (%a0),%d0 + subq.w #4,%d0 | subtract 4 from phase counter + bcc.s __gray_store | not negative -> don't reset + moveq #0x8,%d0 | reset phase counter to 8 +__gray_store: + move.w %d0,(%a0) | store new phase counter value + cmp.b #8,%d0 + beq.s __gray_proceed_old | for value 8 we do nothing (dark plane + | stays active) + lea (__D_plane,%pc),%a0 + |-------------------------------------------------------------------------- + | doublebuffer extension ... add content of __gray_dbl_offset to %d0 + |-------------------------------------------------------------------------- + add.w (__gray_dbl_offset-__D_plane,%a0),%d0 + suba.w %d0,%a0 + move.l (%a0),%d0 | load the address of this plane + lsr.l #3,%d0 | reduce to address / 8 + move.w %d0,0x600010 | set new plane startaddress + lea (__switch_cnt,%pc),%a0 | increment switch count + addq.l #1,(%a0) +__gray_proceed_old: + movem.l (%a7)+,%d0/%a0 + |-------------------------------------------------------------------------- + | JUMP to previous installed interrupt handler + |-------------------------------------------------------------------------- + .word 0x4ef9 | "JMP address" opcode +__gray_old_int1_hw1: + .long 0x00000000 | address of old int1 gots stored here +__gray_dummy1: | NOT used yet (just for alignment) + .byte 0x00 +|------------------------------------------------------------------------------ +| __gray_skipcount is a one byte counter which performs the following counting: +| 3 -> 0 -> 1 -> 2 -> 3 +|------------------------------------------------------------------------------ +__gray_skipcount: + .byte 0x03 +__gray_phase: + .word 0x04 | performs: 4->0->8->4 +__switch_cnt: + .long 0x00000000 +|============================================================================== +| INTERNAL: allocates memory +| +| modifies: __gray_handle +| __gray_used_mem +| __L_plane +| +| Note: __D_plane will not be changed by this function! (will be set by +| __gray_init_handler) +|============================================================================== +__gray_init_mem: + |-------------------------------------------------------------------------- + | HeapAllocHigh(HW1=3848 bytes or HW2=7688 bytes) + |-------------------------------------------------------------------------- + movea.l (0x92*4,%a5),%a0 /* HeapAllocHigh */ + .word 0x4878 | opcode of "PEA #value" +__gray_size_to_allocate: | the size gets patched !! + .word 0x1e08 + jsr (%a0) + addq.w #4,%a7 + lea (__gray_handle,%pc),%a0 + move.w %d0,(%a0)+ | store handle in handle variable + beq.s __gray_init_return | alloc failed (handle=0) -> out here + clr.w (%a0) | clears __gray_dbl_offset + |-------------------------------------------------------------------------- + | HeapDeref(__gray_handle) + |-------------------------------------------------------------------------- + move.w %d0,-(%a7) + movea.l (0x96*4,%a5),%a0 /* HeapDeref */ + jsr (%a0) + addq.l #2,%a7 + |-------------------------------------------------------------------------- + | align memory address to next 8-byte boundary and store address in + | __gray_used_mem + | + | for HW1: __L_plane gets set to the same address as __gray_used_mem + | for HW2: __L_plane gets set to __gray_used_mem + 0xf00 + |-------------------------------------------------------------------------- + move.l %a0,%d0 + addq.l #7,%d0 + andi.b #0xF8,%d0 + lea (__gray_used_mem,%pc),%a0 + move.l %d0,(%a0) + .word 0x0680 | opcode of "ADDI.L #value,%a0" + .word 0x0000 +__gray_size_to_add: + .word 0x0F00 | gets patched (HW1:0 HW2:0x0f00) + move.l %d0,(__L_plane - __gray_used_mem,%a0) +__gray_init_return: + rts + +|------------------------------------------------------------------------------ +| handle to allocated memory used by grayscale +|------------------------------------------------------------------------------ +__gray_handle: + .word 0 + +|------------------------------------------------------------------------------ +| DOUBLEBUFFER extension +|------------------------------------------------------------------------------ +__gray_dbl_offset: | has to be directly AFTER __gray_handle!! + .word 0 +__L_plane2: + .long 0x0 +__D_plane2: + .long 0x0 + +|------------------------------------------------------------------------------ +| pointer to light plane +| HW1: same as __gray_used_mem +| HW2: __gray_used_mem + 0xf00 +|------------------------------------------------------------------------------ +__L_plane: + .long 0x00004c00 +|------------------------------------------------------------------------------ +| pointer to dark plane (set by __gray_init_handler) +| HW1: 0x4c00 +| HW2: same as __gray_used_mem +|------------------------------------------------------------------------------ +__D_plane: + .long 0x00004c00 +|------------------------------------------------------------------------------ +| pointer to allocated memory ALIGNED to 8-byte boundary +|------------------------------------------------------------------------------ +__gray_used_mem: + .long 0x00004c00 +|------------------------------------------------------------------------------ +| This variable is very hard to describe. Indeed this isn't one variable, +| but two variables combined in one. +| +| Description will be added later .... +|------------------------------------------------------------------------------ +__gray_sync_n_count: + .word 0x0000 +|------------------------------------------------------------------------------ +| holds the index of the plane which should be drawn next (NOTE: this label +| is never addressed directly, but indirectly from label __gray_sync_n_count. +| So don't move it do somewhere else!) +|------------------------------------------------------------------------------ +__gray_plane_index: + .word 0x0000 +|============================================================================== +| Interrupt 1 handler for HW2 +| +| port 70001D (bit 7) is used to synchronized to the LCD hardware. Here are the +| docs of this port (taken from Johan Eilert's j89hw.txt) +| +| $70001D RW ($06) +| :7 Toggles every FS (every time the LCD restarts at line 0) +| :6-4 - +| :3 Battery checker bit B (? ???) +| :2 ? (set) +| :1 Screen enable (clear this bit to shut down LCD) +| :0 Battery checker bit A (? enable $600000:2) +| (AMS:) The battery checker bits must both be set (AB=11) prior to +| checking the voltage level with $600000:2. Then, after use, bit B +| must be cleared (AB=10) while the battery trig hardware settles to +| the "rest" voltage value (%111). Finally, both bits should be +| cleared. +|============================================================================== +__gray_int1_handler_hw2: + move.w %sr,-(%a7) | save content of status register on stack + move.w #0x2700,%sr | disable ALL interrupts (no one should + | interrupt us ...) + movem.l %d0-%d7/%a0-%a6,-(%a7) +__gray_startagain: + moveq #0x0,%d1 + lea (__gray_sync_n_count,%pc),%a0 + move.w (%a0),%d0 + bne.s __gray_copy_first_or_sec | there is a third of the plane left to + | copy -> do it now! + move.l (%a0),%d0 +.ifdef ALWAYS_HW2_TESTING + move.b %d0,%d1 + eor.b #0x80,%d1 +.else + move.b 0x70001D,%d1 | get flipping bit + eor.b %d0,%d1 + bpl __gray_to_oldint | not flipped yet -> proceed to previous + | installed int handler +.endif + eor.l %d1,(%a0) | store new flip "bit" and reset the + | work left status + + |-------------------------------------------------------------------------- + | NOTE: if we detect a pageflip we start our copying work with the lowest + | third. this way it will not interfere with the LCD hardware refresh + | + | The 3 thirds are copied in the following order: + | + | last third -> first third -> second third + |-------------------------------------------------------------------------- + move.w #0xA00,%d0 +__gray_copy_next_third: + addq.w #1,(%a0)+ + bra.s __gray_perform_copying +__gray_copy_first_or_sec: + |-------------------------------------------------------------------------- + | if __gray_sync_n_count == 1 -> copy first third of screen + | otherwise -> set __gray_sync_n_count to 0 and copy second third of screen + |-------------------------------------------------------------------------- + subq.w #1,%d0 + beq.s __gray_copy_next_third + clr.w (%a0)+ + move.w #0x500,%d0 | setup to copy second third of screen +__gray_perform_copying: + move.b (%a0),%d1 | fetch index of plane to draw next + beq __gray_update_index | skip index 0 -> stay at darkplane + + |-------------------------------------------------------------------------- + | If we'll come here we will copy 1 third of the screen from a specific + | plane to the video buffer at 0x4c00. Register D0 holds the offset of + | which third should be copied and register D1 contains the "index" of the + | "source" plane + | + | index = 0 -> darkplane (skipped, will not come here!) + | index = 4 -> darkplane + | index = 8 -> lightplane + | + | Due to the fact that the indices are cycled from 8 down to 0 the skipped + | index 0 causes the darkplane to stay active twice as long as the light + | plane. + | + | The copying is performed in a kind of "hardcore" style by using 13 + | registers. This way 52 Bytes are copied with a single instruction. + |-------------------------------------------------------------------------- + + |-------------------------------------------------------------------------- + | doublebuffer extension ... add content of __gray_dbl_offset to %d0 + |-------------------------------------------------------------------------- + add.w (__gray_dbl_offset,%pc),%d1 + neg.w %d1 + movea.l (__gray_used_mem,%pc,%d1.w),%a0 + + lea 0x4C00.w,%a1 + adda.w %d0,%a0 + adda.w %d0,%a1 + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x34,%a1) | size of this instruction: 6 bytes + movem.l (%a0)+,%d0-%d7/%a2-%a6 | size of this instruction: 4 bytes + movem.l %d0-%d7/%a2-%a6,(0x68,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x9C,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0xD0,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x104,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x138,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x16C,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x1A0,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x1D4,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x208,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x23C,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x270,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x2A4,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x2D8,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x30C,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x340,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x374,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x3A8,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x3DC,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x410,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x444,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x478,%a1) + movem.l (%a0)+,%d0-%d7/%a2-%a6 + movem.l %d0-%d7/%a2-%a6,(0x4AC,%a1) + movem.l (%a0)+,%d0-%d7 + movem.l %d0-%d7,(0x4E0,%a1) + + |-------------------------------------------------------------------------- + | evaluate if there is still a third of the screen to copy or if we + | should proceed to the next plane + |-------------------------------------------------------------------------- +__gray_update_index: + lea (__gray_sync_n_count,%pc),%a0 + move.w (%a0)+,%d0 + beq __gray_startagain | no third left to copy -> check again + | the pageflip bit if yet a pageflip + | had occured + subq.w #1,%d0 + bne.s __gray_to_oldint | if there is "copy work" left -> + | don't modify the plane to display + + lea (__switch_cnt,%pc),%a1 | increment switch count here, because + addq.l #1,(%a1) | a complete page was drawn if we come here + + subq.b #4,(%a0) | cycle __gray_plane_index by decrementing + bcc.s __gray_to_oldint | it and wrap around to 8 if negative. + move.b #0x8,(%a0) +__gray_to_oldint: + movem.l (%a7)+,%d0-%d7/%a0-%a6 + move.w (%a7)+,%sr | restore content of status register + |-------------------------------------------------------------------------- + | JUMP to previous installed interrupt handler + |-------------------------------------------------------------------------- + .word 0x4ef9 | opcode of "JMP address" instruction +__gray_old_int1_hw2: + .long 0x00000000 +|============================================================================== +| INTERNAL: initialize grayscale handler +|============================================================================== +__gray_init_handler: + lea (__L_plane,%pc),%a0 + move.w #0x3BF,%d1 + move.w (__gray_hw_type,%pc),%d0 + beq.s __gray_init_hw1_handler + + |-------------------------------------------------------------------------- + | HW2 specific initializations: + | + | (1) set __D_plane to __gray_used_mem + | (2) copy content of 0x4c00 to darkplane + | (3) "backup" old INT1 handler in __gray_old_int1_hw2 (the address part + | of a JUMP address instruction at the end of the HW2 int handler) + | (4) install our own INT1 HW2 handler + |-------------------------------------------------------------------------- + movea.l (__gray_used_mem,%pc),%a1 + move.l %a1,(0x4,%a0) | set __D_plane + lea 0x4C00.w,%a0 + move.w %d1,%d0 +__gray_cpy_d_plane: + move.l (%a0)+,(%a1)+ + dbf %d0, __gray_cpy_d_plane + lea (__gray_int1_handler_hw2,%pc),%a0 + + | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + | the following command should be unnecessary; I commented it out (TOM) + | (__L_plane should be already set by __gray_init_mem) + | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + |move.l %a1,(__L_plane - __gray_int1_handler_hw2,%a0) + + move.l 0x64,(__gray_old_int1_hw2 - __gray_int1_handler_hw2,%a0) + bra.s __gray_init_proceed + |-------------------------------------------------------------------------- + | HW1 specific initializations: + | + | (1) "backup" old INT1 handler in __gray_old_int1_hw1 (the address part + | of a JUMP address instruction at the end of the HW1 int handler) + | (2) install our own INT1 HW1 handler + |-------------------------------------------------------------------------- +__gray_init_hw1_handler: + move.l (%a0),%a1 + lea (__gray_int1_handler_hw1,%pc),%a0 + move.l 0x64,(__gray_old_int1_hw1 - __gray_int1_handler_hw1,%a0) +__gray_init_proceed: + move.l %a0,%d2 + lea 0x600001,%a0 + moveq.l #2,%d0 + bclr.b %d0,(%a0) + move.l %d2,0x64:w + bset.b %d0,(%a0) +__gray_clr_l_plane: + |-------------------------------------------------------------------------- + | clear light plane (done for both HW types) + |-------------------------------------------------------------------------- + clr.l (%a1)+ + dbf %d1, __gray_clr_l_plane + |-------------------------------------------------------------------------- + | PortSet(__D_plane,239,127) + |-------------------------------------------------------------------------- + move.l #0xEF007F,-(%a7) + move.l (__D_plane,%pc),-(%a7) + movea.l 0xC8,%a0 + movea.l (0x1A2*4,%a0),%a1 /* PortSet */ + jsr (%a1) + addq.w #8,%a7 +__gray_ok: + lea (__L_plane,%pc),%a0 + lea (__L_plane2,%pc),%a1 + move.l (%a0)+,(%a1)+ | copy __L_plane to __L_plane2 + move.l (%a0)+,(%a1)+ | copy __D_plane to __D_plane2 +__gray_return_immediately: + moveq #0x1,%d0 + rts +|============================================================================== +| EXPORTED: GrayOff function (turn grayscales off) +| NOTE: ALWAYS returns 1 !! +|============================================================================== +GrayOff: + lea (__gray_handle,%pc),%a0 + tst.w (%a0) + beq __gray_return_immediately | no handle? -> nothing to do + move.w (%a0),-(%a7) + clr.l (%a0) | 0->handle AND(!!) 0->__gray_dbl_offset + lea 0x600001,%a0 + move.w (__gray_hw_type,%pc),%d0 + beq.s __gray_hw1_cleanup + |-------------------------------------------------------------------------- + | cleanup for HW2 calcs + |-------------------------------------------------------------------------- + moveq.l #2,%d0 + bclr.b %d0,(%a0) + move.l (__gray_old_int1_hw2,%pc),0x64:w | restore old INT1 handler + bset.b %d0,(%a0) + movea.l (__D_plane,%pc),%a1 + lea 0x4C00.w,%a0 + move.w #0x3BF,%d0 | copy content of darkplane to 0x4c00 +__gray_dark2lcd: + move.l (%a1)+,(%a0)+ + dbf %d0, __gray_dark2lcd + bra.s __gray_continue_cleanup + |-------------------------------------------------------------------------- + | cleanup for HW1 calcs (on HW1 0x4c00 is used as darkplane. We haven't to + | set it) + |-------------------------------------------------------------------------- +__gray_hw1_cleanup: + move.w #0x980,(0x600010-0x600001,%a0) | restore used plane to 0x4c00 + move.l (__gray_old_int1_hw1,%pc),0x40064 | restore old INT1 handler + | (We can use 0x40064 here because it is HW1 only.) + +__gray_continue_cleanup: + lea (__L_plane,%pc),%a0 | restore plane pointers to 0x4c00 for sure + lea 0x4C00.w,%a1 + move.l %a1,(%a0)+ + move.l %a1,(%a0)+ + move.l %a1,(%a0) + |-------------------------------------------------------------------------- + | HeapFree(__gray_handle) + |-------------------------------------------------------------------------- + movea.l 0xc8,%a0 + movea.l (0x97*4,%a0),%a0 /* HeapFree */ + jsr (%a0) + addq.l #2,%a7 + |-------------------------------------------------------------------------- + | PortRestore() + |-------------------------------------------------------------------------- + movea.l 0xc8,%a0 + movea.l (0x1A3*4,%a0),%a0 /* PortRestore */ + jsr (%a0) + lea (__gray_sync_n_count,%pc),%a0 + clr.l (%a0) +__gray_off_out: + jbra __gray_ok + +| ############################################################################# +| Revision History +| ############################################################################# +| +| Revision 3.17 2006/10/30 07:24:15 Kevin Kofler +| Bumped version to 3.55. +| Size optimization by Martial Demolins (use moveq instead of bclr/bset #imm). +| +| Revision 3.16 2005/10/09 01:48:20 Kevin Kofler +| Bumped version to 3.54. +| Size optimization by Jesse Frey (register saving, ROM_CALL optimization), +| spelling/typo fixes by Kevin Kofler. +| +| Revision 3.15 2005/08/22 20:23:40 Kevin Kofler +| Bumped version to 3.53. +| Fixed calls to GrayOn with grayscale already enabled. +| +| Revision 3.14 2005/07/02 02:56:36 Kevin Kofler +| Bumped version to 3.52. +| +| Revision 3.13 2005/06/11 05:58:27 Kevin Kofler +| Removed commented-out junk. +| Remove Id and Log tags. +| +| Revision 3.12 2005/06/07 16:51:00 Lionel Debroux +| Optimized the routine for size: saved 40 bytes. +| +| Revision 3.11 2004/02/25 03:49:03 Kevin Kofler +| Don't use 0x40000 to set interrupts on code path that affect HW3. +| Use 0xE00000 as ROM_base mask instead of 0x600000. +| Bumped version to 3.51. +| +| Revision 3.10 2002/04/05 11:34:23 tnussb +| (1) Resets now __D_plane2,__L_plane2 and __gray_dbl_offset at end of GrayOn() +| to make sure nothing happens if doublebuffer macros get called without +| setting a buffer first. Nevertheless NO program should call one of the +| doublebuffer macros without setting a buffer previously. +| (2) Some further size optimizations. Now the size is exactly as long as +| without before the integration of doublebuffering. Quite smart, isn't it? +| More functionality, some minor drawbacks fixed and no increase in size ... +| (3) Changed return value of GrayOff() function to void. +| +| Revision 3.9 2002/04/04 18:50:36 tnussb +| first working version of internal doublebuffer support (not checked on +| real calcs yet, but on the VTI) +| +| Revision 3.8 2002/04/04 16:39:05 tnussb +| Debug version checked in previously. This one is the correct one. +| +| Revision 3.7 2002/04/04 16:35:20 tnussb +| (1) documentation of HW2 interrupt handler heavily extended +| (2) HW2: plane switch counting fixed (was incremented too often previously) +| (3) global ALWAYS_HW2_TESTING added which can be used to force the use of +| HW2 grayscales. Now the HW2 grayscales can be tested on the VTI if +| this global is defined. Of course this will flicker extremely, because +| the VTI doesn't simulate port 70001D, but its still better than no +| testing possibility. +| (4) don't trashes %sr on HW2 anymore (restores previous setting) +| (5) This version was tested on a real HW1 and a real HW2 calc. It works. +| (Thanx to Sebastian Reichelt and stoopid guy) +| +| Revision 3.6 2002/04/04 11:58:19 tnussb +| (1) size optimizations +| (2) unnecessary cleanup removed from GrayOff() +| (3) interrupt handler for HW1 rewritten (uses now plane pointer directly) +| (4) "heavily" documented +| +| Revision 3.5 2002/04/04 11:54:39 tnussb +| (1) exports __gray_old_int1_hw1 and __gray_old_int1_hw2. this way it is +| possible to modify them after grayscales are turned on +| (2) comments changed to GNU Assembler style +| [NOTE: CVS time and date doesn't fit to real implementation data] +| +| Revision 3.0 2002/04/04 11:50:56 tnussb +| grayscale support used for TIGCC up to version v0.93 +| [NOTE: CVS time and date doesn't fit to real implementation data] +| diff --git a/pch/src/tigcc-archive/grayversion.c b/pch/src/tigcc-archive/grayversion.c new file mode 100644 index 0000000..bc04501 --- /dev/null +++ b/pch/src/tigcc-archive/grayversion.c @@ -0,0 +1 @@ +volatile char __gray_version[] = "[TIGCCLIB GraySupport v3.50 "__DATE__" "__TIME__"]"; diff --git a/pch/src/tigcc-archive/homestore.s b/pch/src/tigcc-archive/homestore.s new file mode 100644 index 0000000..34c4a11 --- /dev/null +++ b/pch/src/tigcc-archive/homestore.s @@ -0,0 +1,22 @@ +| Workaround for HomePushEStack which does not redraw the Home screen +| Copyright (C) Samuel Stearley, 2002 + +.data + .even + .xdef HomeStore +HomeStore: + move.l %a3,-(%sp) + move.l 0xC8,%a1 + move.l 0x2A3*4(%a1),%a3 + move.l (%a3),-(%sp) + lea .L__NewHook,%a0 + move.l %a0,(%a3) + move.l 0x10F*4(%a1),%a0 /* HomePushEStack */ + jsr (%a0) + move.l (%sp)+,(%a3) + move.l (%sp)+,%a3 + rts +.L__NewHook: + move.l 4(%sp),%a0 + move.w #0x700,(%a0) + rts diff --git a/pch/src/tigcc-archive/homestorepair.c b/pch/src/tigcc-archive/homestorepair.c new file mode 100644 index 0000000..c35e18a --- /dev/null +++ b/pch/src/tigcc-archive/homestorepair.c @@ -0,0 +1,25 @@ +#include +#include +#include + +__ATTR_LIB_C__ void HomeStorePair(HANDLE Entry, HANDLE Ans) +{ + HANDLE hNode; + TRY + hNode = HS_newFIFONode (); + ONERR + HeapFree (Entry); + if (Ans != Entry) + HeapFree (Ans); + PASS; + ENDTRY + TRY + FIFO_NODE *Node = HeapDeref (hNode); + Node->Entry.Expr = Entry; + Node->Ans.Expr = Ans; + HS_pushEmptyFIFONode (hNode); + ONERR + HS_freeFIFONode (hNode); + PASS; + ENDTRY +} diff --git a/pch/src/tigcc-archive/hrealloc_throw.s b/pch/src/tigcc-archive/hrealloc_throw.s new file mode 100644 index 0000000..7015036 --- /dev/null +++ b/pch/src/tigcc-archive/hrealloc_throw.s @@ -0,0 +1,17 @@ +| Warning: This routine has the attribute __ATTR_TIOS__! +| It is a simple wrapper for a TIOS function. + +.data + .even + .xdef HeapReallocThrow +HeapReallocThrow: + lea.l .L__finished+2,%a0 + move.l (%sp)+,(%a0) + move.l 0xC8,%a0 + move.l (%a0,0x9D*4),%a0 /* HeapRealloc */ + jsr (%a0) + tst.w %d0 + jbne .L__finished + .word 0xA000+670 +.L__finished: + jmp.l 0:l diff --git a/pch/src/tigcc-archive/isextalnum.s b/pch/src/tigcc-archive/isextalnum.s new file mode 100644 index 0000000..608853a --- /dev/null +++ b/pch/src/tigcc-archive/isextalnum.s @@ -0,0 +1,5 @@ +.data + .even + .xdef _extalnum_list +_extalnum_list: + .long 0, 65283, -16777337, -16777465, -1106176, 8192, -32769, -32769 diff --git a/pch/src/tigcc-archive/isextpunct.s b/pch/src/tigcc-archive/isextpunct.s new file mode 100644 index 0000000..653a8bb --- /dev/null +++ b/pch/src/tigcc-archive/isextpunct.s @@ -0,0 +1,5 @@ +.data + .even + .xdef _extpunct_list +_extpunct_list: + .long 12648447, -16842500, 16777336, 16777464, 1106175, -8193, 32768, 32768 diff --git a/pch/src/tigcc-archive/kbd_queue.s b/pch/src/tigcc-archive/kbd_queue.s new file mode 100644 index 0000000..2597a21 --- /dev/null +++ b/pch/src/tigcc-archive/kbd_queue.s @@ -0,0 +1,7 @@ +.data + .xdef kbd_queue + .even +kbd_queue: + moveq.l #6,%d0 + trap #9 + rts diff --git a/pch/src/tigcc-archive/loaddll_throw.s b/pch/src/tigcc-archive/loaddll_throw.s new file mode 100644 index 0000000..7346e94 --- /dev/null +++ b/pch/src/tigcc-archive/loaddll_throw.s @@ -0,0 +1,14 @@ +| Warning: This routine has the attribute __ATTR_LIB_C__! +| It is a simple wrapper for a C function. + + .even + .xdef LoadDLLThrow +LoadDLLThrow: + lea.l .L__finished+2,%a0 + move.l (%sp)+,(%a0) + jbsr LoadDLL + tst.w %d0 + jbeq .L__finished + .word 0xA000+850 +.L__finished: + jmp.l 0:l diff --git a/pch/src/tigcc-archive/lshrdi.s b/pch/src/tigcc-archive/lshrdi.s new file mode 100644 index 0000000..8fc3a30 --- /dev/null +++ b/pch/src/tigcc-archive/lshrdi.s @@ -0,0 +1,24 @@ +|lshrdi3 routine copyright (C) 2002, Kevin Kofler + +.data + xdef __lshrdi3 + .even +__lshrdi3: + tst.w 12(%a7) + bne.s .L__lshrdi3_return0 + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + move.w 14(%a7),%d2 + beq.s .L__lshrdi3_returnn + subq.w #1,%d2 +.L__lshrdi3_loop: + lsr.l #1,%d0 + roxr.l #1,%d1 + dbra.w %d2,.L__lshrdi3_loop +.L__lshrdi3_returnn: + rts + +.L__lshrdi3_return0: + moveq.l #0,%d0 + moveq.l #0,%d1 + rts diff --git a/pch/src/tigcc-archive/malloc_throw.s b/pch/src/tigcc-archive/malloc_throw.s new file mode 100644 index 0000000..99fd656 --- /dev/null +++ b/pch/src/tigcc-archive/malloc_throw.s @@ -0,0 +1,18 @@ +| Warning: This routine has the attribute __ATTR_TIOS__! +| It is a simple wrapper for a TIOS function. + +.data + .even + .xdef malloc_throw,HeapAllocPtrThrow +malloc_throw: +HeapAllocPtrThrow: + lea.l .L__finished+2,%a0 + move.l (%sp)+,(%a0) + move.l 0xC8,%a0 + move.l (%a0,0xA2*4),%a0 /* HeapAllocPtr */ + jsr (%a0) + move.l %a0,%d0 + jbne .L__finished + .word 0xA000+670 +.L__finished: + jmp.l 0:l diff --git a/pch/src/tigcc-archive/moddi.s b/pch/src/tigcc-archive/moddi.s new file mode 100644 index 0000000..3df288e --- /dev/null +++ b/pch/src/tigcc-archive/moddi.s @@ -0,0 +1,30 @@ +|moddi3 routine copyright (C) 2002, Kevin Kofler +|WARNING: Division by 0 will be handled the same way as in the unsigned variant. +| For my __umoddi3, this means: +| A division by 0 will not cause an exception, but just crash in an +| infinite loop! + +.data + xdef __moddi3 + .even +__moddi3: + tst.b 12(%a7) + bge.s .L__moddi3_denom_positive + neg.l 16(%a7) + negx.l 12(%a7) +.L__moddi3_denom_positive: + tst.b 4(%a7) + blt.s .L__moddi3_numer_negative +.L__moddi3_umoddi3: + jbra __umoddi3 + +.L__moddi3_numer_negative: + neg.l 8(%a7) + negx.l 4(%a7) + lea.l (.L__moddi3_return_jump+2,%PC),%a0 + move.l (%a7)+,(%a0) + bsr.s .L__moddi3_umoddi3 + neg.l %d1 + negx.l %d0 +.L__moddi3_return_jump: + jmp.l 0:l diff --git a/pch/src/tigcc-archive/modsi.s b/pch/src/tigcc-archive/modsi.s new file mode 100644 index 0000000..0e5681b --- /dev/null +++ b/pch/src/tigcc-archive/modsi.s @@ -0,0 +1,6 @@ +.data + .xdef __modsi3 + .even +__modsi3: + move.w #0x2A9*4,%d2 /* _ms32s32 */ + jra __div_entry diff --git a/pch/src/tigcc-archive/mulbf.s b/pch/src/tigcc-archive/mulbf.s new file mode 100644 index 0000000..6d94350 --- /dev/null +++ b/pch/src/tigcc-archive/mulbf.s @@ -0,0 +1,6 @@ +.data + .xdef __mulbf3 + .even +__mulbf3: + moveq.l #8,%d0 + bra __fp_entry diff --git a/pch/src/tigcc-archive/muldi.s b/pch/src/tigcc-archive/muldi.s new file mode 100644 index 0000000..3dbbbac --- /dev/null +++ b/pch/src/tigcc-archive/muldi.s @@ -0,0 +1,58 @@ +|muldi3 routine copyright (C) 2002, Kevin Kofler + +.data + .xdef __muldi3 + .even +__muldi3: + move.w 18(%a7),%d0 + mulu 4(%a7),%d0 + move.w 16(%a7),%d2 + mulu 6(%a7),%d2 + add.w %d2,%d0 + move.w 14(%a7),%d2 + mulu 8(%a7),%d2 + add.w %d2,%d0 + move.w 12(%a7),%d2 + mulu 10(%a7),%d2 + add.w %d2,%d0 + swap %d0 + clr.w %d0 + + move.w 18(%a7),%d2 + mulu 6(%a7),%d2 + add.l %d2,%d0 + move.w 16(%a7),%d2 + mulu 8(%a7),%d2 + add.l %d2,%d0 + move.w 14(%a7),%d2 + mulu 10(%a7),%d2 + add.l %d2,%d0 + + move.w 18(%a7),%d1 + mulu 8(%a7),%d1 + swap %d1 + add.w %d1,%d0 + clr.w %d1 + swap %d0 + addx.w %d1,%d0 + swap %d0 + + move.w 16(%a7),%d2 + mulu 10(%a7),%d2 + swap %d2 + add.w %d2,%d0 + clr.w %d2 + swap %d0 + addx.w %d2,%d0 + swap %d0 + add.l %d2,%d1 + moveq.l #0,%d2 + addx.l %d2,%d0 + + move.w 18(%a7),%d2 + mulu 10(%a7),%d2 + add.l %d2,%d1 + moveq.l #0,%d2 + addx.l %d2,%d0 + + rts diff --git a/pch/src/tigcc-archive/mulsi.s b/pch/src/tigcc-archive/mulsi.s new file mode 100644 index 0000000..f38f06c --- /dev/null +++ b/pch/src/tigcc-archive/mulsi.s @@ -0,0 +1,17 @@ +.data + .xdef __mulsi3 + .even +__mulsi3: + move.l (4,%sp),%d1 + move.l (8,%sp),%d2 + move.l %d2,%d0 + mulu %d1,%d0 + swap %d2 + mulu %d1,%d2 + swap %d1 + mulu (10,%sp),%d1 + add.w %d1,%d2 + swap %d2 + clr.w %d2 + add.l %d2,%d0 + rts diff --git a/pch/src/tigcc-archive/negbf.s b/pch/src/tigcc-archive/negbf.s new file mode 100644 index 0000000..ce9246e --- /dev/null +++ b/pch/src/tigcc-archive/negbf.s @@ -0,0 +1,6 @@ +.data + .xdef __negbf2 + .even +__negbf2: + moveq.l #16,%d0 + bra __fp_entry diff --git a/pch/src/tigcc-archive/nocallback.s b/pch/src/tigcc-archive/nocallback.s new file mode 100644 index 0000000..13aa4d3 --- /dev/null +++ b/pch/src/tigcc-archive/nocallback.s @@ -0,0 +1,8 @@ +| Warning: This routine has the attribute __ATTR_TIOS_CALLBACK__! + +.data + .xdef NoCallBack + .even +NoCallBack: + moveq.l #1,%d0 + rts diff --git a/pch/src/tigcc-archive/printf.s b/pch/src/tigcc-archive/printf.s new file mode 100644 index 0000000..75fa37b --- /dev/null +++ b/pch/src/tigcc-archive/printf.s @@ -0,0 +1,17 @@ +| Warning: This routine has the attribute __ATTR_TIOS__! + +.data + .xdef printf + .even +printf: + movea.l 0xC8,%a0 + movea.l (%a0,0x14C),%a0 /* vcbprintf */ + lea (%a0,32),%a0 + movea.w (%a0),%a1 + pea (%sp,8) + move.l (%sp,8),-(%sp) + clr.l -(%sp) + pea fputchar + jsr (%a0.l,%a1) + lea (%sp,16),%sp + rts diff --git a/pch/src/tigcc-archive/push_longint.s b/pch/src/tigcc-archive/push_longint.s new file mode 100644 index 0000000..0be4332 --- /dev/null +++ b/pch/src/tigcc-archive/push_longint.s @@ -0,0 +1,43 @@ +.data + .xdef push_longint + .even +push_longint: +| Saving %d2 as well is a really dirty trick to reserve four extra bytes on the stack. +| Only two are needed, but this is smaller than subtracting and adding. + movem.l %d2-%d6/%a5,-(%sp) +| Put address of push_quantum into %a5. + move.l 0xC8,%a5 + move.l (%a5,3000),%a5 /* push_quantum */ +| %d4: Number of bytes. + clr.w %d4 +| Put POSINT_TAG in %d6. + moveq.l #31,%d6 +| Move parameter to %d3. + move.l 28(%sp),%d3 +| If it is zero, the value should be zero bytes long. + jbeq .L__finished +| If negative, put NEGINT_TAG in %d6 and negate it. + jbge .L__mainloop + moveq.l #32,%d6 + neg.l %d3 +.L__mainloop: +| Push rightmost quantum of the value. + move.w %d3,(%sp) + jsr (%a5) +| Add 1 to the number of bytes. + addq.w #1,%d4 +| Shift the value to the right by one quantum. + lsr.l #8,%d3 +| Finished if remaining value is zero. + jbne .L__mainloop +.L__finished: +| Push number of bytes. + move.w %d4,(%sp) + jsr (%a5) +| Push tag. + move.w %d6,(%sp) + jsr (%a5) +| See above. +| There is no problem in "restoring" %d2, since it may be trashed. + movem.l (%sp)+,%d2-%d6/%a5 + rts diff --git a/pch/src/tigcc-archive/push_longlongint.s b/pch/src/tigcc-archive/push_longlongint.s new file mode 100644 index 0000000..4599a0c --- /dev/null +++ b/pch/src/tigcc-archive/push_longlongint.s @@ -0,0 +1,50 @@ +.data + .xdef push_longlongint + .even +push_longlongint: +| Saving %d2 as well is a really dirty trick to reserve four extra bytes on the stack. +| Only two are needed, but this is smaller than subtracting and adding. + movem.l %d2-%d7/%a5,-(%sp) +| Put address of push_quantum into %a5. + move.l 0xC8,%a5 + move.l (%a5,3000),%a5 /* push_quantum */ +| %d7: Number of bytes. + clr.w %d7 +| Put POSINT_TAG in %d6. + moveq.l #31,%d6 +| Move parameter to %d3/%d4. + movem.l 32(%sp),%d3-%d4 +| If negative, put NEGINT_TAG in %d6 and negate it. +| We only need to look at %d3 because of how numbers are stored. + tst.l %d3 + jbge .L__mainloop + moveq.l #32,%d6 + neg.l %d4 + negx.l %d3 +.L__mainloop: +| Finished if remaining value is zero. + move.l %d3,%d0 + or.l %d4,%d0 + jbeq .L__finished +| Push rightmost quantum of the value. + move.w %d4,(%sp) + jsr (%a5) +| Add 1 to the number of bytes. + addq.w #1,%d7 +| Shift the value to the right by one quantum. + move.b %d3,%d4 + lsr.l #8,%d3 + ror.l #8,%d4 +| Always repeat the loop at this point. + jbra .L__mainloop +.L__finished: +| Push number of bytes. + move.w %d7,(%sp) + jsr (%a5) +| Push tag. + move.w %d6,(%sp) + jsr (%a5) +| See above. +| There is no problem in "restoring" %d2, since it may be trashed. + movem.l (%sp)+,%d2-%d7/%a5 + rts diff --git a/pch/src/tigcc-archive/push_shortint.s b/pch/src/tigcc-archive/push_shortint.s new file mode 100644 index 0000000..3a6e5d4 --- /dev/null +++ b/pch/src/tigcc-archive/push_shortint.s @@ -0,0 +1,43 @@ +.data + .xdef push_shortint + .even +push_shortint: +| Saving %d2 as well is a really dirty trick to reserve four extra bytes on the stack. +| Only two are needed, but this is smaller than subtracting and adding. + movem.l %d2-%d6/%a5,-(%sp) +| Put address of push_quantum into %a5. + move.l 0xC8,%a5 + move.l (%a5,3000),%a5 /* push_quantum */ +| %d4: Number of bytes. + clr.w %d4 +| Put POSINT_TAG in %d6. + moveq.l #31,%d6 +| Move parameter to %d3. + move.w 28(%sp),%d3 +| If it is zero, the value should be zero bytes long. + jbeq .L__finished +| If negative, put NEGINT_TAG in %d6 and negate it. + jbge .L__mainloop + moveq.l #32,%d6 + neg.w %d3 +.L__mainloop: +| Push rightmost quantum of the value. + move.w %d3,(%sp) + jsr (%a5) +| Add 1 to the number of bytes. + addq.w #1,%d4 +| Shift the value to the right by one quantum. + lsr.w #8,%d3 +| Finished if remaining value is zero. + jbne .L__mainloop +.L__finished: +| Push number of bytes. + move.w %d4,(%sp) + jsr (%a5) +| Push tag. + move.w %d6,(%sp) + jsr (%a5) +| See above. +| There is no problem in "restoring" %d2, since it may be trashed. + movem.l (%sp)+,%d2-%d6/%a5 + rts diff --git a/pch/src/tigcc-archive/pushfifonode.c b/pch/src/tigcc-archive/pushfifonode.c new file mode 100644 index 0000000..827e910 --- /dev/null +++ b/pch/src/tigcc-archive/pushfifonode.c @@ -0,0 +1,16 @@ +#include +#include + +__ATTR_LIB_C__ __HS_pushEmptyFIFONode__type__ __get_HS_pushEmptyFIFONode(void) +{ + short *Ptr = (void*)HomePushEStack, *EndPtr = Ptr + 0x80; + for (; (unsigned long)Ptr < (unsigned long)EndPtr; Ptr++) + if (*Ptr == 0x4EBA) /* bsr */ + { + Ptr++; + void *Addr = (char*)Ptr + *Ptr; + if (Addr != HS_newFIFONode) + return Addr; + } + ER_throw (410); +} diff --git a/pch/src/tigcc-archive/puts.s b/pch/src/tigcc-archive/puts.s new file mode 100644 index 0000000..e0e59c4 --- /dev/null +++ b/pch/src/tigcc-archive/puts.s @@ -0,0 +1,13 @@ +.data + .xdef puts + .even +.L__puts_1: + move.l %a0,(%sp,4) + move.w %d0,-(%sp) + jsr fputchar + addq.l #2,%sp +puts: + move.l (%sp,4),%a0 + move.b (%a0)+,%d0 + jbne .L__puts_1 + rts diff --git a/pch/src/tigcc-archive/qsort.c b/pch/src/tigcc-archive/qsort.c new file mode 100644 index 0000000..4857fdc --- /dev/null +++ b/pch/src/tigcc-archive/qsort.c @@ -0,0 +1,22 @@ +#include + +// Do not use register a5; callback function might need it. +register long __tbl asm ("a5"); + +__ATTR_LIB_C__ void qsort(void *list, short num_items, short size, compare_t cmp_func) +{ + unsigned short gap,byte_gap,i,j; + char *p,*a,*b,temp; + for (gap=((unsigned short)num_items)>>1; gap>0; gap>>=1) // Yes, this is not a quicksort, + { // but works fast enough... + byte_gap=gap*(unsigned short)size; + for(i=byte_gap; i<((unsigned short)num_items)*(unsigned short)size; i+=size) + for(p=(char*)list+i-byte_gap; p>=(char*)list; p-= byte_gap) + { + a=p; b=p+byte_gap; + if(cmp_func(a,b)<=0) break; + for(j=size;j;j--) + temp=*a, *a++=*b, *b++=temp; + } + } +} diff --git a/pch/src/tigcc-archive/rand.s b/pch/src/tigcc-archive/rand.s new file mode 100644 index 0000000..80a15d4 --- /dev/null +++ b/pch/src/tigcc-archive/rand.s @@ -0,0 +1,26 @@ +.data + .xdef rand,__randseed + .even +rand: + lea __randseed(%pc),%a0 + move.l #0x41C64E6D,%d2 + move.l (%a0),%d1 + move.l %d2,%d0 + mulu %d1,%d0 + swap %d2 + mulu %d1,%d2 + swap %d1 + mulu #0x4E6D,%d1 + add.w %d1,%d2 + swap %d2 + clr.w %d2 + add.l %d2,%d0 + add.l #12345,%d0 + move.l %d0,(%a0) + lsr.l #8,%d0 + and.w #32767,%d0 + rts +.data + .even +__randseed: + .long 1 diff --git a/pch/src/tigcc-archive/realloc.s b/pch/src/tigcc-archive/realloc.s new file mode 100644 index 0000000..07a62ed --- /dev/null +++ b/pch/src/tigcc-archive/realloc.s @@ -0,0 +1,38 @@ +.data + .xdef realloc + .even +realloc: + link.w %a6,#0 + movm.l %d3/%a2-%a3,-(%sp) + move.l 0xC8,%a2 + move.l 12(%a6),%a3 /* new size */ + tst.l 8(%a6) /* address==0? */ + jbeq .L__realloc_0 + move.l 8(%a6),%a0 /* address */ + move.w -2(%a0),%d3 /* handle */ + move.w %d3,-(%sp) + move.l 636(%a2),%a0 /* HeapUnlock */ + jsr (%a0) + pea 2(%a3) /* reallocate a block of size+2 bytes */ + move.w %d3,-(%sp) + move.l 628(%a2),%a0 /* HeapRealloc */ + jsr (%a0) + tst.w %d0 + jbne .L__realloc_1 + move.l 604(%a2),%a0 /* HeapFree */ + jsr (%a0) + sub.l %a0,%a0 + jbra .L__realloc_2 +.L__realloc_0: + pea (%a3) + move.l 648(%a2),%a0 /* HeapAllocPtr */ + jsr (%a0) + jbra .L__realloc_2 +.L__realloc_1: + move.l 612(%a2),%a0 /* HLock */ + jsr (%a0) + addq.l #2,%a0 /* skip the handle */ +.L__realloc_2: + movm.l -12(%a6),%d3/%a2-%a3 + unlk %a6 + rts diff --git a/pch/src/tigcc-archive/realloc_throw.s b/pch/src/tigcc-archive/realloc_throw.s new file mode 100644 index 0000000..d625a4d --- /dev/null +++ b/pch/src/tigcc-archive/realloc_throw.s @@ -0,0 +1,12 @@ +.data + .even + .xdef realloc_throw +realloc_throw: + lea.l .L__finished+2,%a0 + move.l (%sp)+,(%a0) + jbsr realloc + move.l %a0,%d0 + jbne .L__finished + .word 0xA000+670 +.L__finished: + jmp.l 0:l diff --git a/pch/src/tigcc-archive/registertimer.s b/pch/src/tigcc-archive/registertimer.s new file mode 100644 index 0000000..25e93a5 --- /dev/null +++ b/pch/src/tigcc-archive/registertimer.s @@ -0,0 +1,56 @@ +.data + .xdef OSVRegisterTimer + .even +OSVRegisterTimer: + move.w (%sp,4),%d0 + subq.w #1,%d0 + cmpi.w #2,%d0 + bcc.s .L__timer_rfai + muls.w #12,%d0 + move.l 0x74,%a0 + cmpi.l #132133782,(%a0,-4) + beq.s .L__timer_rins + lea .L__timer_told(%pc),%a1 + move.l %a0,(%a1) + lea .L__timer_rti5(%pc),%a0 +.L__timer_rins: + lea -32(%a0,%d0.w),%a1 + cmpi.l #-1,(%a1) + bne.s .L__timer_rfai + move.l (%sp,6),(%a1) + move.l (%sp,6),(%a1,4) + move.l (%sp,10),(%a1,8) + move.l %a0,0x40074 + moveq #1,%d0 + rts +.L__timer_rfai: + clr.w %d0 + rts +.data + .even +.L__timer_ttab: + .long -1,0,0,-1,0,0 +.L__timer_told: + .long 0 + .long 132133782 /* magic */ +.data + .even +.L__timer_rti5: + move.w #0x2700,%sr + movem.l %d0-%d7/%a0-%a6,-(%sp) + lea .L__timer_ttab(%pc),%a4 + moveq #1,%d4 +.L__timer_i5lp: + cmpi.l #-1,(%a4) + beq.s .L__timer_i5sk + subq.l #1,(%a4,4) + bne.s .L__timer_i5sk + move.l (%a4),(%a4,4) + move.l (%a4,8),%a0 + jsr (%a0) +.L__timer_i5sk: + lea (%a4,12),%a4 + dbra %d4,.L__timer_i5lp + movem.l (%sp)+,%d0-%d7/%a0-%a6 + move.l .L__timer_told(%pc),-(%sp) + rts diff --git a/pch/src/tigcc-archive/rename.c b/pch/src/tigcc-archive/rename.c new file mode 100644 index 0000000..7624bfb --- /dev/null +++ b/pch/src/tigcc-archive/rename.c @@ -0,0 +1,10 @@ +#include +#include + +__ATTR_LIB_C__ short rename(const char *old, const char *new) +{ + char sym[100],*sptrold=sym,*sptrnew; + *sptrold=0; while((*++sptrold=*old++)); + sptrnew=sptrold; while((*++sptrnew=*new++)); + return SymMove(sptrold,sptrnew)-1; +} diff --git a/pch/src/tigcc-archive/rowread.s b/pch/src/tigcc-archive/rowread.s new file mode 100644 index 0000000..e7440da --- /dev/null +++ b/pch/src/tigcc-archive/rowread.s @@ -0,0 +1,16 @@ +.data + .xdef _rowread +_rowread: +| Write the mask to the port + move.w (%sp,4),0x600018 +| Wait for a few milliseconds until the I/O can return a valid value + move.w #24,%d0 +0: + dbra %d0,0b +| Read the port and write it to %d0 (return value register) + move.b 0x60001B,%d0 +| Invert the byte + not.b %d0 + and.w #0xFF,%d0 +| Return + rts diff --git a/pch/src/tigcc-archive/sprite16.c b/pch/src/tigcc-archive/sprite16.c new file mode 100644 index 0000000..5db2853 --- /dev/null +++ b/pch/src/tigcc-archive/sprite16.c @@ -0,0 +1,18 @@ +#include + +__ATTR_LIB_C__ void Sprite16(short x, short y, short h, unsigned short *sprite, void *buff, short mode) +{ + long addr=(long)buff+30*y+((x>>3)&0xfffe),d1; + unsigned short cnt=16-(x&15),data; + for(;h--;addr+=30) + { + data=*sprite++; + if(mode==SPRT_AND) *(long*)addr&=~((long)~data< + +__ATTR_LIB_C__ void Sprite32(short x, short y, short h, unsigned long *sprite, void *buff, short mode) +{ + long addr=(long)buff+30*y+((x>>3)&0xfffe); + unsigned long data,d1,d2; + short cnt=x&15,ccnt=32-cnt; + for(;h--;addr+=30) + { + data=*sprite++; + if(mode==SPRT_AND) + { + data=~data; + *(long*)addr&=~(data>>cnt),*(long*)(addr+4)&=~(data<>cnt; d2=data< + +__ATTR_LIB_C__ void Sprite8(short x, short y, short h, unsigned char *sprite, void *buff, short mode) +{ + long addr=(long)buff+30*y+((x>>3)&0xfffe),d1; + unsigned short cnt=24-(x&15),data; + for(;h--;addr+=30) + { + data=*sprite++; + if(mode==SPRT_AND) *(long*)addr&=~((long)(~data&0xff)< +#include + +__ATTR_LIB_C__ long strtol(const char *nptr, char **endptr, short base) +{ + const unsigned char *s=nptr; + unsigned long acc,cutoff,cb; + unsigned short c,cutlim,neg=0; + short any; + do {c=*s++;} while (c==' '); + if(c=='-'||c==0xAD) neg=1, c=*s++; + else if (c=='+') c=*s++; + if((base==0||base==16)&&c=='0'&&(*s=='x'||*s=='X')) + { + c=s[1]; s+=2; base=16; + } + if(base==0) base=c=='0'?8:10; + cb=neg?0x80000000:0x7FFFFFFF; + asm volatile("\n" + " move.l %3,%%d1\n" + " move.l %2,%%d0\n" + " move.l 0xC8,%%a0\n" + " move.l (%%a0,2728),%%a0\n" + " jsr (%%a0)\n" + " move.l %%d1,%0\n" + " move.l %3,%%d1\n" + " move.l %2,%%d0\n" + " move.l 0xC8,%%a0\n" + " move.l (%%a0,2732),%%a0\n" + " jsr (%%a0)\n" + " move.w %%d1,%1":"=g"(cutoff),"=g"(cutlim):"g"((unsigned long)base), + "g"(cb):"a0","a1","d0","d1","d2"); + for(acc=0,any=0;;c=*s++) + { + if(isdigit(c)) c-='0'; + else if(isalpha(c)) c-=isupper(c)?'A'-10:'a'-10; + else break; + if (c>=(unsigned short)base) break; + if (any<0||acc>cutoff||(acc==cutoff&&c>cutlim)) any=-1; + else + { + any=1; + asm volatile("\n" + " move.l %1,%%d0\n" + " mulu %2,%%d0\n" + " move.l %1,%%d1\n" + " swap %%d1\n" + " mulu %2,%%d1\n" + " swap %%d1\n" + " clr.w %%d1\n" + " add.l %%d1,%%d0\n" + " move.l %%d0,%0":"=g"(acc):"g"(acc),"g"(base):"d0","d1","d2"); + acc+=c; + } + } + if (any<0) acc=neg?0x80000000:0x7FFFFFFF; + else if(neg) acc=-acc; + if(endptr!=0) *endptr=(char*)(any?(char*)s-1:nptr); + return (acc); +} diff --git a/pch/src/tigcc-archive/strtoul.c b/pch/src/tigcc-archive/strtoul.c new file mode 100644 index 0000000..dd32f67 --- /dev/null +++ b/pch/src/tigcc-archive/strtoul.c @@ -0,0 +1,57 @@ +#include +#include + +__ATTR_LIB_C__ unsigned long strtoul(const char *nptr, char **endptr, short base) +{ + const unsigned char *s=nptr; + unsigned long acc,cutoff; + unsigned short c,cutlim; + short any; + do {c=*s++;} while (c==' '); + if (c=='+') c=*s++; + if((base==0||base==16)&&c=='0'&&(*s=='x'||*s=='X')) + { + c=s[1]; s+=2; base=16; + } + if(base==0) base=c=='0'?8:10; + asm volatile("\n" + " move.l #-1,%%d1\n" + " move.l %2,%%d0\n" + " move.l 0xC8,%%a0\n" + " move.l (%%a0,2728),%%a0\n" + " jsr (%%a0)\n" + " move.l %%d1,%0\n" + " move.l #-1,%%d1\n" + " move.l %2,%%d0\n" + " move.l 0xC8,%%a0\n" + " move.l (%%a0,2732),%%a0\n" + " jsr (%%a0)\n" + " move.w %%d1,%1":"=g"(cutoff),"=g"(cutlim):"g"((unsigned long)base): + "a0","a1","d0","d1","d2"); + for(acc=0,any=0;;c=*s++) + { + if(isdigit(c)) c-='0'; + else if(isalpha(c)) c-=isupper(c)?'A'-10:'a'-10; + else break; + if(c>=(unsigned short)base) break; + if(any<0||acc>cutoff||(acc==cutoff&&c>cutlim)) any=-1; + else + { + any=1; + asm volatile("\n" + " move.l %1,%%d0\n" + " mulu %2,%%d0\n" + " move.l %1,%%d1\n" + " swap %%d1\n" + " mulu %2,%%d1\n" + " swap %%d1\n" + " clr.w %%d1\n" + " add.l %%d1,%%d0\n" + " move.l %%d0,%0":"=g"(acc):"g"(acc),"g"(base):"d0","d1","d2"); + acc+=c; + } + } + if(any<0) acc=0xFFFFFFFF; + if(endptr!=0) *endptr=(char*)(any?(char*)s-1:nptr); + return(acc); +} diff --git a/pch/src/tigcc-archive/subbf.s b/pch/src/tigcc-archive/subbf.s new file mode 100644 index 0000000..304a197 --- /dev/null +++ b/pch/src/tigcc-archive/subbf.s @@ -0,0 +1,6 @@ +.data + .xdef __subbf3 + .even +__subbf3: + moveq.l #4,%d0 + bra __fp_entry diff --git a/pch/src/tigcc-archive/tigcc.tpr b/pch/src/tigcc-archive/tigcc.tpr new file mode 100644 index 0000000..73e6b50 --- /dev/null +++ b/pch/src/tigcc-archive/tigcc.tpr @@ -0,0 +1,147 @@ +[Settings] +Archive=1 +Pack=0 +Packed Variable= +Project Name=TIGCCLib +GCC Switches=-Os -Wall -W -Wwrite-strings -fomit-frame-pointer -D_GENERIC_ARCHIVE -DREGPARM1_STDLIB +Assembler Switches=-g -t +Linker Switches= +GNU Linker Switches= +BSR Patch=1 +Debug Info=0 +Standard Library=0 +Command Line= +Post-Build Process= +GNU Assembler Switches= +Flash OS=0 +Fargo=0 +Use Data Variable=0 +Data Variable= +Copy Data Variable=1 +Copy Data Variable if Archived=1 +Initialize BSS=1 +Optimize NOPs=1 +Optimize Returns=1 +Optimize Branches=1 +Optimize Moves=1 +Optimize Tests=1 +Optimize Calculations=1 +Remove Unused Sections=1 +Cut Unused Ranges=1 +Reorder Sections=1 +Merge Constants=1 +Binary Output=0 + + +[Library Options] +Use TI-89=0 +Use TI-92 Plus=0 +Use V200=0 +Optimize Calc Consts=0 +Use Kernel=0 +Use PreOS=0 +Minimum AMS Version Defined=0 +Minimum AMS Version=1.00 +Unofficial OS Support=0 +Reloc Format=Unknown +ROM Call Format=Unknown +BSS Ref Format=Unknown +Data Ref Format=Unknown +Use F-Line Jumps=0 +Use 4-Byte F-Line Jumps=0 +Optimize ROM Calls=0 +Use Internal F-Line Emulator=0 +Use Return Value=0 +Enable Error Return=0 +Save Screen=0 +[File Editing] +Open File=C:\Cygwin\home\Paul\gtc-clean\gtc\pch\src\tigcc-archive\sprite16.c +[Included Files] +C File 1=qsort.c +C File 2=bsearch.c +C File 3=atoi.c +C File 4=atol.c +C File 5=strtol.c +C File 6=strtoul.c +C File 7=fopen.c +C File 8=fclose.c +C File 9=ftell.c +C File 10=fseek.c +C File 11=fputc.c +C File 12=fgetc.c +C File 13=fwrite.c +C File 14=fread.c +C File 15=fgets.c +C File 16=rename.c +C File 17=unlink.c +C File 18=tmpnam.c +C File 19=fsetbufsize.c +C File 20=sprite8.c +C File 21=sprite16.c +C File 22=sprite32.c +C File 23=pushfifonode.c +C File 24=homestorepair.c +C File 25=dll.c +C File 26=grayversion.c +GNU Assembler File 1=bzero.s +GNU Assembler File 2=bcopy.s +GNU Assembler File 3=mulsi.s +GNU Assembler File 4=divsi.s +GNU Assembler File 5=udivsi.s +GNU Assembler File 6=modsi.s +GNU Assembler File 7=umodsi.s +GNU Assembler File 8=diventry.s +GNU Assembler File 9=muldi.s +GNU Assembler File 10=ashldi.s +GNU Assembler File 11=ashrdi.s +GNU Assembler File 12=lshrdi.s +GNU Assembler File 13=divdi.s +GNU Assembler File 14=udivdi.s +GNU Assembler File 15=moddi.s +GNU Assembler File 16=umoddi.s +GNU Assembler File 17=addbf.s +GNU Assembler File 18=subbf.s +GNU Assembler File 19=mulbf.s +GNU Assembler File 20=divbf.s +GNU Assembler File 21=negbf.s +GNU Assembler File 22=floatbf.s +GNU Assembler File 23=fixbf.s +GNU Assembler File 24=cmpbf.s +GNU Assembler File 25=fpentry.s +GNU Assembler File 26=fpcall.s +GNU Assembler File 27=bc.s +GNU Assembler File 28=gray.s +GNU Assembler File 29=rand.s +GNU Assembler File 30=realloc.s +GNU Assembler File 31=calloc.s +GNU Assembler File 32=clrscr.s +GNU Assembler File 33=printf.s +GNU Assembler File 34=fprintf.s +GNU Assembler File 35=fputchar.s +GNU Assembler File 36=puts.s +GNU Assembler File 37=strputchar.s +GNU Assembler File 38=fputs.s +GNU Assembler File 39=atof.s +GNU Assembler File 40=push_shortint.s +GNU Assembler File 41=push_longint.s +GNU Assembler File 42=push_longlongint.s +GNU Assembler File 43=nocallback.s +GNU Assembler File 44=kbd_queue.s +GNU Assembler File 45=registertimer.s +GNU Assembler File 46=freetimer.s +GNU Assembler File 47=getappid.s +GNU Assembler File 48=enter_ghost_space.s +GNU Assembler File 49=exit.s +GNU Assembler File 50=atexit.s +GNU Assembler File 51=assert.s +GNU Assembler File 52=rowread.s +GNU Assembler File 53=isextalnum.s +GNU Assembler File 54=isextpunct.s +GNU Assembler File 55=homestore.s +GNU Assembler File 56=dummyhandler.s +GNU Assembler File 57=malloc_throw.s +GNU Assembler File 58=calloc_throw.s +GNU Assembler File 59=realloc_throw.s +GNU Assembler File 60=hrealloc_throw.s +GNU Assembler File 61=loaddll_throw.s +Text File 1=License.txt diff --git a/pch/src/tigcc-archive/tmpnam.c b/pch/src/tigcc-archive/tmpnam.c new file mode 100644 index 0000000..14ea380 --- /dev/null +++ b/pch/src/tigcc-archive/tmpnam.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +//tmpnam implementation by Greg Dietsche +//email: gforce@calc.org +//webpage: http://gforce.calc.org/ + +__ATTR_LIB_C__ char *tmpnam(char *s) +{ + static char buff[10]={0}; //"\0 "; + register char *bptr=buff; + register short i; + + do { + for(i=1;i<9;i++) + bptr[i]=((rand()%25)+97); + } while(SymFind(bptr+9).offset); + + if(s) return strcpy(s,bptr+1); + else return bptr+1; +} diff --git a/pch/src/tigcc-archive/udivdi.s b/pch/src/tigcc-archive/udivdi.s new file mode 100644 index 0000000..f5c1588 --- /dev/null +++ b/pch/src/tigcc-archive/udivdi.s @@ -0,0 +1,43 @@ +|udivdi3 routine copyright (C) 2002, Kevin Kofler +|WARNING: A division by 0 will not cause an exception, but just crash in an +| infinite loop! + +.data + xdef __udivdi3 + .even +__udivdi3: + movem.l %d3-%d6,-(%a7) + move.l 20(%a7),%d4 + move.l 24(%a7),%d5 + move.l 28(%a7),%d2 + move.l 32(%a7),%d3 + moveq.l #0,%d0 + moveq.l #0,%d1 + + moveq.l #-1,%d6 +.L__udivdi3_shl: + addq.w #1,%d6 + add.l %d3,%d3 + addx.l %d2,%d2 + bcc.s .L__udivdi3_shl + roxr.l #1,%d2 + roxr.l #1,%d3 + +.L__udivdi3_shr: + add.l %d1,%d1 + addx.l %d0,%d0 + cmp.l %d2,%d4 + bne.s .L__udivdi3_cmp + cmp.l %d3,%d5 +.L__udivdi3_cmp: + bcs.s .L__udivdi3_skip + sub.l %d3,%d5 + subx.l %d2,%d4 + addq.l #1,%d1 +.L__udivdi3_skip: + lsr.l #1,%d2 + roxr.l #1,%d3 + dbra.w %d6,.L__udivdi3_shr + + movem.l (%a7)+,%d3-%d6 + rts diff --git a/pch/src/tigcc-archive/udivsi.s b/pch/src/tigcc-archive/udivsi.s new file mode 100644 index 0000000..260c27d --- /dev/null +++ b/pch/src/tigcc-archive/udivsi.s @@ -0,0 +1,6 @@ +.data + .xdef __udivsi3 + .even +__udivsi3: + move.w #0x2AA*4,%d2 /* _du32u32 */ + jra __div_entry diff --git a/pch/src/tigcc-archive/umoddi.s b/pch/src/tigcc-archive/umoddi.s new file mode 100644 index 0000000..57e71ed --- /dev/null +++ b/pch/src/tigcc-archive/umoddi.s @@ -0,0 +1,40 @@ +|umoddi3 routine copyright (C) 2002, Kevin Kofler +|WARNING: A division by 0 will not cause an exception, but just crash in an +| infinite loop! + +.data + xdef __umoddi3 + .even +__umoddi3: + movea.l %d3,%a0 + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + move.l 12(%a7),%d2 + move.l 16(%a7),%d3 + + movea.l %d4,%a1 + moveq.l #-1,%d4 +.L__umoddi3_shl: + addq.w #1,%d4 + add.l %d3,%d3 + addx.l %d2,%d2 + bcc.s .L__umoddi3_shl + roxr.l #1,%d2 + roxr.l #1,%d3 + +.L__umoddi3_shr: + cmp.l %d2,%d0 + bne.s .L__umoddi3_cmp + cmp.l %d3,%d1 +.L__umoddi3_cmp: + bcs.s .L__umoddi3_skip + sub.l %d3,%d1 + subx.l %d2,%d0 +.L__umoddi3_skip: + lsr.l #1,%d2 + roxr.l #1,%d3 + dbra.w %d4,.L__umoddi3_shr + + move.l %a1,%d4 + move.l %a0,%d3 + rts diff --git a/pch/src/tigcc-archive/umodsi.s b/pch/src/tigcc-archive/umodsi.s new file mode 100644 index 0000000..0a29b11 --- /dev/null +++ b/pch/src/tigcc-archive/umodsi.s @@ -0,0 +1,6 @@ +.data + .xdef __umodsi3 + .even +__umodsi3: + move.w #0x2AB*4,%d2 /* _mu32u32 */ + jra __div_entry diff --git a/pch/src/tigcc-archive/unlink.c b/pch/src/tigcc-archive/unlink.c new file mode 100644 index 0000000..9893009 --- /dev/null +++ b/pch/src/tigcc-archive/unlink.c @@ -0,0 +1,9 @@ +#include +#include + +__ATTR_LIB_C__ short unlink(const char *fname) +{ + char sym[50],*sptr=sym; + *sptr=0; while((*++sptr=*fname++)); + return SymDel(sptr)-1; +} diff --git a/pch/src/timath.pchsource b/pch/src/timath.pchsource new file mode 100644 index 0000000..e4a65d9 --- /dev/null +++ b/pch/src/timath.pchsource @@ -0,0 +1,116 @@ + +#var FIVE D((5.0)) +#var FOUR D((4.0)) +#var HALF D((0.5)) +#var HALF_PI D((1.570796326794897)) +#var MINUS_ONE D((-1.0)) +#var NAN D((*(float*)&(bcd){0x7FFF,0xAA00000000000000})) +#var NEGATIVE_INF D((*(float*)&(bcd){0xFFFF,0xAA00BB0000000000})) +#var NEGATIVE_ZERO D((*(float*)&(bcd){0x8000,0})) +#var ONE D((1.0)) +#var PI D((3.141592653589793)) +#var POSITIVE_INF D((*(float*)&(bcd){0x7FFF,0xAA00BB0000000000})) +#var POSITIVE_ZERO D((*(float*)&(bcd){0,0})) +#var TEN D((10.0)) +#var THREE D((3.0)) +#var TWO D((2.0)) +#var UNSIGNED_INF D((*(float*)&(bcd){0x7FFF,0xAA00CC0000000000})) +#var UNSIGNED_ZERO D((0.0)) +#var ZERO D((0.0)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var FALSE D(0) +#var TRUE D(1) + +#var ti_float typedef float ti_float; +#var abs(x) D(({typeof(x) __x = (x); __x >= 0 ? __x : -__x;})) +#var acos(x) D(_tios_float_1(F5,x,float)) +#var acosh(x) D(_tios_float_1(288,x,float)) +#var asin(x) D(_tios_float_1(F6,x,float)) +#var asinh(x) D(_tios_float_1(287,x,float)) +#var atan2(x,y) D(_tios_float_2(F8,x,y,float,float)) +#var atan(x) D(_tios_float_1(F7,x,float)) +#var atanh(x) D(_tios_float_1(289,x,float)) +#var bcd_to_float(a) D(({bcd __a=(a);*(float*)&__a;})) +#var bcd_var(a) D((*(bcd*)&(a))) +#var bcdadd(x,y) D(({bcd __x=(x),__y=(y);float __z=fadd(*(float*)&__x,*(float*)&__y);*(bcd*)&__z;})) +#var bcdbcd(x) D(({float __x=flt(x);*(bcd*)&__x;})) +#var bcdcmp(x,y) D(({bcd __x=(x),__y=(y);fcmp(*(float*)&__x,*(float*)&__y);})) +#var bcddiv(x,y) D(({bcd __x=(x),__y=(y);float __z=fdiv(*(float*)&__x,*(float*)&__y);*(bcd*)&__z;})) +#var bcdlong(x) D(({bcd __x=(x);trunc(*(float*)&__x);})) +#var bcdmul(x,y) D(({bcd __x=(x),__y=(y);float __z=fmul(*(float*)&__x,*(float*)&__y);*(bcd*)&__z;})) +#var bcdneg(x) D(({bcd __x=(x);float __y=fneg(*(float*)&__x);*(bcd*)&__y;})) +#var bcdsub(x,y) D(({bcd __x=(x),__y=(y);float __z=fsub(*(float*)&__x,*(float*)&__y);*(bcd*)&__z;})) +#var cacos D(_rom_call(void,(float,float,float*,float*),13A)) +#var cacosh D(_rom_call(void,(float,float,float*,float*),13D)) +#var casin D(_rom_call(void,(float,float,float*,float*),13B)) +#var casinh D(_rom_call(void,(float,float,float*,float*),13E)) +#var catan D(_rom_call(void,(float,float,float*,float*),13C)) +#var catanh D(_rom_call(void,(float,float,float*,float*),13F)) +#var ccos D(_rom_call(void,(float,float,float*,float*),140)) +#var ccosh D(_rom_call(void,(float,float,float*,float*),143)) +#var ceil(x) D(_tios_float_1(105,x,float)) +#var cexp D(_rom_call(void,(float,float,float*,float*),149)) +#var cln D(_rom_call(void,(float,float,float*,float*),147)) +#var clog10 D(_rom_call(void,(float,float,float*,float*),148)) +#var cos(x) D(_tios_float_1(F9,x,float)) +#var cosh(x) D(_tios_float_1(FC,x,float)) +#var csin D(_rom_call(void,(float,float,float*,float*),141)) +#var csinh D(_rom_call(void,(float,float,float*,float*),144)) +#var csqrt D(_rom_call(void,(float,float,float*,float*),146)) +#var ctan D(_rom_call(void,(float,float,float*,float*),142)) +#var ctanh D(_rom_call(void,(float,float,float*,float*),145)) +#var exp(x) D(_tios_float_1(FF,x,float)) +#var fabs(x) D(_tios_float_1(106,x,float)) +#var fadd(x,y) D(_tios_float_2(B6,x,y,float,float)) +#var fcmp D(_rom_call(long,(float,float),BB)) +#var fdiv(x,y) D(_tios_float_2(B9,x,y,float,float)) +#var FEXP(x,y) D((*(float*)&(bcd){0x4000+y,0x##x##LL<<4*(17-sizeof(#x))})) +#var FEXP_NEG(x,y) D((*(float*)&(bcd){0xC000+y,0x##x##LL<<4*(17-sizeof(#x))})) +#var float_to_bcd(a) D(({float __a=(a);*(bcd*)&__a;})) +#var floor(x) D(_tios_float_1(107,x,float)) +#var flt(x) D(_tios_float_1(BD,x,long)) +#var FLT(x,y...) D(((sizeof(#y)==1)?x##.0:x##.##y)) +#var FLT_NEG(x,y...) D(((sizeof(#y)==1)?-x##.0:-x##.##y)) +#var fmod(x,y) D(_tios_float_2(108,x,y,float,float)) +#var fmul(x,y) D(_tios_float_2(B8,x,y,float,float)) +#var fneg(x) D(_tios_float_1(BA,x,float)) +#var fpisanint D(_rom_call(short,(unsigned long long*,short),172)) +#var fpisodd D(_rom_call(short,(unsigned long long*,short),173)) +#var fsub(x,y) D(_tios_float_2(B7,x,y,float,float)) +#var hypot(x,y) D(({float __x=(x),__y=(y);sqrt(fadd(fmul((__x),(__x)),fmul((__y),(__y))));})) +#var init_float() D(((void)0)) +#var itrig D(_rom_call(void,(short,short,float*,float*),28A)) +#var ldexp10(x,e) D(({float __f=x;((bcd*)&__f)->exponent+=e;__f;})) +#var log(x) D(_tios_float_1(100,x,float)) +#var log10(x) D(_tios_float_1(101,x,float)) +#var modf(x,y) D(_tios_float_2(102,x,y,float,float*)) +#var pow(x,y) D(_tios_float_2(103,x,y,float,float)) +#var round12(x) D(_tios_float_1(174,x,float)) +#var round12_err(x,y) D(_tios_float_2(227,x,y,float,short)) +#var round14(x) D(_tios_float_1(175,x,float)) +#var sin(x) D(_tios_float_1(FA,x,float)) +#var sincos D(_rom_call(void,(float,short,float*,float*),286)) +#var sinh(x) D(_tios_float_1(FD,x,float)) +#var sqrt(x) D(_tios_float_1(104,x,float)) +#var tan(x) D(_tios_float_1(FB,x,float)) +#var tanh(x) D(_tios_float_1(FE,x,float)) +#var trig D(_rom_call(void,(short,short,const float*,float*,float*,float*),28B)) +#var trunc D(_rom_call(long,(float),BC)) +#var atof float atof(const char*)__ATTR_LIB_ASM__; +#var float_class D(_rom_call(short,(float),2FA)) +#var frexp10(x,y) D(_tios_float_2(2FB,x,y,float,__pshort)) +#var is_float_infinity D(_rom_call(short,(float),2FF)) +#var is_float_negative_zero D(_rom_call(short,(float),300)) +#var is_float_positive_zero D(_rom_call(short,(float),301)) +#var is_float_signed_infinity D(_rom_call(short,(float),302)) +#var is_float_transfinite D(_rom_call(short,(float),303)) +#var is_float_unsigned_inf_or_nan D(_rom_call(short,(float),304)) +#var is_float_unsigned_zero D(_rom_call(short,(float),305)) +#var is_inf D(_rom_call(short,(float),2FF)) +#var is_nan D(_rom_call(short,(float),306)) +#var is_nzero D(_rom_call(short,(float),300)) +#var is_pzero D(_rom_call(short,(float),301)) +#var is_sinf D(_rom_call(short,(float),302)) +#var is_transfinite D(_rom_call(short,(float),303)) +#var is_uinf_or_nan D(_rom_call(short,(float),304)) +#var is_uzero D(_rom_call(short,(float),305)) diff --git a/pch/src/tiosdlg-merge.pchmerge b/pch/src/tiosdlg-merge.pchmerge new file mode 100644 index 0000000..268f44d --- /dev/null +++ b/pch/src/tiosdlg-merge.pchmerge @@ -0,0 +1,6 @@ +tiosdlg.pchsource + +dialogs.pchsource +menus.pchsource +wingraph.pchsource +textedit.pchsource diff --git a/pch/src/values.pchsource b/pch/src/values.pchsource new file mode 100644 index 0000000..be1bdd7 --- /dev/null +++ b/pch/src/values.pchsource @@ -0,0 +1,30 @@ +#var MAXINT D(0x7FFF) +#var HIBITI D(0x8000) + + +#var _DEXPLEN D(15) +#var _EXPBASE D(10) +#var _FEXPLEN D(15) +#var _IEEE D(0) +#var BITSPERBYTE D(8) +#var DMAXEXP D(999) +#var DMAXPOWTWO D(3321) +#var DMINEXP D((-999)) +#var DSIGNIF D(64) +#var FMAXEXP D(999) +#var FMAXPOWTWO D(3321) +#var FMINEXP D((-999)) +#var FSIGNIF D(56) +#var HIBITL D(0x80000000L) +#var HIBITS D(0x8000) +#var LN_MAXDOUBLE D((2303.58509299)) +#var LN_MINDOUBLE D((-2300.2825079)) +#var MAXDOUBLE D((9.999999999999999e999)) +#var MAXFLOAT D((9.999999999999999e999)) +#var MAXLONG D(0x7FFFFFFFL) +#var MAXSHORT D(0x7FFF) +#var MINDOUBLE D((1e-999)) +#var MINFLOAT D((1e-999)) +#var bcd typedef struct{unsigned short exponent;unsigned long long mantissa;}bcd; +#var ti_float typedef float ti_float; + diff --git a/pch/src/vat-le.pchsource b/pch/src/vat-le.pchsource new file mode 100644 index 0000000..e7c6c9a --- /dev/null +++ b/pch/src/vat-le.pchsource @@ -0,0 +1,124 @@ +#var SYMSTR_CONST(s) D(((SYM_STR)(("\0"s)+sizeof(s)))) +#var VATSTR D(SYMSTR) + +#var __Folder_Del D(_rom_call(short,(const char*,short),66)) + + +#var H_NULL D(0) +#var HS_NULL D(((HSym){0,0})) +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var CF_NONE D(0) +#var CF_CONVERT D(1) +#var CF_ENHANCED D(2) +#var CF_NEW D(3) + +#var ESI typedef ESQ*ESI; + +#var FO_SINGLE_FOLDER D(1) +#var FO_RECURSE D(2) +#var FO_SKIP_TEMPS D(4) +#var FO_NOTEMPS D(4) +#var FO_RETURN_TWINS D(8) +#var FO_CKTWINS D(8) +#var FO_RETURN_FOLDER D(16) +#var FO_SKIP_COLLAPSE D(32) + +#var FOP_UNLOCK D(0) +#var FOP_LOCK D(1) +#var FOP_ALL_FOLDERS D(128) + +#var MAIN_FOLDER D(2) +#var FOLDER_TABLE D(3) +#var NOT_FOUND D(4) +#var BAD_FOLDER D(5) + +#var HANDLE typedef unsigned short HANDLE; +#var HSym typedef struct{HANDLE folder;unsigned short offset;}HSym; +#var HSYM D(HSym) +#var MULTI_EXPR typedef struct{unsigned short Size;ESQ Expr[];}MULTI_EXPR; +#var SYM_ENTRY typedef struct{char name[8];unsigned short compat;union{unsigned short flags_n;struct{unsigned short busy:1,local:1,flag1_5:1,flag1_4:1,collapsed:1,twin:1,archived:1,in_view:1;unsigned short folder:1,overwritten:1,checked:1,hidden:1,locked:1,statvar:1,graph_ref_1:1,graph_ref_0:1;}bits;}flags;HANDLE handle;}SYM_ENTRY; +#var SYM_STR typedef CESI SYM_STR; +#var SF_GREF1 D(1) +#var SF_GREF2 D(2) +#var SF_STATVAR D(4) +#var SF_LOCKED D(8) +#var SF_HIDDEN D(16) +#var SF_OPEN D(16) +#var SF_CHECKED D(32) +#var SF_OVERWRITTEN D(64) +#var SF_FOLDER D(128) +#var SF_INVIEW D(256) +#var SF_ARCHIVED D(512) +#var SF_TWIN D(1024) +#var SF_COLLAPSED D(2048) +#var SF_LOCAL D(16384) +#var SF_BUSY D(-32768) + +#var $(s) D(SYMSTR_CONST(#s)) +#var AddSymToFolder D(_rom_call(HSym,(SYM_STR,SYM_STR),70)) +#var checkCurrent D(_rom_call(HSym,(SYM_STR,ESQ),121)) +#var CheckLinkLockFlag D(_rom_call(void,(const SYM_ENTRY*),7F)) +#var CheckReservedName D(_rom_call(short,(SYM_STR),8B)) +#var CheckSysFunc D(_rom_call(short,(const char*,__pushort),89)) +#var ClearUserDef D(_rom_call(void,(HANDLE),7E)) +#var DerefSym D(_rom_call(SYM_ENTRY*,(HSym),79)) +#var EM_moveSymFromExtMem D(_rom_call(short,(SYM_STR,HSym),161)) +#var EM_moveSymToExtMem D(_rom_call(short,(SYM_STR,HSym),162)) +#var EM_twinSymFromExtMem D(_rom_call(HSym,(SYM_STR,HSym),166)) +#var EX_stoBCD D(_rom_call(void,(unsigned char*,float*),C0)) +#var FindSymInFolder D(_rom_call(HSym,(SYM_STR,const char*),71)) +#var FolderAdd D(_rom_call(HANDLE,(SYM_STR),64)) +#var FolderAddTemp D(_rom_call(const char*,(void),73)) +#var FolderClear(c) D(__Folder_Del((c),1)) +#var FolderCount D(_rom_call(unsigned short,(const SYM_ENTRY*),6B)) +#var FolderCur D(_rom_call(short,(SYM_STR,short),65)) +#var FolderCurTemp D(_rom_call(short,(SYM_STR),72)) +#var FolderDel(c) D(__Folder_Del((c),0)) +#var FolderDelAllTemp D(_rom_call(void,(short),75)) +#var FolderDelTemp D(_rom_call(void,(void),74)) +#var FolderFind D(_rom_call(short,(SYM_STR),67)) +#var FolderGetCur D(_rom_call(void,(char*),68)) +#var FolderOp D(_rom_call(short,(SYM_STR,short),69)) +#var FolderRename D(_rom_call(short,(const char*,const char*),6A)) +#var HSymDel D(_rom_call(short,(HSym),5F)) +#var HSYMtoName D(_rom_call(short,(HSym,char*),7A)) +#var IsMainFolderStr D(_rom_call(short,(const char*),77)) +#var MakeHSym D(_rom_call(HSym,(HANDLE,const SYM_ENTRY*),282)) +#var partial_len D(_rom_call(unsigned long,(const char*,unsigned char*),11C)) +#var QSysProtected D(_rom_call(short,(ESQ),88)) +#var ResetSymFlags D(_rom_call(void,(short),8E)) +#var StrToTokN D(_rom_call(ESI,(const char*,unsigned char*),7B)) +#var SymAdd D(_rom_call(HSym,(SYM_STR),5C)) +#var SymAddMain D(_rom_call(HSym,(SYM_STR),5D)) +#var SymAddTwin D(_rom_call(HSym,(SYM_STR),27F)) +#var SymCmp D(_rom_call(short,(const char*,const char*),81)) +#var SymCpy0 D(_rom_call(void,(char*,const char*),83)) +#var SymCpy D(_rom_call(void,(char*,const char*),82)) +#var SymDel D(_rom_call(short,(SYM_STR),5E)) +#var SymDelTwin D(_rom_call(short,(SYM_ENTRY*),280)) +#var SymFind D(_rom_call(HSym,(SYM_STR),60)) +#var SymFindFirst D(_rom_call(SYM_ENTRY*,(SYM_STR,short),6C)) +#var SymFindFolderName D(_rom_call(char*,(void),6F)) +#var SymFindHome D(_rom_call(HSym,(SYM_STR),62)) +#var SymFindMain D(_rom_call(HSym,(SYM_STR),61)) +#var SymFindNext D(_rom_call(SYM_ENTRY*,(void),6D)) +#var SymFindPrev D(_rom_call(SYM_ENTRY*,(void),6E)) +#var SymFindPtr D(_rom_call(SYM_ENTRY*,(SYM_STR,short),283)) +#var SymMove D(_rom_call(short,(const char*,const char*),63)) +#var SYMSTR(s) D(({register unsigned short __slen=_rom_call(unsigned long,(const char*),27E)(s);ESI __tempstr=alloca(__slen+2);__tempstr[0]=0;_rom_call(void*,(void*,const void*,long),26A)(__tempstr+1,(s),__slen+1);__tempstr+__slen+1;})) +#var SymSysVar D(_rom_call(short,(const char*),8C)) +#var TempFolderName D(_rom_call(SYM_STR,(short),76)) +#var TokToStrN D(_rom_call(short,(unsigned char*,SYM_STR),7C)) +#var ValidateSymName D(_rom_call(short,(const char*),84)) +#var VarRecall D(_rom_call(HSym,(SYM_STR,short),85)) +#var VarStore D(_rom_call(HSym,(SYM_STR,short,short,...),86)) + +#var SymFindFoldername D(SymFindFolderName) + +#var OpenFile void *OpenFile(const char *)__ATTR_LIB_C__; +#var CloseFile void CloseFile(const char *)__ATTR_LIB_C__; diff --git a/pch/src/vat.pchsource b/pch/src/vat.pchsource new file mode 100644 index 0000000..0aa644a --- /dev/null +++ b/pch/src/vat.pchsource @@ -0,0 +1,141 @@ +#var SYMSTR_CONST(s) D(((SYM_STR)(("\0"s)+sizeof(s)))) +#var VATSTR D(SYMSTR) + +#var __Folder_Del D(_rom_call(short,(const char*,short),66)) + + +#var H_NULL D(0) +#var HS_NULL D(((HSym){0,0})) +#var NULL D(((void*)0)) +#var FALSE D(0) +#var TRUE D(1) + +#var ESQ typedef unsigned char ESQ; +#var CESI typedef const ESQ*CESI; +#var CF_NONE D(0) +#var CF_CONVERT D(1) +#var CF_ENHANCED D(2) +#var CF_NEW D(3) + +#var ESI typedef ESQ*ESI; +#var SEQ_INITC D(7) +#var DE_INITC D(8) +#var DE_FLDPIC D(9) +#var SOLVER_SYS_VARS D(10) +#var UNIT_VAR D(11) +#var C_COL D(12) +#var R_REGEQ D(13) +#var R_SYSVAR D(14) + +#var FO_SINGLE_FOLDER D(1) +#var FO_RECURSE D(2) +#var FO_SKIP_TEMPS D(4) +#var FO_NOTEMPS D(4) +#var FO_RETURN_TWINS D(8) +#var FO_CKTWINS D(8) +#var FO_RETURN_FOLDER D(16) +#var FO_SKIP_COLLAPSE D(32) + +#var FOP_UNLOCK D(0) +#var FOP_LOCK D(1) +#var FOP_ALL_FOLDERS D(128) + +#var MAIN_FOLDER D(2) +#var FOLDER_TABLE D(3) +#var NOT_FOUND D(4) +#var BAD_FOLDER D(5) + +#var HANDLE typedef unsigned short HANDLE; +#var HSym typedef struct{HANDLE folder;unsigned short offset;}HSym; +#var HSYM D(HSym) +#var MULTI_EXPR typedef struct{unsigned short Size;ESQ Expr[];}MULTI_EXPR; +#var SYM_ENTRY typedef struct{char name[8];unsigned short compat;union{unsigned short flags_n;struct{unsigned short busy:1,local:1,flag1_5:1,flag1_4:1,collapsed:1,twin:1,archived:1,in_view:1;unsigned short folder:1,overwritten:1,checked:1,hidden:1,locked:1,statvar:1,graph_ref_1:1,graph_ref_0:1;}bits;}flags;HANDLE handle;}SYM_ENTRY; +#var SYM_STR typedef CESI SYM_STR; +#var SF_GREF1 D(1) +#var SF_GREF2 D(2) +#var SF_STATVAR D(4) +#var SF_LOCKED D(8) +#var SF_HIDDEN D(16) +#var SF_OPEN D(16) +#var SF_CHECKED D(32) +#var SF_OVERWRITTEN D(64) +#var SF_FOLDER D(128) +#var SF_INVIEW D(256) +#var SF_ARCHIVED D(512) +#var SF_TWIN D(1024) +#var SF_COLLAPSED D(2048) +#var SF_LOCAL D(16384) +#var SF_BUSY D(-32768) + +#var VR_NO_SYS_VARS D(1) +#var VR_FUNC_NAME D(2) +#var VR_LINK D(4) + +#var STOF_ESI D(16384) +#var STOF_ELEMENT D(16385) +#var STOF_NONE D(16386) +#var STOF_HESI D(16387) + +#var $(s) D(SYMSTR_CONST(#s)) +#var AddSymToFolder D(_rom_call(HSym,(SYM_STR,SYM_STR),70)) +#var checkCurrent D(_rom_call(HSym,(SYM_STR,ESQ),121)) +#var CheckLinkLockFlag D(_rom_call(void,(const SYM_ENTRY*),7F)) +#var CheckReservedName D(_rom_call(short,(SYM_STR),8B)) +#var CheckSysFunc D(_rom_call(short,(const char*,__pushort),89)) +#var ClearUserDef D(_rom_call(void,(HANDLE),7E)) +#var DerefSym D(_rom_call(SYM_ENTRY*,(HSym),79)) +#var EM_moveSymFromExtMem D(_rom_call(short,(SYM_STR,HSym),161)) +#var EM_moveSymToExtMem D(_rom_call(short,(SYM_STR,HSym),162)) +#var EM_twinSymFromExtMem D(_rom_call(HSym,(SYM_STR,HSym),166)) +#var EX_stoBCD D(_rom_call(void,(unsigned char*,float*),C0)) +#var FindSymInFolder D(_rom_call(HSym,(SYM_STR,const char*),71)) +#var FolderAdd D(_rom_call(HANDLE,(SYM_STR),64)) +#var FolderAddTemp D(_rom_call(const char*,(void),73)) +#var FolderClear(c) D(__Folder_Del((c),1)) +#var FolderCount D(_rom_call(unsigned short,(const SYM_ENTRY*),6B)) +#var FolderCur D(_rom_call(short,(SYM_STR,short),65)) +#var FolderCurTemp D(_rom_call(short,(SYM_STR),72)) +#var FolderDel(c) D(__Folder_Del((c),0)) +#var FolderDelAllTemp D(_rom_call(void,(short),75)) +#var FolderDelTemp D(_rom_call(void,(void),74)) +#var FolderFind D(_rom_call(short,(SYM_STR),67)) +#var FolderGetCur D(_rom_call(void,(char*),68)) +#var FolderOp D(_rom_call(short,(SYM_STR,short),69)) +#var FolderRename D(_rom_call(short,(const char*,const char*),6A)) +#var HSymDel D(_rom_call(short,(HSym),5F)) +#var HSYMtoName D(_rom_call(short,(HSym,char*),7A)) +#var IsMainFolderStr D(_rom_call(short,(const char*),77)) +#var MakeHSym D(_rom_call(HSym,(HANDLE,const SYM_ENTRY*),282)) +#var partial_len D(_rom_call(unsigned long,(const char*,unsigned char*),11C)) +#var QSysProtected D(_rom_call(short,(ESQ),88)) +#var ResetSymFlags D(_rom_call(void,(short),8E)) +#var StrToTokN D(_rom_call(ESI,(const char*,unsigned char*),7B)) +#var SymAdd D(_rom_call(HSym,(SYM_STR),5C)) +#var SymAddMain D(_rom_call(HSym,(SYM_STR),5D)) +#var SymAddTwin D(_rom_call(HSym,(SYM_STR),27F)) +#var SymCmp D(_rom_call(short,(const char*,const char*),81)) +#var SymCpy0 D(_rom_call(void,(char*,const char*),83)) +#var SymCpy D(_rom_call(void,(char*,const char*),82)) +#var SymDel D(_rom_call(short,(SYM_STR),5E)) +#var SymDelTwin D(_rom_call(short,(SYM_ENTRY*),280)) +#var SymFind D(_rom_call(HSym,(SYM_STR),60)) +#var SymFindFirst D(_rom_call(SYM_ENTRY*,(SYM_STR,short),6C)) +#var SymFindFolderName D(_rom_call(char*,(void),6F)) +#var SymFindHome D(_rom_call(HSym,(SYM_STR),62)) +#var SymFindMain D(_rom_call(HSym,(SYM_STR),61)) +#var SymFindNext D(_rom_call(SYM_ENTRY*,(void),6D)) +#var SymFindPrev D(_rom_call(SYM_ENTRY*,(void),6E)) +#var SymFindPtr D(_rom_call(SYM_ENTRY*,(SYM_STR,short),283)) +#var SymMove D(_rom_call(short,(const char*,const char*),63)) +#var SYMSTR(s) D(({register unsigned short __slen=_rom_call(unsigned long,(const char*),27E)(s);ESI __tempstr=alloca(__slen+2);__tempstr[0]=0;_rom_call(void*,(void*,const void*,long),26A)(__tempstr+1,(s),__slen+1);__tempstr+__slen+1;})) +#var SymSysVar D(_rom_call(short,(const char*),8C)) +#var TempFolderName D(_rom_call(SYM_STR,(short),76)) +#var TokToStrN D(_rom_call(short,(unsigned char*,SYM_STR),7C)) +#var ValidateSymName D(_rom_call(short,(const char*),84)) +#var VarRecall D(_rom_call(HSym,(SYM_STR,short),85)) +#var VarStore D(_rom_call(HSym,(SYM_STR,short,short,...),86)) + +#var SymFindFoldername D(SymFindFolderName) + +#var OpenFile void *OpenFile(const char *)__ATTR_LIB_C__; +#var CloseFile void CloseFile(const char *)__ATTR_LIB_C__; diff --git a/pch/src/version.pchsource b/pch/src/version.pchsource new file mode 100644 index 0000000..eeda5be --- /dev/null +++ b/pch/src/version.pchsource @@ -0,0 +1,6 @@ + +#var __TIGCCLIB__ D(2) +#var __TIGCCLIB_MINOR__ D(50) +#var __TIGCCLIB_SP__ D(0) +#var __TIGCCLIB_VERSION__ D(250) +#var __TIGCCLIB_VERSION_STRING__ D("LIB2.5") diff --git a/pch/src/wingraph.pchsource b/pch/src/wingraph.pchsource new file mode 100644 index 0000000..99cab56 --- /dev/null +++ b/pch/src/wingraph.pchsource @@ -0,0 +1,113 @@ + +#var BITMAP_HDR_SIZE D(4) +#var NULL D(((void*)0)) +#var A_REVERSE D(0) +#var A_NORMAL D(1) +#var A_XOR D(2) +#var A_SHADED D(3) +#var A_REPLACE D(4) +#var A_OR D(5) +#var A_AND D(6) +#var A_THICK1 D(7) +#var A_SHADE_V D(8) +#var A_SHADE_H D(9) +#var A_SHADE_NS D(10) +#var A_SHADE_PS D(11) + +#var BITMAP typedef struct{unsigned short NumRows,NumCols;unsigned char Data[];}BITMAP; +#var FALSE D(0) +#var TRUE D(1) + +#var B_NORMAL D(16) +#var B_ROUNDED D(32) +#var B_DOUBLE D(64) +#var B_CUT D(128) + +#var BT_NONE D(0) +#var BT_OK D(1) +#var BT_SAVE D(2) +#var BT_YES D(3) +#var BT_CANCEL D(4) +#var BT_NO D(5) +#var BT_GOTO D(6) + +#var F_4x6 D(0) +#var F_6x8 D(1) +#var F_8x10 D(2) + +#var HANDLE typedef unsigned short HANDLE; +#var ICON typedef struct{unsigned short i[16];}ICON; +#var pICON typedef unsigned short*pICON; +#var SCR_COORDS typedef unsigned char SCR_COORDS; +#var SCR_RECT typedef union{struct{unsigned char x0,y0,x1,y1;}xy;unsigned long l;}SCR_RECT; +#var SCR_STATE typedef struct{void*ScrAddr;unsigned char XMax,YMax;short CurFont,CurAttr,CurX,CurY;SCR_RECT CurClip;}SCR_STATE; +#var WIN_COORDS typedef short WIN_COORDS; +#var WIN_RECT typedef struct{short x0,y0,x1,y1;}WIN_RECT; +#var WINDOW typedef struct WindowStruct{unsigned short Flags;unsigned char CurFont;unsigned char CurAttr;unsigned char Background;short TaskId;short CurX,CurY;short CursorX,CursorY;SCR_RECT Client;SCR_RECT Window;SCR_RECT Clip;SCR_RECT Port;unsigned short DupScr;struct WindowStruct*Next;char*Title;SCR_STATE savedScrState;unsigned char Reserved[16];}WINDOW; +#var WF_SYS_ALLOC D(1) +#var WF_STEAL_MEM D(2) +#var WF_DONT_REALLOC D(4) +#var WF_ROUNDEDBORDER D(8) +#var WF_SAVE_SCR D(16) +#var WF_DUP_SCR D(32) +#var WF_TTY D(64) +#var WF_ACTIVE D(128) +#var WF_NOBORDER D(256) +#var WF_NOBOLD D(512) +#var WF_DUP_ON D(1024) +#var WF_VIRTUAL D(2048) +#var WF_TITLE D(4096) +#var WF_DIRTY D(8192) +#var WF_TRY_SAVE_SCR D(16400) +#var WF_VISIBLE D(-32768) + +#var DeskTop D(((WINDOW*const)(((long*)(_rom_call_addr(0)))+1))) +#var FirstWindow D((*((WINDOW**)(_rom_call_addr(0))))) +#var DrawStaticButton D(_rom_call(void,(WINDOW*,short,short),35)) +#var DrawWinBorder D(_rom_call(void,(WINDOW*,SCR_RECT*),27)) +#var MakeWinRect D(_rom_call(WIN_RECT*,(short,short,short,short),2C)) +#var RectWinToScr D(_rom_call(SCR_RECT*,(const SCR_RECT*,const WIN_RECT*,SCR_RECT*),2A)) +#var RectWinToWin D(_rom_call(WIN_RECT*,(const SCR_RECT*,WIN_RECT*),29)) +#var WinActivate D(_rom_call(void,(WINDOW*),1)) +#var WinAttr D(_rom_call(short,(WINDOW*,short),2)) +#var WinBackground D(_rom_call(void,(WINDOW*,short),4)) +#var WinBackupToScr D(_rom_call(void,(WINDOW*),3)) +#var WinBegin D(_rom_call(void,(WINDOW*),5)) +#var WinBitmapGet D(_rom_call(short,(WINDOW*,const WIN_RECT*,void*),6)) +#var WinBitmapPut D(_rom_call(void,(WINDOW*,short,short,void*,short),7)) +#var WinBitmapSize D(_rom_call(unsigned short,(WINDOW*,const WIN_RECT*),8)) +#var WinChar D(_rom_call(void,(WINDOW*,char),A)) +#var WinCharXY D(_rom_call(void,(WINDOW*,short,short,char,short),9)) +#var WinClose D(_rom_call(void,(WINDOW*),B)) +#var WinClr D(_rom_call(void,(WINDOW*),C)) +#var WinDeactivate D(_rom_call(void,(WINDOW*),D)) +#var WinDupStat D(_rom_call(short,(WINDOW*,short),E)) +#var WinEllipse D(_rom_call(void,(WINDOW*,short,short,short,short),F)) +#var WinEnd(w) D(((void)0)) +#var WinFill D(_rom_call(void,(WINDOW*,const WIN_RECT*,short),10)) +#var WinFillLines2 D(_rom_call(void,(WINDOW*,const WIN_RECT*,const WIN_RECT*,short),11)) +#var WinFillTriangle D(_rom_call(void,(WINDOW*,short,short,short,short,short,short,short),12)) +#var WinFont D(_rom_call(void,(WINDOW*,short),13)) +#var WinGetCursor D(_rom_call(void,(WINDOW*,__pshort,__pshort),14)) +#var WinHeight D(_rom_call(short,(WINDOW*),292)) +#var WinHide D(_rom_call(void,(WINDOW*),15)) +#var WinHome D(_rom_call(void,(WINDOW*),16)) +#var WinLine D(_rom_call(void,(WINDOW*,const WIN_RECT*),17)) +#var WinLineNC D(_rom_call(void,(WINDOW*,const WIN_RECT*),18)) +#var WinLineRel D(_rom_call(void,(WINDOW*,short,short),1A)) +#var WinLineTo D(_rom_call(void,(WINDOW*,short,short),19)) +#var WinMoveCursor D(_rom_call(void,(WINDOW*,short,short),1B)) +#var WinMoveRel D(_rom_call(void,(WINDOW*,short,short),1D)) +#var WinMoveTo D(_rom_call(void,(WINDOW*,short,short),1C)) +#var WinOpen D(_rom_call(short,(WINDOW*,const WIN_RECT*,short,...),1E)) +#var WinPixGet D(_rom_call(short,(WINDOW*,short,short),1F)) +#var WinPixSet D(_rom_call(void,(WINDOW*,short,short),20)) +#var WinRect D(_rom_call(void,(WINDOW*,const WIN_RECT*,short),21)) +#var WinReOpen D(_rom_call(short,(WINDOW*,const WIN_RECT*,short,...),22)) +#var WinScrollH D(_rom_call(void,(WINDOW*,const WIN_RECT*,short),23)) +#var WinScrollV D(_rom_call(void,(WINDOW*,const WIN_RECT*,short),24)) +#var WinSetCursor(w,x,y) D((void)((w)->CursorX=x,(w)->CursorY=y)) +#var WinShow(w) D((void)((w)->Flags|=WF_VISIBLE)) +#var WinStr D(_rom_call(void,(WINDOW*,const char*),25)) +#var WinStrXY D(_rom_call(void,(WINDOW*,short,short,const char*),26)) +#var WinWidth D(_rom_call(short,(WINDOW*),291)) diff --git a/pch/srcdata/C-loseF-ile.ref b/pch/srcdata/C-loseF-ile.ref new file mode 100644 index 0000000..265eb7d --- /dev/null +++ b/pch/srcdata/C-loseF-ile.ref @@ -0,0 +1 @@ +OPENFILE.ext \ No newline at end of file diff --git a/pch/srcdata/CI1.ext b/pch/srcdata/CI1.ext new file mode 100644 index 0000000000000000000000000000000000000000..9004868201425d6d83c00a4a1b449e1eeee69c5d GIT binary patch literal 50 zcmZQDV30ClIC9XQ!NcL;K@Z2n_b)hlI5;_6X!0v%U|?WkV2F>;EzK#;G>$JS017ZL F005qe4+a1L literal 0 HcmV?d00001 diff --git a/pch/srcdata/CI2.ext b/pch/srcdata/CI2.ext new file mode 100644 index 0000000000000000000000000000000000000000..825863f313bf0578dc8c7e5016ff624c4bdd67cd GIT binary patch literal 58 zcmZRuV30Fm@Hpt;EzK#;G%n6G LiZ3bviU9!t8&?qu literal 0 HcmV?d00001 diff --git a/pch/srcdata/CI3.ext b/pch/srcdata/CI3.ext new file mode 100644 index 0000000000000000000000000000000000000000..f1d70dfe20b1590878ea02962fad567320efc7aa GIT binary patch literal 46 xcmZS3VGuH5IC9X#;Q$ajIb3M+D`j9{U}9j1kIya5Db6%5%`}QHDgcTB0RTXJ42}Q* literal 0 HcmV?d00001 diff --git a/pch/srcdata/O-penF-ile.ref b/pch/srcdata/O-penF-ile.ref new file mode 100644 index 0000000..265eb7d --- /dev/null +++ b/pch/srcdata/O-penF-ile.ref @@ -0,0 +1 @@ +OPENFILE.ext \ No newline at end of file diff --git a/pch/srcdata/OpenFile.ext b/pch/srcdata/OpenFile.ext new file mode 100644 index 0000000000000000000000000000000000000000..aef74721acf407aa40cc1e4feb26c946ae9ec54e GIT binary patch literal 224 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

N^MdYj zl5sXeTFuxA_@&NlpKCL|?>pgorREi9nrrOD#N3XzY(`HFR;8IXW7~B9&bH_LJ0UBc z_U~l)pSInZbD_pJ`l%x!Hs`09eJ*!gaH+LfQyGg!#=^%~EJi!ClCYSk7*A|_f0yF= z#c}xK49>r%pO}|Eu}sJ7iV^GFOwTr8a&6l){%e8BsQ=o`sp#paZMRRrq>pHXPcuo2 zdA>!Y>CSW2Vr5qXp5nA$d)``R%NOS3&*z=-+P3^j`5BEj(|S0VS()Om9j)zreF&1M zG$r7HtoW-ki8WhYPHRW$xP=VOqlY(0JpGg^jnu?ZqJ*8xn}AXIqV&odSe0*_ZbxBw4Tq)7xU1EmmS9LjI48JygdDQz}fW=9m)^dM(f{L`)PBNHexd5 zp3oAd@RQl*RXTsr*l*5K#`h>bZ|v9hDAKmU6JDlldvm9;<_c+98&I=Q_F9Xz7@wks zF7$M9p3ho?wac30b1i{Ab3UvYrTZWFyAaxUDZU@Vw+-J5@U39o65|+oMEX10s=aDnx*oJv9Ym2uQ^r8kn=R-UTD+Kr1uA*eK<#itJapHae9Zt z<#ME?Imf;SyJl8LCgCd4n`<;It z8-opOR2r;1+dO(t-jY3OdyV?oCC0L{&cW;$=}yPrR=f*9h0PJXZgUp&;E%Zt@#X8# zhd)uEIc(KAGAYtQ7_6XsrNx(518%o~?#WaKmBr_<6oohe&6BA760FIL5tYg#8HJwc z*hH!(y@RTY4V(Xepz5eb)$glRopk&K^CVF91xeLBrs``dRiCNp)TlcBDWYeMPS5(h zoo$ZIV{Ly_DOh+C1)+&a3XXt+V>2WL$AmJe{*B6s)I*#Lf8x+)A7KhYYUlK&&a<2Y z?e!6*Z&EYul|WYk_uVg|!sTkKT!bAErSEJDR?B+(=Ahq(ZN5!9%ltZ3C{}l2gcL>|4EZk+yl%S{}~=AX#9V0V8#D8K@Djf$}j%^ zU|?Y=0gZh+Il#GXRWke3K7ixuQ~8h|cgNC^Rz5j-n^b0IJO z|4DTNl}fu=fC{o zfT@tduN0!@{~KV+djuNg(DLvIP{`u^0csh9ITZanw7 z&|Dh4T?IUp7T6nPaas-(1GcDueHjj5&em~$_y4ib4Uis>%>VzvI*vg5eGI_Sku1h7 zz_iH$l)nL-on!c41gspvqbl~mktn|_&^Ejp@Tg|czEJS}2cU~dzzm4*JY0epe#FiM E0FDQzY5)KL literal 0 HcmV?d00001 diff --git a/pch/stdhead.def b/pch/stdhead.def new file mode 100644 index 0000000..d353aca --- /dev/null +++ b/pch/stdhead.def @@ -0,0 +1,939 @@ + +$ +AB_prodid +AB_prodname +AB_serno +APD_TIMER +ARROW_DOWN +ARROW_LEFT +ARROW_RIGHT +ARROW_UP +ASM_TAG +ASM_call +ASM_fastcall +AUTO_INT +AUTO_INT_1 +AUTO_INT_2 +AUTO_INT_3 +AUTO_INT_4 +AUTO_INT_5 +AUTO_INT_6 +AUTO_INT_7 +AUTO_INT_COUNT +A_AND +A_NORMAL +A_OR +A_REPLACE +A_REVERSE +A_SHADED +A_SHADE_H +A_SHADE_NS +A_SHADE_PS +A_SHADE_V +A_THICK1 +A_XOR +AddSymToFolder +ArgCount +AutoInts +BAD_FOLDER +BATT_TIMER +BCD_TAG +BEGIN_KEYTEST +BITMAP +BITMAP_HDR_SIZE +BITSPERBYTE +BOOL +BYTE +B_CUT +B_DOUBLE +B_NORMAL +B_ROUNDED +BitmapGet +BitmapInit +BitmapPut +BitmapSize +Bool +CB_fetchTEXT +CB_replaceTEXT +CESI +CF_CONVERT +CF_ENHANCED +CF_NEW +CF_NONE +CHAR_BIT +CHAR_MAX +CHAR_MIN +CURSOR_TIMER +CU_restore +CU_start +CU_stop +CheckLinkLockFlag +CheckReservedName +CheckSysFunc +ClearScreen +ClearUserDef +CloseFile +ClrScr +DARK_PLANE +DATA_TAG +DBL_DIG +DBL_EPSILON +DBL_MANT_BITS +DBL_MANT_DIG +DBL_MAX +DBL_MAX_10_EXP +DBL_MAX_2_EXP +DBL_MAX_EXP +DBL_MIN +DBL_MIN_10_EXP +DBL_MIN_2_EXP +DBL_MIN_EXP +DEFINE_INT_HANDLER +DEF_QUEUE +DMAXEXP +DMAXPOWTWO +DMINEXP +DSIGNIF +DUMMY_HANDLER +DWORD +DerefSym +DisableAutoInt3 +DisplayOff +DisplayOn +DrawChar +DrawClipChar +DrawClipEllipse +DrawClipLine +DrawClipPix +DrawClipRect +DrawFkey +DrawIcon +DrawLine +DrawMultiLines +DrawPix +DrawStr +DrawStrWidth +DrawStrXY +DrawTo +EM_GC +EM_abandon +EM_blockVerifyErase +EM_findEmptySlot +EM_moveSymFromExtMem +EM_moveSymToExtMem +EM_survey +EM_twinSymFromExtMem +EM_write +ENDFINAL +ENDTRY +END_KEYTEST +END_TAG +EOF +ERD_dialog +ERD_process +ERROR_FRAME +ER_ARGUMENT +ER_BREAK +ER_ESTACK_OVERFLOW +ER_EXIT +ER_MEMORY +ER_MEMORY_EXHAUSTION +ER_NO_MSG +ER_OFF +ER_OK +ER_OKAY +ER_PRGM_STOP +ER_STACK_VIO +ER_STOP +ER_SYNTAX +ER_THROW +ER_TOO_FEW_ARGS +ER_TOO_MANY_ARGS +ER_catch +ER_success +ER_throw +ER_throwVar +ESI +ESQ +EStackIndex +EX_getArg +EX_getBCD +EX_patch +EX_stoBCD +EnableAutoInt3 +ExecuteHandler +FALSE +FALSE_TAG +FIG_TAG +FILE +FINALLY +FIRST_AUTO_INT +FIRST_TRAP +FLOAT_TAG +FLT_DIG +FLT_EPSILON +FLT_MANT_BITS +FLT_MANT_DIG +FLT_MAX +FLT_MAX_10_EXP +FLT_MAX_2_EXP +FLT_MAX_EXP +FLT_MIN +FLT_MIN_10_EXP +FLT_MIN_2_EXP +FLT_MIN_EXP +FLT_NORMALIZE +FLT_RADIX +FLT_ROUNDS +FL_addCert +FL_download +FL_getCert +FL_getHardwareParmBlock +FL_getVerNum +FL_write +FMAXEXP +FMAXPOWTWO +FMINEXP +FOLDER_TABLE +FOP_ALL_FOLDERS +FOP_LOCK +FOP_UNLOCK +FO_CKTWINS +FO_NOTEMPS +FO_RECURSE +FO_RETURN_FOLDER +FO_RETURN_TWINS +FO_SINGLE_FOLDER +FO_SKIP_COLLAPSE +FO_SKIP_TEMPS +FSIGNIF +FUNC_TAG +F_4x6 +F_6x8 +F_8x10 +FillLines2 +FillTriangle +FindSymInFolder +FolderAdd +FolderAddTemp +FolderClear +FolderCount +FolderCur +FolderCurTemp +FolderDel +FolderDelAllTemp +FolderDelTemp +FolderFind +FolderGetCur +FolderOp +FolderRename +FontCharWidth +FontGetSys +FontSetSys +FreeHandles +GDB_TAG +GKeyDown +GKeyFlush +GKeyIn +GRAYDBUFFER_SIZE +GRAY_HW1 +GRAY_HW2 +GRAY_OFF +GRAY_ON +GetAMSSize +GetArgType +GetFloatArg +GetGrayInt1Handler +GetGraySwitchCount +GetIntArg +GetIntVec +GetLongLongArg +GetPix +GetPlane +GetStrnArg +GetSymstrArg +GrayAdjust +GrayCheckRunning +GrayDBufCleanup +GrayDBufGetActiveIdx +GrayDBufGetActivePlane +GrayDBufGetHiddenIdx +GrayDBufGetHiddenPlane +GrayDBufGetPlane +GrayDBufInit +GrayDBufSetAMSPlane +GrayDBufSetActiveAMSPlane +GrayDBufSetActiveIdx +GrayDBufSetActiveIdxSync +GrayDBufSetHiddenAMSPlane +GrayDBufToggle +GrayDBufToggleSync +GrayGetInt1Handler +GrayGetPlane +GrayGetSwitchCount +GrayGetVersionString +GrayMode +GrayOff +GrayOn +GraySetAMSPlane +GraySetInt1Handler +GraySetSwitchCount +GrayWaitNSwitches +HANDLE +HARDWARE_PARM_BLOCK +HIBITI +HIBITL +HIBITS +HLock +HSYM +HSYMtoName +HS_NULL +HSym +HSymDel +H_NULL +HeapAlloc +HeapAllocESTACK +HeapAllocHigh +HeapAllocHighThrow +HeapAllocPtr +HeapAllocPtrThrow +HeapAllocThrow +HeapAvail +HeapCompress +HeapDeref +HeapEnd +HeapFree +HeapFreeIndir +HeapFreePtr +HeapGetHandle +HeapGetLock +HeapLock +HeapMax +HeapMoveHigh +HeapPtrToHandle +HeapRealloc +HeapReallocThrow +HeapSize +HeapUnlock +HelpKeys +ICON +INT_HANDLER +INT_MAX +INT_MIN +INT_VEC_ADDRESS_ERROR +INT_VEC_ARCHIVE +INT_VEC_BUS_ERROR +INT_VEC_CHK_INS +INT_VEC_ER_THROW +INT_VEC_ILLEGAL_INSTRUCTION +INT_VEC_INT_MASK +INT_VEC_KEY_PRESS +INT_VEC_LINE_1010 +INT_VEC_LINE_1111 +INT_VEC_LINK +INT_VEC_MANUAL_RESET +INT_VEC_OFF +INT_VEC_ON_KEY_PRESS +INT_VEC_PRIVILEGE_VIOLATION +INT_VEC_RESET +INT_VEC_SELF_TEST +INT_VEC_SPURIOUS_INT +INT_VEC_STACK_OVERFLOW +INT_VEC_TRACE +INT_VEC_TRAPV_INS +INT_VEC_UNINITIALIZED_INT +INT_VEC_ZERO_DIVIDE +InitArgPtr +IsGrayMode +IsMainFolderStr +JMP_BUF +KEY_APPS +KEY_BACKSPACE +KEY_CHAR +KEY_CLEAR +KEY_ENTER +KEY_ENTRY +KEY_ESC +KEY_F1 +KEY_F2 +KEY_F3 +KEY_F4 +KEY_F5 +KEY_F6 +KEY_F7 +KEY_F8 +KEY_INS +KEY_MATH +KEY_MEM +KEY_MODE +KEY_OFF +KEY_ON +KEY_QUIT +KEY_RCL +KEY_SIGN +KEY_STO +KEY_SWITCH +KEY_VARLNK +LAST_AUTO_INT +LAST_TRAP +LCD_BUFFER +LCD_MEM +LCD_SIZE +LCD_restore +LCD_save +LDBL_DIG +LDBL_EPSILON +LDBL_MANT_BITS +LDBL_MANT_DIG +LDBL_MAX +LDBL_MAX_10_EXP +LDBL_MAX_2_EXP +LDBL_MAX_EXP +LDBL_MIN +LDBL_MIN_10_EXP +LDBL_MIN_2_EXP +LDBL_MIN_EXP +LIGHT_PLANE +LIO_CTX +LIO_Get +LIO_GetMultiple +LIO_Receive +LIO_RecvData +LIO_Send +LIO_SendData +LIO_SendProduct +LIO_TIMER +LIST_TAG +LN_MAXDOUBLE +LN_MINDOUBLE +LONG_MAX +LONG_MIN +LineTo +MAC_TAG +MAIN_FOLDER +MATRIX_TAG +MAXDOUBLE +MAXFLOAT +MAXINT +MAXLONG +MAXSHORT +MINDOUBLE +MINFLOAT +MISC_TIMER +MULTI_EXPR +MULTI_LINE +MakeHSym +MakeWinRect +MoveTo +NEGINT_TAG +NOT_FOUND +NULL +NeedStack +ONERR +OSCheckBreak +OSCheckSilentLink +OSClearBreak +OSContrastDn +OSContrastUp +OSDisableBreak +OSEnableBreak +OSFastArrows +OSFreeTimer +OSGetStatKeys +OSInitBetweenKeyDelay +OSInitKeyInitDelay +OSLinkClose +OSLinkCmd +OSLinkOpen +OSLinkReset +OSLinkTxQueueActive +OSLinkTxQueueInquire +OSReadLinkBlock +OSRegisterTimer +OSReset +OSSetSR +OSTimerCurVal +OSTimerExpired +OSTimerRestart +OSVFreeTimer +OSVRegisterTimer +OSWriteLinkBlock +OSdequeue +OSenqueue +OSqclear +OSqhead +OSqinquire +OTH_TAG +OpenFile +PASS +PIC_TAG +POSINT_TAG +PortRestore +PortSet +QModeKey +QScrRectOverlap +QSysKey +QSysProtected +QUEUE +Quantum +RAND_MAX +RR_0 +RR_1 +RR_2 +RR_2ND +RR_3 +RR_4 +RR_5 +RR_6 +RR_7 +RR_8 +RR_9 +RR_A +RR_ALPHA +RR_APPS +RR_B +RR_BCKSPC +RR_C +RR_CATALOG +RR_CLEAR +RR_COMMA +RR_COS +RR_D +RR_DIAMOND +RR_DIVIDE +RR_DOT +RR_DOWN +RR_E +RR_EE +RR_ENTER +RR_ENTER1 +RR_ENTER2 +RR_EQUALS +RR_ESC +RR_F +RR_F1 +RR_F2 +RR_F3 +RR_F4 +RR_F5 +RR_F6 +RR_F7 +RR_F8 +RR_G +RR_H +RR_HAND +RR_HOME +RR_I +RR_J +RR_K +RR_L +RR_LEFT +RR_LN +RR_M +RR_MINUS +RR_MODE +RR_MULTIPLY +RR_N +RR_NEGATE +RR_NO_KEY +RR_O +RR_P +RR_PAREN_CLOSE +RR_PAREN_OPEN +RR_PLUS +RR_POWER +RR_Q +RR_R +RR_RIGHT +RR_S +RR_SHIFT +RR_SIN +RR_SPACE +RR_STORE +RR_T +RR_TAN +RR_THETA +RR_U +RR_UP +RR_V +RR_W +RR_WITH +RR_X +RR_Y +RR_Z +ReleaseDate +ReleaseVersion +RemainingArgCnt +ResetSymFlags +RestoreScrState +SBYTE +SCHAR +SCHAR_MAX +SCHAR_MIN +SCR_COORDS +SCR_RECT +SCR_STATE +SDWORD +SEEK_CUR +SEEK_END +SEEK_SET +SF_ARCHIVED +SF_BUSY +SF_CHECKED +SF_COLLAPSED +SF_FOLDER +SF_GREF1 +SF_GREF2 +SF_HIDDEN +SF_INVIEW +SF_LOCAL +SF_LOCKED +SF_OPEN +SF_OVERWRITTEN +SF_STATVAR +SF_TWIN +SHRT_MAX +SHRT_MIN +SINT +SLONG +SPRT_AND +SPRT_OR +SPRT_XOR +SSHORT +STAT_2ND +STAT_DIAMOND +STAT_HAND +STAT_SHIFT +STR_TAG +ST_busy +ST_eraseHelp +ST_folder +ST_helpMsg +ST_refDsp +ST_showHelp +SWORD +SYMSTR +SYMSTR_CONST +SYM_ENTRY +SYM_STR +SaveScrState +ScrRect +ScrRectFill +ScrRectOverlap +ScrRectScroll +ScrRectShift +ScrToHome +ScrToWin +SetCurAttr +SetCurClip +SetGrayInt1Handler +SetGraySwitchCount +SetIntVec +SetPlane +SkipArg +Sprite16 +Sprite32 +Sprite8 +StrToTokN +SumStoChkMem +SymAdd +SymAddMain +SymAddTwin +SymCmp +SymCpy +SymCpy0 +SymDel +SymDelTwin +SymFind +SymFindFirst +SymFindFolderName +SymFindFoldername +SymFindHome +SymFindMain +SymFindNext +SymFindPrev +SymFindPtr +SymMove +SymSysVar +TEXT_TAG +TI89 +TI92PLUS +TMP_MAX +TRAP +TRAP_0 +TRAP_1 +TRAP_10 +TRAP_11 +TRAP_12 +TRAP_13 +TRAP_14 +TRAP_15 +TRAP_2 +TRAP_3 +TRAP_4 +TRAP_5 +TRAP_6 +TRAP_7 +TRAP_8 +TRAP_9 +TRAP_COUNT +TRUE +TRUE_TAG +TRY +TempFolderName +Timer_Callback_t +TokToStrN +UBYTE +UCHAR +UCHAR_MAX +UDWORD +UINT +UINT_MAX +ULONG +ULONG_MAX +UNDEF_TAG +USERFUNC_TAG +USER_TIMER +USHORT +USHRT_MAX +UWORD +V200 +VATSTR +ValidateSymName +VarRecall +VarStore +WINDOW +WIN_COORDS +WIN_RECT +WORD +WordInList +XR_stringPtr +_DEREF_INT_HANDLER +_DEXPLEN +_EXPBASE +_FEXPLEN +_F_BIN +_F_EOF +_F_ERR +_F_RDWR +_F_READ +_F_WRIT +_GrayIsRealHW2 +_IEEE +_OSInitBetweenKeyDelay +_RR +_RS +__D_plane +__D_plane2 +__EM_findEmptySlot +__FERROR +__Folder_Del +__L_plane +__L_plane2 +__TIGCCLIB_MINOR__ +__TIGCCLIB_SP__ +__TIGCCLIB_VERSION_STRING__ +__TIGCCLIB_VERSION__ +__TIGCCLIB__ +__assertion_failed +__div_entry +__divsi3 +__dummy_handler__ +__exit +__gray_dbl_offset +__gray_handle +__gray_hw_type +__gray_old_int1_hw1 +__gray_old_int1_hw2 +__gray_version +__keytest +__keytest_optimized +__modsi3 +__mulsi3 +__mulsi3_rp +__mulsi3si2_rp +__mulsi3ui2_rp +__randseed +__switch_cnt +__udivsi3 +__umodsi3 +__vcbprintf__type__ +_keytest +_keytest_optimized +_memset +_rowread +_rowread_internal +_rowread_inverted +_tolower +_toupper +abort +abs +atexit +atexit_t +atof +atoi +atol +bcd +bsearch +calloc +calloc_throw +checkCurrent +clearerr +clrscr +cmpstri +compare_t +div +div_t +enter_ghost_space +exit +fabs +fclose +feof +ferror +fflush +fgetc +fgetchar +fgetpos +fgets +find_error_message +flush_link +fopen +fpos_t +fprintf +fputc +fputchar +fputs +fread +free +freopen +fseek +fsetbufsize +fsetpos +ftell +fwrite +getc +getcalc +getchar +gets +idle +isGreek +isalnum +isalpha +isascii +iscntrl +isdigit +isextalnum +isextlower +isextpunct +isextupper +isfrgn +isfrgnalnum +isfrgnlower +isfrgnupper +isgraph +islower +isprint +ispunct +isspace +isupper +isxdigit +jmp_buf +kbd_queue +kbhit +ldiv +ldiv_t +longjmp +malloc +malloc_throw +max +memchr +memcmp +memcpy +memmove +memset +min +ngetchx +off +pICON +partial_len +peek +peekIO +peekIO_bit +peekIO_w +peek_bit +peek_l +peek_w +poke +pokeIO +pokeIO_bclr +pokeIO_bset +pokeIO_w +poke_bclr +poke_bset +poke_l +poke_w +printf +printf_xy +pushkey +putc +putchar +puts +qsort +rand +random +randomize +realloc +realloc_throw +receive +remove +rename +reset_link +rewind +sendcalc +setjmp +size_t +speek +speek_l +speek_w +sprintf +srand +strcat +strchr +strcmp +strcpy +strcspn +strerror +strlen +strncat +strncmp +strncpy +strpbrk +strputchar +strrchr +strspn +strstr +strtok +strtol +strtoul +ti_float +tmpnam +toascii +toextlower +toextupper +tolower +top_estack +toupper +transmit +tx_free +ungetc +unlink +va_arg +va_end +va_list +va_start +vcbprintf +vcbprintf_Callback_t +vcbprintf_callback_t +vfprintf +vprintf +vsprintf diff --git a/pch/stdhead.pch b/pch/stdhead.pch new file mode 100644 index 0000000000000000000000000000000000000000..f9d8bd8c59e3e4460925a27d32a5d57065d49524 GIT binary patch literal 40350 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%0D19nWLLTQ4gzsCvM~v09egr%#wKLR4Y&2gZ&rowO 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 I8DQT50Eu*%>Hq)$ literal 0 HcmV?d00001 diff --git a/pch/subprojects/xupaki.pch b/pch/subprojects/xupaki.pch new file mode 100644 index 0000000000000000000000000000000000000000..3770445b2f2f99cff0d2a8fb6ff48050f37e700a GIT binary patch literal 860 zcmWG=_Fw>lFosYD#?ZWi#N=!c7X*?s5{ne#;}c6tiZYW*OH$+GH8kSmi%YT#5{q)< z<25xE;x)?hGgB0_ii?tUAgq+)5>0CcMh1omrcVWb6PODA`P{Gh;a6JlKjE7~J_CzV zJ_Coxb9uX}|4yv#znIqXM7W2f-QtM|$WFTw(NVx4AYsA4&LK2r8y*~>uIHiNsJAPnbsAHJtlEo3=F4txwE+b*U_AcXq z^9H|kk$FC-qCy7}t`+?cJkP)dQyb*S&lZ0E|F5)n^BhstG9S3)c%WE-$;&aFf#C`< zx=h&KWicPRy6gm`m;{Ol# zUyO?q82(#%xu-D&b%gYTLal(ouQb?6NGM(GaTc=cKqeguZE=)qG7>NOzu5_4z6hiH zM-2v{+dvcl08I=?VEFd}*-jy#ogfSpzknPH{A}qrQ2A+Qm?3(w&xq%72C_>)J^}le zp}`3lwhaHOhzTc9{J=sN7(xxX9>MO2um_n*swu$?at#LJ0!+l{LyjdDCkBNqHW4EQ z#RQ4xUg1ct0EID=BLjPjBRGEkBryD)2h0+T49pDd4Ezl84E7B54F4JbGyiA*&;MWk Rzy1IE|3G;m1_tCj1OP;f7?1z} literal 0 HcmV?d00001 diff --git a/pch/subprojects/xupaki/Unpack2.o b/pch/subprojects/xupaki/Unpack2.o new file mode 100644 index 0000000000000000000000000000000000000000..ea83c4ff4002f0b0b5180d1f531e967c4bac3c8c GIT binary patch literal 968 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 literal 0 HcmV?d00001 diff --git a/pch/tiosdlg.def b/pch/tiosdlg.def new file mode 100644 index 0000000..8926991 --- /dev/null +++ b/pch/tiosdlg.def @@ -0,0 +1,168 @@ + +BT_CANCEL +BT_GOTO +BT_NO +BT_NONE +BT_OK +BT_SAVE +BT_YES +CENTER +DMF_BITMAP +DMF_CHILD +DMF_CHILD_SUB +DMF_ICON +DMF_TEXT +DMF_TOP +DMF_TOP_SUB +DeskTop +Dialog +DialogAdd +DialogAddPulldown +DialogAddRequest +DialogAddScroll +DialogAddText +DialogAddTitle +DialogDo +DialogNew +DialogNewSimple +DialogNew_t +DlgMessage +DrawStaticButton +DrawWinBorder +EVENT +FirstWindow +MBF_HMENU +MBF_MAX_MENU_WIDTH +MBF_NO_DRAWTOP +MBF_REDEF +MBF_STRIKEOUT +MBF_SYS_ALLOC +MBF_WITHICON +MC_CHECK +MC_FLIP +MC_STATUS +MC_UNCHECK +MF_ALT_ICONS +MF_BITMAP_TITLE +MF_DYN_POPUP +MF_ERROR +MF_ICONS_OVERLAP +MF_ICON_TITLE +MF_NONSEQ +MF_NO_NUMS +MF_NO_UNAMED +MF_POPUP +MF_TEXT_TITLE +MF_TITLE +MF_TOOLBOX +MT_CASCADE +MT_ICON +MT_TEXT +MT_XREF +M_NOITEM +M_NOTMENUKEY +MenuAddIcon +MenuAddText +MenuBegin +MenuCheck +MenuEnd +MenuGetTopRedef +MenuKey +MenuNew +MenuOn +MenuPopup +MenuSubStat +MenuTopRedef +MenuTopSelect +MenuTopStat +MenuUpdate +NoCallBack +PopupAddText +PopupClear +PopupDo +PopupNew +PopupText +RectWinToScr +RectWinToWin +TEXT_EDIT +TE_checkSlack +TE_close +TE_empty +TE_focus +TE_handleEvent +TE_indicateReadOnly +TE_isBlank +TE_open +TE_openFixed +TE_pasteText +TE_reopen +TE_reopenPlain +TE_select +TE_shrinkWrap +TE_unfocus +TE_updateCommand +VCFP_ALL +VCFP_SKIP_CURDIR +VarCreateFolderPopup +VarNew +VarOpen +VarSaveAs +WF_ACTIVE +WF_DIRTY +WF_DONT_REALLOC +WF_DUP_ON +WF_DUP_SCR +WF_NOBOLD +WF_NOBORDER +WF_ROUNDEDBORDER +WF_SAVE_SCR +WF_STEAL_MEM +WF_SYS_ALLOC +WF_TITLE +WF_TRY_SAVE_SCR +WF_TTY +WF_VIRTUAL +WF_VISIBLE +WinActivate +WinAttr +WinBackground +WinBackupToScr +WinBegin +WinBitmapGet +WinBitmapPut +WinBitmapSize +WinChar +WinCharXY +WinClose +WinClr +WinDeactivate +WinDupStat +WinEllipse +WinEnd +WinFill +WinFillLines2 +WinFillTriangle +WinFont +WinGetCursor +WinHeight +WinHide +WinHome +WinLine +WinLineNC +WinLineRel +WinLineTo +WinMoveCursor +WinMoveRel +WinMoveTo +WinOpen +WinPixGet +WinPixSet +WinReOpen +WinRect +WinScrollH +WinScrollV +WinSetCursor +WinShow +WinStr +WinStrXY +WinWidth diff --git a/pch/tiosdlg.pch b/pch/tiosdlg.pch new file mode 100644 index 0000000000000000000000000000000000000000..bb7419568b7aa4803a3479f572ef1c414d0a47a9 GIT binary patch literal 5934 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 literal 0 HcmV?d00001 diff --git a/pch/xupaki.pch b/pch/xupaki.pch new file mode 100644 index 0000000000000000000000000000000000000000..3770445b2f2f99cff0d2a8fb6ff48050f37e700a GIT binary patch literal 860 zcmWG=_Fw>lFosYD#?ZWi#N=!c7X*?s5{ne#;}c6tiZYW*OH$+GH8kSmi%YT#5{q)< z<25xE;x)?hGgB0_ii?tUAgq+)5>0CcMh1omrcVWb6PODA`P{Gh;a6JlKjE7~J_CzV zJ_Coxb9uX}|4yv#znIqXM7W2f-QtM|$WFTw(NVx4AYsA4&LK2r8y*~>uIHiNsJAPnbsAHJtlEo3=F4txwE+b*U_AcXq z^9H|kk$FC-qCy7}t`+?cJkP)dQyb*S&lZ0E|F5)n^BhstG9S3)c%WE-$;&aFf#C`< zx=h&KWicPRy6gm`m;{Ol# zUyO?q82(#%xu-D&b%gYTLal(ouQb?6NGM(GaTc=cKqeguZE=)qG7>NOzu5_4z6hiH zM-2v{+dvcl08I=?VEFd}*-jy#ogfSpzknPH{A}qrQ2A+Qm?3(w&xq%72C_>)J^}le zp}`3lwhaHOhzTc9{J=sN7(xxX9>MO2um_n*swu$?at#LJ0!+l{LyjdDCkBNqHW4EQ z#RQ4xUg1ct0EID=BLjPjBRGEkBryD)2h0+T49pDd4Ezl84E7B54F4JbGyiA*&;MWk Rzy1IE|3G;m1_tCj1OP;f7?1z} literal 0 HcmV?d00001 diff --git a/platform.mk b/platform.mk new file mode 100644 index 0000000..285257c --- /dev/null +++ b/platform.mk @@ -0,0 +1,2 @@ +PLATFORM := $(shell uname) +BIN_SUFFIX := $(if $(patsubst CYGWIN%,,$(patsubst MINGW%,,$(PLATFORM))),,.exe) diff --git a/readme.html b/readme.html new file mode 100644 index 0000000..c5a7205 --- /dev/null +++ b/readme.html @@ -0,0 +1,11 @@ + + + + Readme + + + + +

You can access the documentation here.

+ + diff --git a/ti68k/Makefile b/ti68k/Makefile new file mode 100644 index 0000000..4031056 --- /dev/null +++ b/ti68k/Makefile @@ -0,0 +1,51 @@ +all: +ifndef CALCULATOR +%: make89-% make9x-% makev2-% + @# dummy command, otherwise make ignores the rule +make89-%: + $(MAKE) $(patsubst make89-%,%,$@) CALCULATOR=89 +make9x-%: + $(MAKE) $(patsubst make9x-%,%,$@) CALCULATOR=9x +makev2-%: + $(MAKE) $(patsubst makev2-%,%,$@) CALCULATOR=v2 +else +PRETTY_CALCULATOR=$(if $(subst 89,,$(CALCULATOR)),$(if $(subst 9x,,$(CALCULATOR)),v200,92p),89) +DIR = bin-$(PRETTY_CALCULATOR) +MK = mkinfo-$(PRETTY_CALCULATOR)- + +all: ide h pch flashapp +ide: $(MK)ide +h: $(MK)h +pch: $(MK)pch +flashapp: $(MK)flashapp + +clean: +distclean: clean +scratchclean: distclean + $(RM) $(MK)* + $(RM) -r $(DIR) + +$(MK)h : ../h/processed/* +$(MK)pch : ../pch/* +$(MK)h : filedir = ../h/processed +$(MK)pch : filedir = ../pch +$(MK)h : fileext = t +$(MK)pch : fileext = y +$(MK)h $(MK)pch: files = $(wildcard $(filedir)/*.89$(fileext)) +$(MK)h $(MK)pch: + mkdir -p $(DIR) + $(foreach file,$(files),cp $(file) $(patsubst $(filedir)/%.89$(fileext),$(DIR)/%.$(CALCULATOR)$(fileext),$(file));) + touch $@ +$(MK)ide: ide/bin/* + mkdir -p $(DIR) + cp ide/bin/gtc-ide.$(CALCULATOR)z $(DIR) + touch $@ + +$(MK)flashapp: srcdata/flashapp/* +$(MK)flashapp: tifs_calc = $(if $(subst 89,,$(CALCULATOR)),92p,89) +$(MK)flashapp: tifs_ext = $(if $(subst 89,,$(CALCULATOR)),9xk,89k) +$(MK)flashapp: + mkdir -p $(DIR) + cp srcdata/flashapp/gtc-$(tifs_calc).$(tifs_ext) $(DIR)/gtc.$(CALCULATOR)k + touch $@ +endif diff --git a/ti68k/bin-89/assert.89t b/ti68k/bin-89/assert.89t new file mode 100644 index 0000000000000000000000000000000000000000..e64b549ec32d83efc5eeadd68fdb479357fb0702 GIT binary patch literal 222 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0o5iJ7pE4LFfb@GFf-f(@|Q+|4QOFtR8Y=L z%S%a3Q}A2j~ts!>nTdh3SNUq3Z!4%u~ZcyS_%x}rW%!%r0T^E-0z z@i$eY8@r9`ZD`dr=Zks+e(rpa2BV=dvW=l-&S?-j2e5YbdxpDS2mUdlU;X3m$@g4( zy>-GCTW@&2yW7;ECmP$kOze(rHm}Y;wNP z4^K4x>%<~xp^7$i81`mmX$!(ax@7T9TLD8Gliu4^?7WalrwX=bL<-$1QZ<)Tf|aXS zdsa-MSA`?jg$jq2ygs}&rz(-nO%=YF=(+BxmtbPP7-HD&xrgkuCrfar%@?{krE?6A z7;k^{auWy8h7^WtZr*}N=jhQ4^CQ@~EtX-J{AdC2e0TxTkeSsw}m8D8WvfFC>V?FdvtLaizRRtWzY0t5xFC z^DNYD5`@{o47)|9EU*9rw=)o3b;<2TI^+de;i2rLqkuT#-Xd9%Q-lJEFHaH@Bo6il LVR$mBUybb_X#sIV literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/default.89t b/ti68k/bin-89/default.89t new file mode 100644 index 0000000000000000000000000000000000000000..4966a1f5b28f3b4d0bf1bea926d74a00c7715f76 GIT binary patch literal 3054 zcmb_e-EP}96n3yX_a#^u2qYmLY_}bpH4UK1bShMq3`q{w76su%RHDX~3|ZO|w7uIS z>}C(J_u3Qe8Fna26eTN5H!L@?4!`rm@BC5Id~21X9k}9);mChD2(A45i-RyeQEjq0enU=l_gQgAWIJu-#i{K1Vl)z zrPm+OIEcbN7<|et1PVW&9IJyzV_fU7oyOb`68qY(W+uHl}O zW8&D>JK+buFfnw?D8r%xcO}LDoNvk#@PsEhx1FSGAXO#2TPV8Z*%B&63#~ zKI(w;Hrj(e7f`z1Q5GPd7<=~;M^)d8jMjeTFbgyPB2IySJW$R=Nr>R3&Pk)0+ha%+ zPenzYqzl~@Y*eR2_kEXm{*(|HnyV~Jqsu&_geVFjyX$o*X_lvP!wyU%>r6M^g4a5PnsYAnO~)&&KLTk)BCxfz({2?3IH-QMap#6XNLy%` zX9UFibfxr~)1{2mea4uY?#&;$PKBytmkFw+ok5k97STO)r6T$Y$m8jNe%fqFcDY81 zru>{lfu?C{W4)0y*^sN%daYzftD{H-oRTS8nM=sKnWS|{VNO&zMwPB#+o&TQsk-1q*g%lR~i1)^YEO&@LV`IDPmEg}1|(k-WpKi>9OcPqD8KZCO&N1qV)&J_`z-~FXmlS-n>86{!Dp9?+8@Nz&c-H>VXFl{`*%S$@e6 MI+j%L&tHH48&M6URsaA1 literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/doors.89t b/ti68k/bin-89/doors.89t new file mode 100644 index 0000000000000000000000000000000000000000..c79f0db4e5ef392a8780ba3235a1b7f00db79c5f GIT binary patch literal 906 zcma))QHt9z5Qd%REvL}N5F`^qA6qB|uOp~wVg*@VLSF`NByUU|8DyJM*c0>~y;qM? zIZk3{4W)h=N%PP5kH+#m5q|jSc@yWQJ{+ZS{`;Fa+-hZ6n##rpXX^Z#I?nHJEnxcI znIJdMv{V^dGsfeYYnQoJ*Ik~qsffiQd7Qb*n9|J8tkrRTYN{IPvPRDe<@!)GQc1g* z>$0kw=lQ9W>S5+KL%1p`HM52-lhnYvO$Mbx8xV4l}T&WiYv=T z-<8p-KrMS^E49os%j?WPS!&u8_3HTfY73@3!67Y*(E+4Vn%iw}I$ST)Wlpe%ag99y zUkDB&WHA6q30?qaTL}Ek23$8Mgp3JiFt&&{+Fp4|bBzf=7yEOQcD>?!SrhAjM)*U! zv3BS-lwOC-sYrMPPyQyMeRV|X8UnW6ZRj4hei-$m?A}7efbK&9akASnZvWBcRlvV0 zQ74jktRk&*0KkD6IM^Xzp literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/estack.89y b/ti68k/bin-89/estack.89y new file mode 100644 index 0000000000000000000000000000000000000000..2003e702beb843294e42ae5e0785b3eece0cb0fd GIT binary patch literal 12268 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 P5hwkd3R~=hm!A4RwH@TW literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/estackle.89y b/ti68k/bin-89/estackle.89y new file mode 100644 index 0000000000000000000000000000000000000000..214255fc31dd3fb8168d263ab06518c38a7d820f GIT binary patch literal 5670 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 DH?-iN literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/gtc.89k b/ti68k/bin-89/gtc.89k new file mode 100644 index 0000000000000000000000000000000000000000..b3d9a9e6a34b0fe51d8a54b2e323ca2fd998d3d6 GIT binary patch literal 109161 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≫z=suam-ei!#SVnTt$0{3@4;*e1<6B}H^_Zp1!; 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 literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/homescr.89y b/ti68k/bin-89/homescr.89y new file mode 100644 index 0000000000000000000000000000000000000000..7fe5a7f8e1d077a36a94e3dff8da23e8b8dc3e35 GIT binary patch literal 1438 zcma)6&utMz>$oJ*K#DYF|k!5TJ_O?q%N0eBaDB^PX)O zwVBgr3`2n%4y!j<0RQ(>U=E>6CocoLD&R2Oo;MqGNx#TvuBMv3zHXWV~NzHF#eY4jNq~n);uZbt@%lT3z_*#H5 zD@@VtMH+Bo+wt2%F7{WZh}vIX!BMBG8$eM_`xK=#IfPhvp3+i}dr zHecEXQ-3D=Q$}hHRa4R8T}VpTby(Xev&NU&Z0)=MB(CVI_!?s7wvH(5K(x(Mn{!vW zA23i~Xex}t?G=5H1*L@hs0cOD#B!hy#HKUj(WWskd6l{=epMQQLvVYT9*VXq-EkO7 zg=R`cF@O)@-b%`#dMeZ(q0(!<+eoLRAvChk^*V0TV+{g=*kB8!!-KBPw_NBre!!6? zEwu1$g6naxeXqj_*iJnF8u*LUuD4n#pfq2r&C%M-Y!y|+UU}v`oqpTRS1-r_l=4=g zYyvhg(x9h-Nbw0ZaSn_V`;PbE&oOuJ!xM+|uVHj7ByM8L8jSroMy)RKAu;~@Zm_yI zs)`q}xi2|8JheXE2um-I!C9EvL$FTC+xUYx$%-{N1@o&5o`?}=crJU2QJTLzRy^Wsr#e0)QFX2nknTo%}9p8Y+La8tZuZ}+Y7sN`KVE_OC literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/keywords.89y b/ti68k/bin-89/keywords.89y new file mode 100644 index 0000000000000000000000000000000000000000..49e8cf5af17a83541b2665a57377c27809dca86c GIT binary patch literal 792 zcma)3J8M)y7(FxV+x7j5(Il(uBW{sS&_WwiL=cf+CFnAH@9gfdvoq`5xyA$=3&Fxh z8?lx&wia55U~lCg5bUjNYy{8Ty^_`ghi}gL9`ovS?%up|wbK#U7;2U4fd7TSDoaOt zea(lwXrh6c2C#WA^~=w9ZmgvEQGP%t^DY`!YG7U{9HrkLt1Nh637@b#Y3=eca1Bqe zt&-OCfm^r_kz}s>#;PWi4R%a*N&(wRCS8>U-eG5D zxXhM$J$@G*Wv$N?@KwxWf2x=SH5jXwRc-+Mz%T6Ga=9Y*knOS_EE;H1ce^UaV0vZL z-EJxZ_K}(5*~Ow*#vv+I@ZJ!Yae$#0v>GuI2gz)x(szhe98Su+A~F(3$ii%B--mc8 zn^>SWF6$Ww@l<@lN$TmFI;RsDtA|yvGTKfsg!>gc&mE!9;~I z#5eI1r)e0Mdc}9lGFYFUBHnk|>) zb)2aT6-~wk(ISf&$}CNgw{bS@EhEVxWb<%hyD|6!{_Jv{?s}*mrFLDb z>84a0N%Lmr&66xkIuDPQHAAoM=^WSS-)n|=&n>H_?T!d7&<*P52)!K!gZV9*VIxb+ zI7zY3gbdf3(Vw$2QP(UTid)9G(2S(6t6Cq;R%gBFniiK;i;oG;%2VFON!%awZB^Bc zUQ}_i(2VYvdy+SaW_**Mdh4jm+tvBG$5K4Dj?GX|cyS${0%sm=oi^IrLbVPu3TOBP7Sa}HPi``ODl zONW@ld;CdIa|nA!L2Njs{#AZXWypQl*=|UCcrnf8GoX7%f(V0vae1YnzP)xSP|g{L vQQk)#br^g~x3FPe;L<&Kw&Sa;6QhW-(j)-m{-Yc}5`W=JG|q`W?%qEEuTZt7 literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/patch.89t b/ti68k/bin-89/patch.89t new file mode 100644 index 0000000000000000000000000000000000000000..094e1d461f810a97669cbeb0e4af106e15dca861 GIT binary patch literal 5660 zcmbVQ%W~t^5#>~N*e9zjIK!$ba)y!tkb=lbdBLGE9#$w)#fLnJ>AD3HkVFS0C;%GL zj_p6mGC$%k@j73T)Axl7iZgLV3lX@ukM7gmr@QZ~SF=H<`|8!R%3Z#?57Wx;{(DxL zVD2u!GW}!AIPX>L~oAlogZhQ+LXnf+& z=93Y-=?&)?!^nCYRT<0jw0>yR4#vS?9)I77H zm*~;Sp!arY3Uf1pM3bA>^=$oPl-$;_4auSxK=ekVVMT{LO1IV3eUS3`-+uQOs}^m; z^{xJSLdY$|G{VD`AiGMM!x?Q>yNLlhyDk4)f}EQkBjgFv1Q_QhvQ4nwzR}zAS7=A0kS5NeVx#G7{#H-a z>$gdkKQ6ID8HuvWo8)739#_Lw^Q<0RHmqgzu-GOn-> zX)WR;*;zptKAi7sE{$Z5%ZKxro?FI3e!%w`Y&02Pv3_qjWNxb`ChV)B-P98B4aJEx z_FC_QX_xdO0T7xUZP~F2nUctS~XM+*@`u%u1W7F$i-&d-*Hq^GQ zU>ib5`{3L3MK6K3dL5+?ZM&~_J&%GKNpujyR6+^dX_yC{Gs-|t(T zzE~PPJg(CytnXG(HVqb=?2bi;b#57wDmqiK8e`#L_i8-aCmF3=Q`~+ zy)Rd*^UM@+nME9yjxrs0XNBDv)PmW77&jZaC!VEaI~rqzj)Tz2b`8V&rS~#?POH-v z_}LcxmL5gq#5GuPr#6v`gboh5*BM_{(qg^M@*s{az-j0uP$b=!2tbF6mgboyr^rQb z_(>abK=&;0z6e`qh%6yEpgnVKT3AQ~Q?|MnZZpsUEl^fL;OQU`UhcFU`w|YP;{fval>gwaPcjL2Zf8zV2#>|=tk6yrC)4@$ z^>{L4lnjs&`cux`{E?03S0do{H9bI*fXGo&C@9NvG%UeNe43~Lq`2deFLoJ^hJWLX z#Fb3`LHi+_5-}Dde5v56eVT0VxMoiYN~&|bP?43CtyD+|aYo20NZMe#PvrD+aZs99 zDr`ULaFd4gP7|t5w|(L9r;Zt@Zu?SjVc-hN!ahf4M9txU z7$8jwYjUF#w{TYZf`^pk7PYXHZYdfDqZ#4>bJW>7%4%g(gxQ$V( zvU_-Z9BD_Rn6?j+hY@}@4@w}3*{R}THhzqJxM;A z7>-4Q)^ce3xDnAT*+WJ%P$kU0wnC;1<>!q0du&C!zW%(mBwi}oKH-I8Bf}MsP(O+j zBOXM0Dnf%NY!OA6RVXf;OPqrsQ8<)*{A62j5@YT!+-YSo&V5EYt=;vgPA)u}TbP%O zRN|>h0YakQSp=KRVOY+aA^tZ;>NgrtIAL#U@f6LF}jyu~g}?$ThxsDh!Ss}dMh^pp$Cer1(L0s0m4=vZ_! zJaBZg;dq{^wc5=9eT!;z0YXn zP=gpJ@u^bP@^LDxi3i?JrX|l44rw9=11rBTIw7rHQ$EpLj{d&olw~c4%Wsl zRrH=+kbyAQdyW#`FBZW$5u2g3lw1GG-QSmE6~`9 zN{VW43T+-hjNOdPut6(F!DvPeahs@gsd^TQ%Zz;zo|49f3psYT$tFG7DBJcs14OA* z(MQu{GZz1c^krx5c$~;TA+(hJ)Q^ac&k=n&Rg0$Md@mVU$1-Pn)nfAOqWf7w7wx}F z=dRsG|8HAy7E^;vkEVegGLp%T;54d~&-cPa%Dpu+>pI=2B4rV8RO>1jiz>B&8ebKl zAchl{1r1BLu~O|At+KoeC^)u60%h)_PPjyWC*r4wEAsooA1-hqCzUM!e70|S`BLd* zz=7f(H*6oHt!0+?g2B&wy*+-AKft_3yJCrqcdd~!iSJHP*?bxoJ9Rds9eWK+$WGO~?p X$uD0l>=&mlF$=+jxhlW?=U@K?Bu%Hc literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/std.89t b/ti68k/bin-89/std.89t new file mode 100644 index 0000000000000000000000000000000000000000..13d9c73aa41fa2f4b38d5a5f658bc0bf830a7a48 GIT binary patch literal 168 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

N^MdYj zl5sXeTFuxA_@&NlpKCL|?>pgorREi9nrrOD#N3XzY(`HFR;8IXW7~B9&bH_LJ0UBc z_U~l)pSInZbD_pJ`l%x!Hs`09eJ*!gaH+LfQyGg!#=^%~EJi!ClCYSk7*A|_f0yF= z#c}xK49>r%pO}|Eu}sJ7iV^GFOwTr8a&6l){%e8BsQ=o`sp#paZMRRrq>pHXPcuo2 zdA>!Y>CSW2Vr5qXp5nA$d)``R%NOS3&*z=-+P3^j`5BEj(|S0VS()Om9j)zreF&1M zG$r7HtoW-ki8WhYPHRW$xP=VOqlY(0JpGg^jnu?ZqJ*8xn}AXIqV&odSe0*_ZbxBw4Tq)7xU1EmmS9LjI48JygdDQz}fW=9m)^dM(f{L`)PBNHexd5 zp3oAd@RQl*RXTsr*l*5K#`h>bZ|v9hDAKmU6JDlldvm9;<_c+98&I=Q_F9Xz7@wks zF7$M9p3ho?wac30b1i{Ab3UvYrTZWFyAaxUDZU@Vw+-J5@U39o65|+oMEX10s=aDnx*oJv9Ym2uQ^r8kn=R-UTD+Kr1uA*eK<#itJapHae9Zt z<#ME?Imf;SyJl8LCgCd4n`<;It z8-opOR2r;1+dO(t-jY3OdyV?oCC0L{&cW;$=}yPrR=f*9h0PJXZgUp&;E%Zt@#X8# zhd)uEIc(KAGAYtQ7_6XsrNx(518%o~?#WaKmBr_<6oohe&6BA760FIL5tYg#8HJwc z*hH!(y@RTY4V(Xepz5eb)$glRopk&K^CVF91xeLBrs``dRiCNp)TlcBDWYeMPS5(h zoo$ZIV{Ly_DOh+C1)+&a3XXt+V>2WL$AmJe{*B6s)I*#Lf8x+)A7KhYYUlK&&a<2Y z?e!6*Z&EYul|WYk_uVg|!sTkKT!bAErSEJDR?B+(=Ahq(ZN5!9%ltZ3C{}l2gcL>|4EZk+yl%S{}~=AX#9V0V8#D8K@Djf$}j%^ zU|?Y=0gZh+Il#GXRWke3K7ixuQ~8h|cgNC^Rz5j-n^b0IJO z|4DTNl}fu=fC{o zfT@tduN0!@{~KV+djuNg(DLvIP{`u^0csh9ITZanw7 z&|Dh4T?IUp7T6nPaas-(1GcDueHjj5&em~$_y4ib4Uis>%>VzvI*vg5eGI_Sku1h7 zz_iH$l)nL-on!c41gspvqbl~mktn|_&^Ejp@Tg|czEJS}2cU~dzzm4*JY0epe#FiM E0FDQzY5)KL literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/tigcclib.89t b/ti68k/bin-89/tigcclib.89t new file mode 100644 index 0000000000000000000000000000000000000000..1b1a7770574b9d442e1ff59c804189c939e5263f GIT binary patch literal 402 zcma)%OKQU~5I{#{=WQ;K;GGv)r(g<=^T7~ONV91-LXpPS5JfhU(%z$Y=)HQB%1zy3 z$f86>RMUoBH)r(H{pLFssPW3w1BN~bc`|qd4$&*x T;0Nf9Z0$tbt$5AD=lJvmyBc*5 literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/tiosdlg.89y b/ti68k/bin-89/tiosdlg.89y new file mode 100644 index 0000000000000000000000000000000000000000..0f8297da16e68b7e430335c3fb9e59e91bc057e1 GIT binary patch literal 6030 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 literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/ttunpack.89t b/ti68k/bin-89/ttunpack.89t new file mode 100644 index 0000000000000000000000000000000000000000..742d0969b7a28437bfe3a6c5568ba9a82cdc17d1 GIT binary patch literal 3610 zcma)8+iqJ`5Ou}dk>CS(GD522Xd~_WMQK59o0h61uF?dRB4k<4A+g9!wu7LhpTke^ z#Ha8nthM(!$Hq>9_MtwrXV0uzvu1X8caNXPw7Yw+ceb3KpU!*#`_H}J5qy`++pC+& z^rz2yAN4-{q}TiX4Fi1qXYXEr`Rh%6TL0KzEa$h=<-6+kYB4*zs!#jV^U1t_y_mhN z#~0UociPWqoA%4e*=(xrwCYXk^aHVreLHr&*p7U4y}Vu2r)D#DW4D`j#Mr`dHo3f< zY+=sUE#LZ=<$QASb~9{~ZYxM*-wHFosOzicd{!^^s`tmoCx)4p*&VgL9+Tdk@y&R!v(q(oaeh5t!m!iDE=hL>*>mv4 zmu<&?`){Z7*@FjhFc@s7{&{jSJ8g1*I8_nL!-pM~Qs@2q{{k=H(VKVl3PTrc^kVp3 ze??1YKOF79di->Ba`>dLZS1gj=Qw@z{P-0P)Ar%P@b$Cd!NIVv-5sI#UmqV0zj^Z# zr)vA|;V9RKL%n@CIyruH@^tj={?XCNAzaM13j&W`0e0)MQbX7B(|US+c{8sUi~eTQ zchKTa2Au6(@z2k}U_8Df&|o$BSv>tay}tk9;k!yj?~O1zcrCQF`0brjT0|p_h*B8E z4=Zr$m6oC^1{}a(f)`2~8wL0g+B$s0OQ;}?6hX@FTt&9rU zCWTeTi;B0M)kv6Bgrn5n!9gV>6pYaan~gRb;jBdk*QA9B)^@H49X;XuWMH&b$`+|j zD9Rd95w(m_Al*6yrG#|~h?x)7Sh_1w;ma9EM(`E#2h*48kuO*8SQL<>aO=GFaPwfH zbyJO-W%$OJ}kY=|Eh z(Ug$DlQZQapj(4B0;a@8Xd*`dWk`g(7BVUKm))DKil27E4{%~>%NHF^vU zY73XhFl$lTiwa?t)-mO)C>vtyu4c(FRbt;umos0M^SVYq&d{E!F@XkLie5XC5y85n zs$AAho@?a{)`ZqRv~sSzGm0#4LMcUbMO!L3%cdl&+Wu2!)+2fzI>*kyFMwnI;3qrR zG{8iM8D%IPaSw3UyS5&m>xH!X09Kl&X4vaaMX_r_HS7T=rwkk94+=}?kkoodDS$)l zC!ZNenP13^O(NLJVAmD26bUsa6&EXhx}+r(R`immgN?|NQjPEpL6^4w}{S_-ID!JX6-99r5CNo;UutFxX9j)1c9-N1nE3k^*s(1-E@ zd9~c43M0e`Lvfg1AV!-C;x>+HUk0c|Q6*V!g(%G_&0_^D>y0E)P<=ClRa>&mdxz6h z-YR4RQ6Xhc7)s*Jkoa4*x&bc8KZZQ`Wel}KGc}$f9lEFR6_y zgRKi48ldb9fmgBYfI&OVhvbx$xrSiSEkr>*T451^-w3!Vz_HZQtXKfxB0+X;np_Mv z6SjQ}*i~&oCdV;+LS4*5v{n&;vuOzdSjvzLa8{@Y+b2KO+<$r1@^Nh~;3PlD QIeEtUey{5N^~YC#1Kz1h8~^|S literal 0 HcmV?d00001 diff --git a/ti68k/bin-89/wingraph.89y b/ti68k/bin-89/wingraph.89y new file mode 100644 index 0000000000000000000000000000000000000000..f3015adffa3bedce3d6fe3e69b62dcbb674f4cbb GIT binary patch literal 2540 zcma)8OKclO82M9M?xh$_q-lIst(MBA0zesFUA4RalQ=Y2QWZLx&M%h?D=_K?G-C91~`c-~w`Hpg0TLZxouAQXA~_H}2%t!o29 zWr&LkP^_q{;QP+^3*0#)&(h+tHIq||WC&e%$f+5;5w=`XtCd1#aj~4k7T-T`7um_n zST5mbyzZ8hDc-Ciwf~6!COkaFTgYdp;QkZ-*WrGdN`&J}VdpH!`^Rz020fWz|CWRmiQ#%FBXf`-E*YxN7gj%rdR16Kk& zjO}73_F$Tp*=sjknlS;vtu`qzS`)(u5crBcA-ac>vymuI&W=5$*)GA8-r6uPn?q@e zlPv0O4T9mY!qS3cu!R|x-3_g`3n(Et7COEotpmhjoAD$cnKR5T4xI~r!k!gFhf-Gb zwrUmxUk+}vBcgL~b>xOrh*R{-+@+_tUlZ2T8rA33`WSDM#q z!t&s^!J8~DkV7dihz!1IV!M4g-k0xn=ybwaLQ$6RZ0e5+98fR}y@N}oiyajN&dG;T zM)MptZ?FGUGu=kSyXwf)El( zL`v-W{SXl$f{++zrswu!L5XO<35_!Sn%QOu7mJrRe%q?Uh^)6`HbtZcYNaRVu130=B{el&C0ar1a;wV#E z_zI8(tL?X=NuZ*pV+)dNIPPSNJSJ^^oHGXb)6Ecr0w9? zux9EFDF$?dUc0L|+ggKxz0uJc+AFMUTRn79JVLi+S~kL+I~ZoW3C{Nh26Z|GtCo4O xTCW*Kwbp1@vE66j! zMq-gdYH@N>W=XLQkT!q{DmmF7YPfSlxL1E6uW5dn_g@g6Qg)?CU!OEdFQ z6~H3Cj_#h$h6)-Q>h9_`HWr%N>LKcySd@Qwps+@bkgA~fr#&Mid2MDJ?xWPx6(C9`o| zP?UJNtmhJy@{*#s-HK8w7qqy(tSF*R&?CW60 z-k9r;@=f)#PUhEe@(3Fit>(owvYYNS#C|N-Y>Um3jSYwyU}KQ1OXg0VYqiA>MwUea zNlQj2Tyd;hmDk+Kbv=r!UzfK9*w1V*d~5zA*^zgd=PJmRfShK-tC6QvH4VYag2eNg zQ=9qT>L^nyS{I#->;M1& literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/assert.9xt b/ti68k/bin-92p/assert.9xt new file mode 100644 index 0000000000000000000000000000000000000000..e64b549ec32d83efc5eeadd68fdb479357fb0702 GIT binary patch literal 222 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0o5iJ7pE4LFfb@GFf-f(@|Q+|4QOFtR8Y=L z%S%a3Q}A2j~ts!>nTdh3SNUq3Z!4%u~ZcyS_%x}rW%!%r0T^E-0z z@i$eY8@r9`ZD`dr=Zks+e(rpa2BV=dvW=l-&S?-j2e5YbdxpDS2mUdlU;X3m$@g4( zy>-GCTW@&2yW7;ECmP$kOze(rHm}Y;wNP z4^K4x>%<~xp^7$i81`mmX$!(ax@7T9TLD8Gliu4^?7WalrwX=bL<-$1QZ<)Tf|aXS zdsa-MSA`?jg$jq2ygs}&rz(-nO%=YF=(+BxmtbPP7-HD&xrgkuCrfar%@?{krE?6A z7;k^{auWy8h7^WtZr*}N=jhQ4^CQ@~EtX-J{AdC2e0TxTkeSsw}m8D8WvfFC>V?FdvtLaizRRtWzY0t5xFC z^DNYD5`@{o47)|9EU*9rw=)o3b;<2TI^+de;i2rLqkuT#-Xd9%Q-lJEFHaH@Bo6il LVR$mBUybb_X#sIV literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/default.9xt b/ti68k/bin-92p/default.9xt new file mode 100644 index 0000000000000000000000000000000000000000..4966a1f5b28f3b4d0bf1bea926d74a00c7715f76 GIT binary patch literal 3054 zcmb_e-EP}96n3yX_a#^u2qYmLY_}bpH4UK1bShMq3`q{w76su%RHDX~3|ZO|w7uIS z>}C(J_u3Qe8Fna26eTN5H!L@?4!`rm@BC5Id~21X9k}9);mChD2(A45i-RyeQEjq0enU=l_gQgAWIJu-#i{K1Vl)z zrPm+OIEcbN7<|et1PVW&9IJyzV_fU7oyOb`68qY(W+uHl}O zW8&D>JK+buFfnw?D8r%xcO}LDoNvk#@PsEhx1FSGAXO#2TPV8Z*%B&63#~ zKI(w;Hrj(e7f`z1Q5GPd7<=~;M^)d8jMjeTFbgyPB2IySJW$R=Nr>R3&Pk)0+ha%+ zPenzYqzl~@Y*eR2_kEXm{*(|HnyV~Jqsu&_geVFjyX$o*X_lvP!wyU%>r6M^g4a5PnsYAnO~)&&KLTk)BCxfz({2?3IH-QMap#6XNLy%` zX9UFibfxr~)1{2mea4uY?#&;$PKBytmkFw+ok5k97STO)r6T$Y$m8jNe%fqFcDY81 zru>{lfu?C{W4)0y*^sN%daYzftD{H-oRTS8nM=sKnWS|{VNO&zMwPB#+o&TQsk-1q*g%lR~i1)^YEO&@LV`IDPmEg}1|(k-WpKi>9OcPqD8KZCO&N1qV)&J_`z-~FXmlS-n>86{!Dp9?+8@Nz&c-H>VXFl{`*%S$@e6 MI+j%L&tHH48&M6URsaA1 literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/doors.9xt b/ti68k/bin-92p/doors.9xt new file mode 100644 index 0000000000000000000000000000000000000000..c79f0db4e5ef392a8780ba3235a1b7f00db79c5f GIT binary patch literal 906 zcma))QHt9z5Qd%REvL}N5F`^qA6qB|uOp~wVg*@VLSF`NByUU|8DyJM*c0>~y;qM? zIZk3{4W)h=N%PP5kH+#m5q|jSc@yWQJ{+ZS{`;Fa+-hZ6n##rpXX^Z#I?nHJEnxcI znIJdMv{V^dGsfeYYnQoJ*Ik~qsffiQd7Qb*n9|J8tkrRTYN{IPvPRDe<@!)GQc1g* z>$0kw=lQ9W>S5+KL%1p`HM52-lhnYvO$Mbx8xV4l}T&WiYv=T z-<8p-KrMS^E49os%j?WPS!&u8_3HTfY73@3!67Y*(E+4Vn%iw}I$ST)Wlpe%ag99y zUkDB&WHA6q30?qaTL}Ek23$8Mgp3JiFt&&{+Fp4|bBzf=7yEOQcD>?!SrhAjM)*U! zv3BS-lwOC-sYrMPPyQyMeRV|X8UnW6ZRj4hei-$m?A}7efbK&9akASnZvWBcRlvV0 zQ74jktRk&*0KkD6IM^Xzp literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/estack.9xy b/ti68k/bin-92p/estack.9xy new file mode 100644 index 0000000000000000000000000000000000000000..2003e702beb843294e42ae5e0785b3eece0cb0fd GIT binary patch literal 12268 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 P5hwkd3R~=hm!A4RwH@TW literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/estackle.9xy b/ti68k/bin-92p/estackle.9xy new file mode 100644 index 0000000000000000000000000000000000000000..214255fc31dd3fb8168d263ab06518c38a7d820f GIT binary patch literal 5670 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 Pb(JlP+39~Xz4CtoS_iLW literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/gtc.9xk b/ti68k/bin-92p/gtc.9xk new file mode 100644 index 0000000000000000000000000000000000000000..fca265c817ffbc614345779834e158a798fb2b30 GIT binary patch literal 109161 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 literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/homescr.9xy b/ti68k/bin-92p/homescr.9xy new file mode 100644 index 0000000000000000000000000000000000000000..7fe5a7f8e1d077a36a94e3dff8da23e8b8dc3e35 GIT binary patch literal 1438 zcma)6&utMz>$oJ*K#DYF|k!5TJ_O?q%N0eBaDB^PX)O zwVBgr3`2n%4y!j<0RQ(>U=E>6CocoLD&R2Oo;MqGNx#TvuBMv3zHXWV~NzHF#eY4jNq~n);uZbt@%lT3z_*#H5 zD@@VtMH+Bo+wt2%F7{WZh}vIX!BMBG8$eM_`xK=#IfPhvp3+i}dr zHecEXQ-3D=Q$}hHRa4R8T}VpTby(Xev&NU&Z0)=MB(CVI_!?s7wvH(5K(x(Mn{!vW zA23i~Xex}t?G=5H1*L@hs0cOD#B!hy#HKUj(WWskd6l{=epMQQLvVYT9*VXq-EkO7 zg=R`cF@O)@-b%`#dMeZ(q0(!<+eoLRAvChk^*V0TV+{g=*kB8!!-KBPw_NBre!!6? zEwu1$g6naxeXqj_*iJnF8u*LUuD4n#pfq2r&C%M-Y!y|+UU}v`oqpTRS1-r_l=4=g zYyvhg(x9h-Nbw0ZaSn_V`;PbE&oOuJ!xM+|uVHj7ByM8L8jSroMy)RKAu;~@Zm_yI zs)`q}xi2|8JheXE2um-I!C9EvL$FTC+xUYx$%-{N1@o&5o`?}=crJU2QJTLzRy^Wsr#e0)QFX2nknTo%}9p8Y+La8tZuZ}+Y7sN`KVE_OC literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/keywords.9xy b/ti68k/bin-92p/keywords.9xy new file mode 100644 index 0000000000000000000000000000000000000000..49e8cf5af17a83541b2665a57377c27809dca86c GIT binary patch literal 792 zcma)3J8M)y7(FxV+x7j5(Il(uBW{sS&_WwiL=cf+CFnAH@9gfdvoq`5xyA$=3&Fxh z8?lx&wia55U~lCg5bUjNYy{8Ty^_`ghi}gL9`ovS?%up|wbK#U7;2U4fd7TSDoaOt zea(lwXrh6c2C#WA^~=w9ZmgvEQGP%t^DY`!YG7U{9HrkLt1Nh637@b#Y3=eca1Bqe zt&-OCfm^r_kz}s>#;PWi4R%a*N&(wRCS8>U-eG5D zxXhM$J$@G*Wv$N?@KwxWf2x=SH5jXwRc-+Mz%T6Ga=9Y*knOS_EE;H1ce^UaV0vZL z-EJxZ_K}(5*~Ow*#vv+I@ZJ!Yae$#0v>GuI2gz)x(szhe98Su+A~F(3$ii%B--mc8 zn^>SWF6$Ww@l<@lN$TmFI;RsDtA|yvGTKfsg!>gc&mE!9;~I z#5eI1r)e0Mdc}9lGFYFUBHnk|>) zb)2aT6-~wk(ISf&$}CNgw{bS@EhEVxWb<%hyD|6!{_Jv{?s}*mrFLDb z>84a0N%Lmr&66xkIuDPQHAAoM=^WSS-)n|=&n>H_?T!d7&<*P52)!K!gZV9*VIxb+ zI7zY3gbdf3(Vw$2QP(UTid)9G(2S(6t6Cq;R%gBFniiK;i;oG;%2VFON!%awZB^Bc zUQ}_i(2VYvdy+SaW_**Mdh4jm+tvBG$5K4Dj?GX|cyS${0%sm=oi^IrLbVPu3TOBP7Sa}HPi``ODl zONW@ld;CdIa|nA!L2Njs{#AZXWypQl*=|UCcrnf8GoX7%f(V0vae1YnzP)xSP|g{L vQQk)#br^g~x3FPe;L<&Kw&Sa;6QhW-(j)-m{-Yc}5`W=JG|q`W?%qEEuTZt7 literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/patch.9xt b/ti68k/bin-92p/patch.9xt new file mode 100644 index 0000000000000000000000000000000000000000..094e1d461f810a97669cbeb0e4af106e15dca861 GIT binary patch literal 5660 zcmbVQ%W~t^5#>~N*e9zjIK!$ba)y!tkb=lbdBLGE9#$w)#fLnJ>AD3HkVFS0C;%GL zj_p6mGC$%k@j73T)Axl7iZgLV3lX@ukM7gmr@QZ~SF=H<`|8!R%3Z#?57Wx;{(DxL zVD2u!GW}!AIPX>L~oAlogZhQ+LXnf+& z=93Y-=?&)?!^nCYRT<0jw0>yR4#vS?9)I77H zm*~;Sp!arY3Uf1pM3bA>^=$oPl-$;_4auSxK=ekVVMT{LO1IV3eUS3`-+uQOs}^m; z^{xJSLdY$|G{VD`AiGMM!x?Q>yNLlhyDk4)f}EQkBjgFv1Q_QhvQ4nwzR}zAS7=A0kS5NeVx#G7{#H-a z>$gdkKQ6ID8HuvWo8)739#_Lw^Q<0RHmqgzu-GOn-> zX)WR;*;zptKAi7sE{$Z5%ZKxro?FI3e!%w`Y&02Pv3_qjWNxb`ChV)B-P98B4aJEx z_FC_QX_xdO0T7xUZP~F2nUctS~XM+*@`u%u1W7F$i-&d-*Hq^GQ zU>ib5`{3L3MK6K3dL5+?ZM&~_J&%GKNpujyR6+^dX_yC{Gs-|t(T zzE~PPJg(CytnXG(HVqb=?2bi;b#57wDmqiK8e`#L_i8-aCmF3=Q`~+ zy)Rd*^UM@+nME9yjxrs0XNBDv)PmW77&jZaC!VEaI~rqzj)Tz2b`8V&rS~#?POH-v z_}LcxmL5gq#5GuPr#6v`gboh5*BM_{(qg^M@*s{az-j0uP$b=!2tbF6mgboyr^rQb z_(>abK=&;0z6e`qh%6yEpgnVKT3AQ~Q?|MnZZpsUEl^fL;OQU`UhcFU`w|YP;{fval>gwaPcjL2Zf8zV2#>|=tk6yrC)4@$ z^>{L4lnjs&`cux`{E?03S0do{H9bI*fXGo&C@9NvG%UeNe43~Lq`2deFLoJ^hJWLX z#Fb3`LHi+_5-}Dde5v56eVT0VxMoiYN~&|bP?43CtyD+|aYo20NZMe#PvrD+aZs99 zDr`ULaFd4gP7|t5w|(L9r;Zt@Zu?SjVc-hN!ahf4M9txU z7$8jwYjUF#w{TYZf`^pk7PYXHZYdfDqZ#4>bJW>7%4%g(gxQ$V( zvU_-Z9BD_Rn6?j+hY@}@4@w}3*{R}THhzqJxM;A z7>-4Q)^ce3xDnAT*+WJ%P$kU0wnC;1<>!q0du&C!zW%(mBwi}oKH-I8Bf}MsP(O+j zBOXM0Dnf%NY!OA6RVXf;OPqrsQ8<)*{A62j5@YT!+-YSo&V5EYt=;vgPA)u}TbP%O zRN|>h0YakQSp=KRVOY+aA^tZ;>NgrtIAL#U@f6LF}jyu~g}?$ThxsDh!Ss}dMh^pp$Cer1(L0s0m4=vZ_! zJaBZg;dq{^wc5=9eT!;z0YXn zP=gpJ@u^bP@^LDxi3i?JrX|l44rw9=11rBTIw7rHQ$EpLj{d&olw~c4%Wsl zRrH=+kbyAQdyW#`FBZW$5u2g3lw1GG-QSmE6~`9 zN{VW43T+-hjNOdPut6(F!DvPeahs@gsd^TQ%Zz;zo|49f3psYT$tFG7DBJcs14OA* z(MQu{GZz1c^krx5c$~;TA+(hJ)Q^ac&k=n&Rg0$Md@mVU$1-Pn)nfAOqWf7w7wx}F z=dRsG|8HAy7E^;vkEVegGLp%T;54d~&-cPa%Dpu+>pI=2B4rV8RO>1jiz>B&8ebKl zAchl{1r1BLu~O|At+KoeC^)u60%h)_PPjyWC*r4wEAsooA1-hqCzUM!e70|S`BLd* zz=7f(H*6oHt!0+?g2B&wy*+-AKft_3yJCrqcdd~!iSJHP*?bxoJ9Rds9eWK+$WGO~?p X$uD0l>=&mlF$=+jxhlW?=U@K?Bu%Hc literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/std.9xt b/ti68k/bin-92p/std.9xt new file mode 100644 index 0000000000000000000000000000000000000000..13d9c73aa41fa2f4b38d5a5f658bc0bf830a7a48 GIT binary patch literal 168 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

N^MdYj zl5sXeTFuxA_@&NlpKCL|?>pgorREi9nrrOD#N3XzY(`HFR;8IXW7~B9&bH_LJ0UBc z_U~l)pSInZbD_pJ`l%x!Hs`09eJ*!gaH+LfQyGg!#=^%~EJi!ClCYSk7*A|_f0yF= z#c}xK49>r%pO}|Eu}sJ7iV^GFOwTr8a&6l){%e8BsQ=o`sp#paZMRRrq>pHXPcuo2 zdA>!Y>CSW2Vr5qXp5nA$d)``R%NOS3&*z=-+P3^j`5BEj(|S0VS()Om9j)zreF&1M zG$r7HtoW-ki8WhYPHRW$xP=VOqlY(0JpGg^jnu?ZqJ*8xn}AXIqV&odSe0*_ZbxBw4Tq)7xU1EmmS9LjI48JygdDQz}fW=9m)^dM(f{L`)PBNHexd5 zp3oAd@RQl*RXTsr*l*5K#`h>bZ|v9hDAKmU6JDlldvm9;<_c+98&I=Q_F9Xz7@wks zF7$M9p3ho?wac30b1i{Ab3UvYrTZWFyAaxUDZU@Vw+-J5@U39o65|+oMEX10s=aDnx*oJv9Ym2uQ^r8kn=R-UTD+Kr1uA*eK<#itJapHae9Zt z<#ME?Imf;SyJl8LCgCd4n`<;It z8-opOR2r;1+dO(t-jY3OdyV?oCC0L{&cW;$=}yPrR=f*9h0PJXZgUp&;E%Zt@#X8# zhd)uEIc(KAGAYtQ7_6XsrNx(518%o~?#WaKmBr_<6oohe&6BA760FIL5tYg#8HJwc z*hH!(y@RTY4V(Xepz5eb)$glRopk&K^CVF91xeLBrs``dRiCNp)TlcBDWYeMPS5(h zoo$ZIV{Ly_DOh+C1)+&a3XXt+V>2WL$AmJe{*B6s)I*#Lf8x+)A7KhYYUlK&&a<2Y z?e!6*Z&EYul|WYk_uVg|!sTkKT!bAErSEJDR?B+(=Ahq(ZN5!9%ltZ3C{}l2gcL>|4EZk+yl%S{}~=AX#9V0V8#D8K@Djf$}j%^ zU|?Y=0gZh+Il#GXRWke3K7ixuQ~8h|cgNC^Rz5j-n^b0IJO z|4DTNl}fu=fC{o zfT@tduN0!@{~KV+djuNg(DLvIP{`u^0csh9ITZanw7 z&|Dh4T?IUp7T6nPaas-(1GcDueHjj5&em~$_y4ib4Uis>%>VzvI*vg5eGI_Sku1h7 zz_iH$l)nL-on!c41gspvqbl~mktn|_&^Ejp@Tg|czEJS}2cU~dzzm4*JY0epe#FiM E0FDQzY5)KL literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/tigcclib.9xt b/ti68k/bin-92p/tigcclib.9xt new file mode 100644 index 0000000000000000000000000000000000000000..1b1a7770574b9d442e1ff59c804189c939e5263f GIT binary patch literal 402 zcma)%OKQU~5I{#{=WQ;K;GGv)r(g<=^T7~ONV91-LXpPS5JfhU(%z$Y=)HQB%1zy3 z$f86>RMUoBH)r(H{pLFssPW3w1BN~bc`|qd4$&*x T;0Nf9Z0$tbt$5AD=lJvmyBc*5 literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/tiosdlg.9xy b/ti68k/bin-92p/tiosdlg.9xy new file mode 100644 index 0000000000000000000000000000000000000000..0f8297da16e68b7e430335c3fb9e59e91bc057e1 GIT binary patch literal 6030 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 literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/ttunpack.9xt b/ti68k/bin-92p/ttunpack.9xt new file mode 100644 index 0000000000000000000000000000000000000000..742d0969b7a28437bfe3a6c5568ba9a82cdc17d1 GIT binary patch literal 3610 zcma)8+iqJ`5Ou}dk>CS(GD522Xd~_WMQK59o0h61uF?dRB4k<4A+g9!wu7LhpTke^ z#Ha8nthM(!$Hq>9_MtwrXV0uzvu1X8caNXPw7Yw+ceb3KpU!*#`_H}J5qy`++pC+& z^rz2yAN4-{q}TiX4Fi1qXYXEr`Rh%6TL0KzEa$h=<-6+kYB4*zs!#jV^U1t_y_mhN z#~0UociPWqoA%4e*=(xrwCYXk^aHVreLHr&*p7U4y}Vu2r)D#DW4D`j#Mr`dHo3f< zY+=sUE#LZ=<$QASb~9{~ZYxM*-wHFosOzicd{!^^s`tmoCx)4p*&VgL9+Tdk@y&R!v(q(oaeh5t!m!iDE=hL>*>mv4 zmu<&?`){Z7*@FjhFc@s7{&{jSJ8g1*I8_nL!-pM~Qs@2q{{k=H(VKVl3PTrc^kVp3 ze??1YKOF79di->Ba`>dLZS1gj=Qw@z{P-0P)Ar%P@b$Cd!NIVv-5sI#UmqV0zj^Z# zr)vA|;V9RKL%n@CIyruH@^tj={?XCNAzaM13j&W`0e0)MQbX7B(|US+c{8sUi~eTQ zchKTa2Au6(@z2k}U_8Df&|o$BSv>tay}tk9;k!yj?~O1zcrCQF`0brjT0|p_h*B8E z4=Zr$m6oC^1{}a(f)`2~8wL0g+B$s0OQ;}?6hX@FTt&9rU zCWTeTi;B0M)kv6Bgrn5n!9gV>6pYaan~gRb;jBdk*QA9B)^@H49X;XuWMH&b$`+|j zD9Rd95w(m_Al*6yrG#|~h?x)7Sh_1w;ma9EM(`E#2h*48kuO*8SQL<>aO=GFaPwfH zbyJO-W%$OJ}kY=|Eh z(Ug$DlQZQapj(4B0;a@8Xd*`dWk`g(7BVUKm))DKil27E4{%~>%NHF^vU zY73XhFl$lTiwa?t)-mO)C>vtyu4c(FRbt;umos0M^SVYq&d{E!F@XkLie5XC5y85n zs$AAho@?a{)`ZqRv~sSzGm0#4LMcUbMO!L3%cdl&+Wu2!)+2fzI>*kyFMwnI;3qrR zG{8iM8D%IPaSw3UyS5&m>xH!X09Kl&X4vaaMX_r_HS7T=rwkk94+=}?kkoodDS$)l zC!ZNenP13^O(NLJVAmD26bUsa6&EXhx}+r(R`immgN?|NQjPEpL6^4w}{S_-ID!JX6-99r5CNo;UutFxX9j)1c9-N1nE3k^*s(1-E@ zd9~c43M0e`Lvfg1AV!-C;x>+HUk0c|Q6*V!g(%G_&0_^D>y0E)P<=ClRa>&mdxz6h z-YR4RQ6Xhc7)s*Jkoa4*x&bc8KZZQ`Wel}KGc}$f9lEFR6_y zgRKi48ldb9fmgBYfI&OVhvbx$xrSiSEkr>*T451^-w3!Vz_HZQtXKfxB0+X;np_Mv z6SjQ}*i~&oCdV;+LS4*5v{n&;vuOzdSjvzLa8{@Y+b2KO+<$r1@^Nh~;3PlD QIeEtUey{5N^~YC#1Kz1h8~^|S literal 0 HcmV?d00001 diff --git a/ti68k/bin-92p/wingraph.9xy b/ti68k/bin-92p/wingraph.9xy new file mode 100644 index 0000000000000000000000000000000000000000..f3015adffa3bedce3d6fe3e69b62dcbb674f4cbb GIT binary patch literal 2540 zcma)8OKclO82M9M?xh$_q-lIst(MBA0zesFUA4RalQ=Y2QWZLx&M%h?D=_K?G-C91~`c-~w`Hpg0TLZxouAQXA~_H}2%t!o29 zWr&LkP^_q{;QP+^3*0#)&(h+tHIq||WC&e%$f+5;5w=`XtCd1#aj~4k7T-T`7um_n zST5mbyzZ8hDc-Ciwf~6!COkaFTgYdp;QkZ-*WrGdN`&J}VdpH!`^Rz020fWz|CWRmiQ#%FBXf`-E*YxN7gj%rdR16Kk& zjO}73_F$Tp*=sjknlS;vtu`qzS`)(u5crBcA-ac>vymuI&W=5$*)GA8-r6uPn?q@e zlPv0O4T9mY!qS3cu!R|x-3_g`3n(Et7COEotpmhjoAD$cnKR5T4xI~r!k!gFhf-Gb zwrUmxUk+}vBcgL~b>xOrh*R{-+@+_tUlZ2T8rA33`WSDM#q z!t&s^!J8~DkV7dihz!1IV!M4g-k0xn=ybwaLQ$6RZ0e5+98fR}y@N}oiyajN&dG;T zM)MptZ?FGUGu=kSyXwf)El( zL`v-W{SXl$f{++zrswu!L5XO<35_!Sn%QOu7mJrRe%q?Uh^)6`HbtZcYNaRVu130=B{el&C0ar1a;wV#E z_zI8(tL?X=NuZ*pV+)dNIPPSNJSJ^^oHGXb)6Ecr0w9? zux9EFDF$?dUc0L|+ggKxz0uJc+AFMUTRn79JVLi+S~kL+I~ZoW3C{Nh26Z|GtCo4O xTCW*Kwbp1@vE66j! zMq-gdYH@N>W=XLQkT!q{DmmF7YPfSlxL1E6uW5dn_g@g6Qg)?CU!OEdFQ z6~H3Cj_#h$h6)-Q>h9_`HWr%N>LKcySd@Qwps+@bkgA~fr#&Mid2MDJ?xWPx6(C9`o| zP?UJNtmhJy@{*#s-HK8w7qqy(tSF*R&?CW60 z-k9r;@=f)#PUhEe@(3Fit>(owvYYNS#C|N-Y>Um3jSYwyU}KQ1OXg0VYqiA>MwUea zNlQj2Tyd;hmDk+Kbv=r!UzfK9*w1V*d~5zA*^zgd=PJmRfShK-tC6QvH4VYag2eNg zQ=9qT>L^nyS{I#->;M1& literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/assert.v2t b/ti68k/bin-v200/assert.v2t new file mode 100644 index 0000000000000000000000000000000000000000..e64b549ec32d83efc5eeadd68fdb479357fb0702 GIT binary patch literal 222 zcmdPW3h}hC)Y4*PNH0mwNGW0<8Za^h0o5iJ7pE4LFfb@GFf-f(@|Q+|4QOFtR8Y=L z%S%a3Q}A2j~ts!>nTdh3SNUq3Z!4%u~ZcyS_%x}rW%!%r0T^E-0z z@i$eY8@r9`ZD`dr=Zks+e(rpa2BV=dvW=l-&S?-j2e5YbdxpDS2mUdlU;X3m$@g4( zy>-GCTW@&2yW7;ECmP$kOze(rHm}Y;wNP z4^K4x>%<~xp^7$i81`mmX$!(ax@7T9TLD8Gliu4^?7WalrwX=bL<-$1QZ<)Tf|aXS zdsa-MSA`?jg$jq2ygs}&rz(-nO%=YF=(+BxmtbPP7-HD&xrgkuCrfar%@?{krE?6A z7;k^{auWy8h7^WtZr*}N=jhQ4^CQ@~EtX-J{AdC2e0TxTkeSsw}m8D8WvfFC>V?FdvtLaizRRtWzY0t5xFC z^DNYD5`@{o47)|9EU*9rw=)o3b;<2TI^+de;i2rLqkuT#-Xd9%Q-lJEFHaH@Bo6il LVR$mBUybb_X#sIV literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/default.v2t b/ti68k/bin-v200/default.v2t new file mode 100644 index 0000000000000000000000000000000000000000..4966a1f5b28f3b4d0bf1bea926d74a00c7715f76 GIT binary patch literal 3054 zcmb_e-EP}96n3yX_a#^u2qYmLY_}bpH4UK1bShMq3`q{w76su%RHDX~3|ZO|w7uIS z>}C(J_u3Qe8Fna26eTN5H!L@?4!`rm@BC5Id~21X9k}9);mChD2(A45i-RyeQEjq0enU=l_gQgAWIJu-#i{K1Vl)z zrPm+OIEcbN7<|et1PVW&9IJyzV_fU7oyOb`68qY(W+uHl}O zW8&D>JK+buFfnw?D8r%xcO}LDoNvk#@PsEhx1FSGAXO#2TPV8Z*%B&63#~ zKI(w;Hrj(e7f`z1Q5GPd7<=~;M^)d8jMjeTFbgyPB2IySJW$R=Nr>R3&Pk)0+ha%+ zPenzYqzl~@Y*eR2_kEXm{*(|HnyV~Jqsu&_geVFjyX$o*X_lvP!wyU%>r6M^g4a5PnsYAnO~)&&KLTk)BCxfz({2?3IH-QMap#6XNLy%` zX9UFibfxr~)1{2mea4uY?#&;$PKBytmkFw+ok5k97STO)r6T$Y$m8jNe%fqFcDY81 zru>{lfu?C{W4)0y*^sN%daYzftD{H-oRTS8nM=sKnWS|{VNO&zMwPB#+o&TQsk-1q*g%lR~i1)^YEO&@LV`IDPmEg}1|(k-WpKi>9OcPqD8KZCO&N1qV)&J_`z-~FXmlS-n>86{!Dp9?+8@Nz&c-H>VXFl{`*%S$@e6 MI+j%L&tHH48&M6URsaA1 literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/doors.v2t b/ti68k/bin-v200/doors.v2t new file mode 100644 index 0000000000000000000000000000000000000000..c79f0db4e5ef392a8780ba3235a1b7f00db79c5f GIT binary patch literal 906 zcma))QHt9z5Qd%REvL}N5F`^qA6qB|uOp~wVg*@VLSF`NByUU|8DyJM*c0>~y;qM? zIZk3{4W)h=N%PP5kH+#m5q|jSc@yWQJ{+ZS{`;Fa+-hZ6n##rpXX^Z#I?nHJEnxcI znIJdMv{V^dGsfeYYnQoJ*Ik~qsffiQd7Qb*n9|J8tkrRTYN{IPvPRDe<@!)GQc1g* z>$0kw=lQ9W>S5+KL%1p`HM52-lhnYvO$Mbx8xV4l}T&WiYv=T z-<8p-KrMS^E49os%j?WPS!&u8_3HTfY73@3!67Y*(E+4Vn%iw}I$ST)Wlpe%ag99y zUkDB&WHA6q30?qaTL}Ek23$8Mgp3JiFt&&{+Fp4|bBzf=7yEOQcD>?!SrhAjM)*U! zv3BS-lwOC-sYrMPPyQyMeRV|X8UnW6ZRj4hei-$m?A}7efbK&9akASnZvWBcRlvV0 zQ74jktRk&*0KkD6IM^Xzp literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/estack.v2y b/ti68k/bin-v200/estack.v2y new file mode 100644 index 0000000000000000000000000000000000000000..2003e702beb843294e42ae5e0785b3eece0cb0fd GIT binary patch literal 12268 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 P5hwkd3R~=hm!A4RwH@TW literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/estackle.v2y b/ti68k/bin-v200/estackle.v2y new file mode 100644 index 0000000000000000000000000000000000000000..214255fc31dd3fb8168d263ab06518c38a7d820f GIT binary patch literal 5670 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 Pb(JlP+39~Xz4CtoS_iLW literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/gtc.v2k b/ti68k/bin-v200/gtc.v2k new file mode 100644 index 0000000000000000000000000000000000000000..fca265c817ffbc614345779834e158a798fb2b30 GIT binary patch literal 109161 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 literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/homescr.v2y b/ti68k/bin-v200/homescr.v2y new file mode 100644 index 0000000000000000000000000000000000000000..7fe5a7f8e1d077a36a94e3dff8da23e8b8dc3e35 GIT binary patch literal 1438 zcma)6&utMz>$oJ*K#DYF|k!5TJ_O?q%N0eBaDB^PX)O zwVBgr3`2n%4y!j<0RQ(>U=E>6CocoLD&R2Oo;MqGNx#TvuBMv3zHXWV~NzHF#eY4jNq~n);uZbt@%lT3z_*#H5 zD@@VtMH+Bo+wt2%F7{WZh}vIX!BMBG8$eM_`xK=#IfPhvp3+i}dr zHecEXQ-3D=Q$}hHRa4R8T}VpTby(Xev&NU&Z0)=MB(CVI_!?s7wvH(5K(x(Mn{!vW zA23i~Xex}t?G=5H1*L@hs0cOD#B!hy#HKUj(WWskd6l{=epMQQLvVYT9*VXq-EkO7 zg=R`cF@O)@-b%`#dMeZ(q0(!<+eoLRAvChk^*V0TV+{g=*kB8!!-KBPw_NBre!!6? zEwu1$g6naxeXqj_*iJnF8u*LUuD4n#pfq2r&C%M-Y!y|+UU}v`oqpTRS1-r_l=4=g zYyvhg(x9h-Nbw0ZaSn_V`;PbE&oOuJ!xM+|uVHj7ByM8L8jSroMy)RKAu;~@Zm_yI zs)`q}xi2|8JheXE2um-I!C9EvL$FTC+xUYx$%-{N1@o&5o`?}=crJU2QJTLzRy^Wsr#e0)QFX2nknTo%}9p8Y+La8tZuZ}+Y7sN`KVE_OC literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/keywords.v2y b/ti68k/bin-v200/keywords.v2y new file mode 100644 index 0000000000000000000000000000000000000000..49e8cf5af17a83541b2665a57377c27809dca86c GIT binary patch literal 792 zcma)3J8M)y7(FxV+x7j5(Il(uBW{sS&_WwiL=cf+CFnAH@9gfdvoq`5xyA$=3&Fxh z8?lx&wia55U~lCg5bUjNYy{8Ty^_`ghi}gL9`ovS?%up|wbK#U7;2U4fd7TSDoaOt zea(lwXrh6c2C#WA^~=w9ZmgvEQGP%t^DY`!YG7U{9HrkLt1Nh637@b#Y3=eca1Bqe zt&-OCfm^r_kz}s>#;PWi4R%a*N&(wRCS8>U-eG5D zxXhM$J$@G*Wv$N?@KwxWf2x=SH5jXwRc-+Mz%T6Ga=9Y*knOS_EE;H1ce^UaV0vZL z-EJxZ_K}(5*~Ow*#vv+I@ZJ!Yae$#0v>GuI2gz)x(szhe98Su+A~F(3$ii%B--mc8 zn^>SWF6$Ww@l<@lN$TmFI;RsDtA|yvGTKfsg!>gc&mE!9;~I z#5eI1r)e0Mdc}9lGFYFUBHnk|>) zb)2aT6-~wk(ISf&$}CNgw{bS@EhEVxWb<%hyD|6!{_Jv{?s}*mrFLDb z>84a0N%Lmr&66xkIuDPQHAAoM=^WSS-)n|=&n>H_?T!d7&<*P52)!K!gZV9*VIxb+ zI7zY3gbdf3(Vw$2QP(UTid)9G(2S(6t6Cq;R%gBFniiK;i;oG;%2VFON!%awZB^Bc zUQ}_i(2VYvdy+SaW_**Mdh4jm+tvBG$5K4Dj?GX|cyS${0%sm=oi^IrLbVPu3TOBP7Sa}HPi``ODl zONW@ld;CdIa|nA!L2Njs{#AZXWypQl*=|UCcrnf8GoX7%f(V0vae1YnzP)xSP|g{L vQQk)#br^g~x3FPe;L<&Kw&Sa;6QhW-(j)-m{-Yc}5`W=JG|q`W?%qEEuTZt7 literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/patch.v2t b/ti68k/bin-v200/patch.v2t new file mode 100644 index 0000000000000000000000000000000000000000..094e1d461f810a97669cbeb0e4af106e15dca861 GIT binary patch literal 5660 zcmbVQ%W~t^5#>~N*e9zjIK!$ba)y!tkb=lbdBLGE9#$w)#fLnJ>AD3HkVFS0C;%GL zj_p6mGC$%k@j73T)Axl7iZgLV3lX@ukM7gmr@QZ~SF=H<`|8!R%3Z#?57Wx;{(DxL zVD2u!GW}!AIPX>L~oAlogZhQ+LXnf+& z=93Y-=?&)?!^nCYRT<0jw0>yR4#vS?9)I77H zm*~;Sp!arY3Uf1pM3bA>^=$oPl-$;_4auSxK=ekVVMT{LO1IV3eUS3`-+uQOs}^m; z^{xJSLdY$|G{VD`AiGMM!x?Q>yNLlhyDk4)f}EQkBjgFv1Q_QhvQ4nwzR}zAS7=A0kS5NeVx#G7{#H-a z>$gdkKQ6ID8HuvWo8)739#_Lw^Q<0RHmqgzu-GOn-> zX)WR;*;zptKAi7sE{$Z5%ZKxro?FI3e!%w`Y&02Pv3_qjWNxb`ChV)B-P98B4aJEx z_FC_QX_xdO0T7xUZP~F2nUctS~XM+*@`u%u1W7F$i-&d-*Hq^GQ zU>ib5`{3L3MK6K3dL5+?ZM&~_J&%GKNpujyR6+^dX_yC{Gs-|t(T zzE~PPJg(CytnXG(HVqb=?2bi;b#57wDmqiK8e`#L_i8-aCmF3=Q`~+ zy)Rd*^UM@+nME9yjxrs0XNBDv)PmW77&jZaC!VEaI~rqzj)Tz2b`8V&rS~#?POH-v z_}LcxmL5gq#5GuPr#6v`gboh5*BM_{(qg^M@*s{az-j0uP$b=!2tbF6mgboyr^rQb z_(>abK=&;0z6e`qh%6yEpgnVKT3AQ~Q?|MnZZpsUEl^fL;OQU`UhcFU`w|YP;{fval>gwaPcjL2Zf8zV2#>|=tk6yrC)4@$ z^>{L4lnjs&`cux`{E?03S0do{H9bI*fXGo&C@9NvG%UeNe43~Lq`2deFLoJ^hJWLX z#Fb3`LHi+_5-}Dde5v56eVT0VxMoiYN~&|bP?43CtyD+|aYo20NZMe#PvrD+aZs99 zDr`ULaFd4gP7|t5w|(L9r;Zt@Zu?SjVc-hN!ahf4M9txU z7$8jwYjUF#w{TYZf`^pk7PYXHZYdfDqZ#4>bJW>7%4%g(gxQ$V( zvU_-Z9BD_Rn6?j+hY@}@4@w}3*{R}THhzqJxM;A z7>-4Q)^ce3xDnAT*+WJ%P$kU0wnC;1<>!q0du&C!zW%(mBwi}oKH-I8Bf}MsP(O+j zBOXM0Dnf%NY!OA6RVXf;OPqrsQ8<)*{A62j5@YT!+-YSo&V5EYt=;vgPA)u}TbP%O zRN|>h0YakQSp=KRVOY+aA^tZ;>NgrtIAL#U@f6LF}jyu~g}?$ThxsDh!Ss}dMh^pp$Cer1(L0s0m4=vZ_! zJaBZg;dq{^wc5=9eT!;z0YXn zP=gpJ@u^bP@^LDxi3i?JrX|l44rw9=11rBTIw7rHQ$EpLj{d&olw~c4%Wsl zRrH=+kbyAQdyW#`FBZW$5u2g3lw1GG-QSmE6~`9 zN{VW43T+-hjNOdPut6(F!DvPeahs@gsd^TQ%Zz;zo|49f3psYT$tFG7DBJcs14OA* z(MQu{GZz1c^krx5c$~;TA+(hJ)Q^ac&k=n&Rg0$Md@mVU$1-Pn)nfAOqWf7w7wx}F z=dRsG|8HAy7E^;vkEVegGLp%T;54d~&-cPa%Dpu+>pI=2B4rV8RO>1jiz>B&8ebKl zAchl{1r1BLu~O|At+KoeC^)u60%h)_PPjyWC*r4wEAsooA1-hqCzUM!e70|S`BLd* zz=7f(H*6oHt!0+?g2B&wy*+-AKft_3yJCrqcdd~!iSJHP*?bxoJ9Rds9eWK+$WGO~?p X$uD0l>=&mlF$=+jxhlW?=U@K?Bu%Hc literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/std.v2t b/ti68k/bin-v200/std.v2t new file mode 100644 index 0000000000000000000000000000000000000000..13d9c73aa41fa2f4b38d5a5f658bc0bf830a7a48 GIT binary patch literal 168 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

N^MdYj zl5sXeTFuxA_@&NlpKCL|?>pgorREi9nrrOD#N3XzY(`HFR;8IXW7~B9&bH_LJ0UBc z_U~l)pSInZbD_pJ`l%x!Hs`09eJ*!gaH+LfQyGg!#=^%~EJi!ClCYSk7*A|_f0yF= z#c}xK49>r%pO}|Eu}sJ7iV^GFOwTr8a&6l){%e8BsQ=o`sp#paZMRRrq>pHXPcuo2 zdA>!Y>CSW2Vr5qXp5nA$d)``R%NOS3&*z=-+P3^j`5BEj(|S0VS()Om9j)zreF&1M zG$r7HtoW-ki8WhYPHRW$xP=VOqlY(0JpGg^jnu?ZqJ*8xn}AXIqV&odSe0*_ZbxBw4Tq)7xU1EmmS9LjI48JygdDQz}fW=9m)^dM(f{L`)PBNHexd5 zp3oAd@RQl*RXTsr*l*5K#`h>bZ|v9hDAKmU6JDlldvm9;<_c+98&I=Q_F9Xz7@wks zF7$M9p3ho?wac30b1i{Ab3UvYrTZWFyAaxUDZU@Vw+-J5@U39o65|+oMEX10s=aDnx*oJv9Ym2uQ^r8kn=R-UTD+Kr1uA*eK<#itJapHae9Zt z<#ME?Imf;SyJl8LCgCd4n`<;It z8-opOR2r;1+dO(t-jY3OdyV?oCC0L{&cW;$=}yPrR=f*9h0PJXZgUp&;E%Zt@#X8# zhd)uEIc(KAGAYtQ7_6XsrNx(518%o~?#WaKmBr_<6oohe&6BA760FIL5tYg#8HJwc z*hH!(y@RTY4V(Xepz5eb)$glRopk&K^CVF91xeLBrs``dRiCNp)TlcBDWYeMPS5(h zoo$ZIV{Ly_DOh+C1)+&a3XXt+V>2WL$AmJe{*B6s)I*#Lf8x+)A7KhYYUlK&&a<2Y z?e!6*Z&EYul|WYk_uVg|!sTkKT!bAErSEJDR?B+(=Ahq(ZN5!9%ltZ3C{}l2gcL>|4EZk+yl%S{}~=AX#9V0V8#D8K@Djf$}j%^ zU|?Y=0gZh+Il#GXRWke3K7ixuQ~8h|cgNC^Rz5j-n^b0IJO z|4DTNl}fu=fC{o zfT@tduN0!@{~KV+djuNg(DLvIP{`u^0csh9ITZanw7 z&|Dh4T?IUp7T6nPaas-(1GcDueHjj5&em~$_y4ib4Uis>%>VzvI*vg5eGI_Sku1h7 zz_iH$l)nL-on!c41gspvqbl~mktn|_&^Ejp@Tg|czEJS}2cU~dzzm4*JY0epe#FiM E0FDQzY5)KL literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/tigcclib.v2t b/ti68k/bin-v200/tigcclib.v2t new file mode 100644 index 0000000000000000000000000000000000000000..1b1a7770574b9d442e1ff59c804189c939e5263f GIT binary patch literal 402 zcma)%OKQU~5I{#{=WQ;K;GGv)r(g<=^T7~ONV91-LXpPS5JfhU(%z$Y=)HQB%1zy3 z$f86>RMUoBH)r(H{pLFssPW3w1BN~bc`|qd4$&*x T;0Nf9Z0$tbt$5AD=lJvmyBc*5 literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/tiosdlg.v2y b/ti68k/bin-v200/tiosdlg.v2y new file mode 100644 index 0000000000000000000000000000000000000000..0f8297da16e68b7e430335c3fb9e59e91bc057e1 GIT binary patch literal 6030 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 literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/ttunpack.v2t b/ti68k/bin-v200/ttunpack.v2t new file mode 100644 index 0000000000000000000000000000000000000000..742d0969b7a28437bfe3a6c5568ba9a82cdc17d1 GIT binary patch literal 3610 zcma)8+iqJ`5Ou}dk>CS(GD522Xd~_WMQK59o0h61uF?dRB4k<4A+g9!wu7LhpTke^ z#Ha8nthM(!$Hq>9_MtwrXV0uzvu1X8caNXPw7Yw+ceb3KpU!*#`_H}J5qy`++pC+& z^rz2yAN4-{q}TiX4Fi1qXYXEr`Rh%6TL0KzEa$h=<-6+kYB4*zs!#jV^U1t_y_mhN z#~0UociPWqoA%4e*=(xrwCYXk^aHVreLHr&*p7U4y}Vu2r)D#DW4D`j#Mr`dHo3f< zY+=sUE#LZ=<$QASb~9{~ZYxM*-wHFosOzicd{!^^s`tmoCx)4p*&VgL9+Tdk@y&R!v(q(oaeh5t!m!iDE=hL>*>mv4 zmu<&?`){Z7*@FjhFc@s7{&{jSJ8g1*I8_nL!-pM~Qs@2q{{k=H(VKVl3PTrc^kVp3 ze??1YKOF79di->Ba`>dLZS1gj=Qw@z{P-0P)Ar%P@b$Cd!NIVv-5sI#UmqV0zj^Z# zr)vA|;V9RKL%n@CIyruH@^tj={?XCNAzaM13j&W`0e0)MQbX7B(|US+c{8sUi~eTQ zchKTa2Au6(@z2k}U_8Df&|o$BSv>tay}tk9;k!yj?~O1zcrCQF`0brjT0|p_h*B8E z4=Zr$m6oC^1{}a(f)`2~8wL0g+B$s0OQ;}?6hX@FTt&9rU zCWTeTi;B0M)kv6Bgrn5n!9gV>6pYaan~gRb;jBdk*QA9B)^@H49X;XuWMH&b$`+|j zD9Rd95w(m_Al*6yrG#|~h?x)7Sh_1w;ma9EM(`E#2h*48kuO*8SQL<>aO=GFaPwfH zbyJO-W%$OJ}kY=|Eh z(Ug$DlQZQapj(4B0;a@8Xd*`dWk`g(7BVUKm))DKil27E4{%~>%NHF^vU zY73XhFl$lTiwa?t)-mO)C>vtyu4c(FRbt;umos0M^SVYq&d{E!F@XkLie5XC5y85n zs$AAho@?a{)`ZqRv~sSzGm0#4LMcUbMO!L3%cdl&+Wu2!)+2fzI>*kyFMwnI;3qrR zG{8iM8D%IPaSw3UyS5&m>xH!X09Kl&X4vaaMX_r_HS7T=rwkk94+=}?kkoodDS$)l zC!ZNenP13^O(NLJVAmD26bUsa6&EXhx}+r(R`immgN?|NQjPEpL6^4w}{S_-ID!JX6-99r5CNo;UutFxX9j)1c9-N1nE3k^*s(1-E@ zd9~c43M0e`Lvfg1AV!-C;x>+HUk0c|Q6*V!g(%G_&0_^D>y0E)P<=ClRa>&mdxz6h z-YR4RQ6Xhc7)s*Jkoa4*x&bc8KZZQ`Wel}KGc}$f9lEFR6_y zgRKi48ldb9fmgBYfI&OVhvbx$xrSiSEkr>*T451^-w3!Vz_HZQtXKfxB0+X;np_Mv z6SjQ}*i~&oCdV;+LS4*5v{n&;vuOzdSjvzLa8{@Y+b2KO+<$r1@^Nh~;3PlD QIeEtUey{5N^~YC#1Kz1h8~^|S literal 0 HcmV?d00001 diff --git a/ti68k/bin-v200/wingraph.v2y b/ti68k/bin-v200/wingraph.v2y new file mode 100644 index 0000000000000000000000000000000000000000..f3015adffa3bedce3d6fe3e69b62dcbb674f4cbb GIT binary patch literal 2540 zcma)8OKclO82M9M?xh$_q-lIst(MBA0zesFUA4RalQ=Y2QWZLx&M%h?D=_K?G-C91~`c-~w`Hpg0TLZxouAQXA~_H}2%t!o29 zWr&LkP^_q{;QP+^3*0#)&(h+tHIq||WC&e%$f+5;5w=`XtCd1#aj~4k7T-T`7um_n zST5mbyzZ8hDc-Ciwf~6!COkaFTgYdp;QkZ-*WrGdN`&J}VdpH!`^Rz020fWz|CWRmiQ#%FBXf`-E*YxN7gj%rdR16Kk& zjO}73_F$Tp*=sjknlS;vtu`qzS`)(u5crBcA-ac>vymuI&W=5$*)GA8-r6uPn?q@e zlPv0O4T9mY!qS3cu!R|x-3_g`3n(Et7COEotpmhjoAD$cnKR5T4xI~r!k!gFhf-Gb zwrUmxUk+}vBcgL~b>xOrh*R{-+@+_tUlZ2T8rA33`WSDM#q z!t&s^!J8~DkV7dihz!1IV!M4g-k0xn=ybwaLQ$6RZ0e5+98fR}y@N}oiyajN&dG;T zM)MptZ?FGUGu=kSyXwf)El( zL`v-W{SXl$f{++zrswu!L5XO<35_!Sn%QOu7mJrRe%q?Uh^)6`HbtZcYNaRVu130=B{el&C0ar1a;wV#E z_zI8(tL?X=NuZ*pV+)dNIPPSNJSJ^^oHGXb)6Ecr0w9? zux9EFDF$?dUc0L|+ggKxz0uJc+AFMUTRn79JVLi+S~kL+I~ZoW3C{Nh26Z|GtCo4O xTCW*Kwbp1@vE66j! zMq-gdYH@N>W=XLQkT!q{DmmF7YPfSlxL1E6uW5dn_g@g6Qg)?CU!OEdFQ z6~H3Cj_#h$h6)-Q>h9_`HWr%N>LKcySd@Qwps+@bkgA~fr#&Mid2MDJ?xWPx6(C9`o| zP?UJNtmhJy@{*#s-HK8w7qqy(tSF*R&?CW60 z-k9r;@=f)#PUhEe@(3Fit>(owvYYNS#C|N-Y>Um3jSYwyU}KQ1OXg0VYqiA>MwUea zNlQj2Tyd;hmDk+Kbv=r!UzfK9*w1V*d~5zA*^zgd=PJmRfShK-tC6QvH4VYag2eNg zQ=9qT>L^nyS{I#->;M1& literal 0 HcmV?d00001 diff --git a/ti68k/ide/Makefile b/ti68k/ide/Makefile new file mode 100644 index 0000000..b511bab --- /dev/null +++ b/ti68k/ide/Makefile @@ -0,0 +1,55 @@ +# You will have to define environment variables corresponding to your system. + +ifdef GTCROOT +TIGCC = $(GTCROOT)/tigcc_for_ide/tigcc +LIBS = '$(shell $(TOTIGCCPATH) $(GTCROOT)/tigcc_for_ide/extgraph.a)' +endif +ifdef EXTGRAPH +LIBS = $(EXTGRAPH) +endif +ifndef NOT_CYGWIN +TOTIGCCPATH = cygpath -aw +INCLUDES = -I'$(shell $(TOTIGCCPATH) $(GTCROOT)/base_dir)' -I'$(shell $(TOTIGCCPATH) .)' +endif +ifndef TIGCC +TIGCC = tigcc +endif + +SWITCHES = -W -Wall -Wno-unused -O2 -fno-strict-aliasing -mregparm=3 -DFORCE_SMALL_FONT + + +all: bin/gtc-ide.89z bin/gtc-ide.9xz bin/gtc-ide.v2z + +superscratchclean: + rm -f bin/* + +bin/gtc-ide.89z : calc = _89 +bin/gtc-ide.89z : ext = 89 +bin/gtc-ide.9xz : calc = _92 +bin/gtc-ide.9xz : ext = 9x +bin/gtc-ide.v2z : calc = _92 +bin/gtc-ide.v2z : ext = v2 + +bin/gtc-ide.89z bin/gtc-ide.9xz bin/gtc-ide.v2z: *.c *.h + -mkdir tmp.ide$(ext) + cp main.c sunpack.c tmp.ide$(ext) + cd tmp.ide$(ext) && $(TIGCC) $(INCLUDES) $(SWITCHES) -D$(calc) -o gtc_ide main.c sunpack.c $(LIBS) + cp tmp.ide$(ext)/gtc_ide.$(ext)z bin/gtc-ide.$(ext)z + rm -rf tmp.ide$(ext) + + +pedrom: bin/gtc-ide-pedrom.89z bin/gtc-ide-pedrom.9xz bin/gtc-ide-pedrom.v2z + +bin/gtc-ide-pedrom.89z : calc = _89 +bin/gtc-ide-pedrom.89z : ext = 89 +bin/gtc-ide-pedrom.9xz : calc = _92 +bin/gtc-ide-pedrom.9xz : ext = 9x +bin/gtc-ide-pedrom.v2z : calc = _92 +bin/gtc-ide-pedrom.v2z : ext = v2 + +bin/gtc-ide-pedrom.89z bin/gtc-ide-pedrom.9xz bin/gtc-ide-pedrom.v2z: *.c *.h + -mkdir tmp.idepedrom$(ext) + cp main.c sunpack.c tmp.idepedrom$(ext) + cd tmp.idepedrom$(ext) && $(TIGCC) -DPEDROM $(INCLUDES) $(SWITCHES) -D$(calc) -o gtc_ide main.c sunpack.c $(LIBS) + cp tmp.idepedrom$(ext)/gtc_ide.$(ext)z bin/gtc-ide-pedrom.$(ext)z + rm -rf tmp.idepedrom$(ext) diff --git a/ti68k/ide/autoint_fix.h b/ti68k/ide/autoint_fix.h new file mode 100644 index 0000000..def94be --- /dev/null +++ b/ti68k/ide/autoint_fix.h @@ -0,0 +1,92 @@ +#ifndef OSKeyScan +#define OSKeyScan _rom_call(void,(void),298) +#endif + +#ifndef OLD_NONTITANIUM_METHOD +void *autoint_fix=0,*autoint_previous=0; +#define MAX_BLOCK1 150 +#define MAX_BLOCK2 500 +int autoint_fix_block[(MAX_BLOCK1+MAX_BLOCK2)/2]; +// !!! DIRTY HACK !!! +// -- but speeds up a whole lot :) +// !!! CAUTION : not tested on AMS3 !!! +void FixAutoint() { +#ifndef PEDROM + autoint_fix=0; + void *v1=GetIntVec(AUTO_INT_1); + autoint_previous=v1; + if (v1>=(void *)0x200000l) { + void *v2=(void *)OSKeyScan; + int l2=(void *)off - v2; + if ((unsigned int)l2>=MAX_BLOCK2) return; + int pos=0; + do { + pos+=2; + if (*(int *)(v1+pos)==0x4e75 || *(int *)(v1+pos)==0x4e73) return; + } while (*(void **)(v1+pos)!=v2); + pos+=4+6; // leave some room for the jmp + if (pos>=MAX_BLOCK1) return; + autoint_fix=autoint_fix_block; + memcpy(autoint_fix,v1,pos); + memcpy(autoint_fix+pos,v2,l2); + *(void **)(autoint_fix+pos-10)=autoint_fix+pos; + *(int *)(autoint_fix+pos-6)=0x4ef9; // jmp abs.l + *(void **)(autoint_fix+pos-4)=v1+pos-6; + int *z=autoint_fix+pos; + while (*z++!=0x58 && l2--); + if (l2>0) *--z=0x10; + SetIntVec(AUTO_INT_1,autoint_fix); + } +#endif +} +void RestoreAutoint() { +#ifndef PEDROM + if (autoint_fix) + SetIntVec(AUTO_INT_1,autoint_previous),autoint_fix=0; +#endif +} +#else +#define IntVec (*(void **)0x40064l) +void *autoint_fix=0,*autoint_previous=0; +// !!! DIRTY HACK !!! +// -- but speeds up a whole lot :) +// !!! CAUTION : not Titanium-compliant !!! +void FixAutoint() { +#ifndef PEDROM + autoint_fix=0; + void *v1=IntVec; + autoint_previous=v1; + if (v1>=(void *)0x200000l) { + void *v2=(void *)OSKeyScan; + int l2=(void *)off - v2; + if ((unsigned int)l2>=500) return; + int pos=0; + do { + pos+=2; + if (*(int *)(v1+pos)==0x4e75) return; + } while (*(void **)(v1+pos)!=v2); + pos+=4+6; // leave some room for the jmp + if (pos>=150) return; + autoint_fix=malloc(pos+l2); + if (!autoint_fix) return; + autoint_fix+=0x40000; // switch to ghost space + memcpy(autoint_fix,v1,pos); + memcpy(autoint_fix+pos,v2,l2); + *(void **)(autoint_fix+pos-10)=autoint_fix+pos; + *(int *)(autoint_fix+pos-6)=0x4ef9; // jmp abs.l + *(void **)(autoint_fix+pos-4)=v1+pos-6; + int *z=autoint_fix+pos; + while (*z++!=0x58 && l2--); + if (l2>0) *--z=0x10; + IntVec=autoint_fix; + } +#endif +} +void RestoreAutoint() { +#ifndef PEDROM + if (autoint_fix) + IntVec=autoint_previous,free(autoint_fix); +#endif +} +#undef IntVec +#endif diff --git a/ti68k/ide/axplore.h b/ti68k/ide/axplore.h new file mode 100644 index 0000000..7071a25 --- /dev/null +++ b/ti68k/ide/axplore.h @@ -0,0 +1,223 @@ +//void *Port=0; +#define DrawSStr(x,y,s) DStr((x)>>2,y,s) +/*void DrawSStr(int x,int y,char *s) { + DStr(x>>2,y,s); +}*/ + +typedef struct { + int i,t; + void *d; +} XP_S; +typedef struct { + XP_S *s; + int sh,sel,msel; +} XP_C; + +int XpMove(XP_C *xc,int n) { + XP_S *xs=xc->s+xc->sel,*lp=xc->s; + int d=(n>=0?1:-1); + while (n || xs->i<=0) { + if (!xs->i) return lp-xc->s; + if (xs->i>0) n-=d,lp=xs; + xs+=d; + } + return xs-xc->s; +} +char XpSprite[8*5]={ + 0,0,0,0,0,0,0,0, + 0b0110000, + 0b1001100, + 0b1110010, + 0b1001110, + 0b1000010, + 0b0111100, + 0,0, + 0b0000000, + 0b0110000, + 0b1001110, + 0b1000010, + 0b1000010, + 0b0111100, + 0,0, + 0b0000000, + 0b1111100, + 0b1000110, + 0b1000010, + 0b1000010, + 0b1111110, + 0,0, + 0b0000000, + 0b1111100, + 0b1000110, + 0b1011010, + 0b1000010, + 0b1111110, + 0,0, +}; + +/* [IFT_TEXT] 4, + [IFT_RES] 5, + [IFT_C] 6, + [IFT_H] 7, + [IFT_PRGM] 8, + [IFT_FUNC] 8, + [IFT_XFUNC]8, + [IFT_PACK] 9, + [IFT_EXPR] 10,*/ + +#define XP_X1 24 +#define XP_X2 136 +#define XP_N 8 +#define XP_H 6 +/*#define XP_Y1 14 +#define XP_Y2 (XP_Y1+8*XP_N)*/ +void XpDisp(XP_C *xc,int y) { + XP_S *xs=xc->s+xc->sh; + int r=xc->sel-xc->sh,n=XP_N; + if (xc->sh) DrawChar(XP_X1+1,y,UPARR,A_NORMAL); + do { + if (!xs->i) return; + if (xs->i>0) { + int x=XP_X1+2-8+6+(xs->i<<3); + Sprite8(x,y,8,XpSprite+(xs->t<<3),Port,A_NORMAL); + DrawSStr(x+8,y,(char *)xs->d); + if (!r) { + SCR_RECT sr={{XP_X1,y,XP_X2-1,y+XP_H-1}}; + ScrRectFill(&sr,ScrRect,A_XOR); + } + y+=XP_H; + n--; + } + xs++; r--; + } while (n || xs->i<=0); + DrawChar(XP_X1+1,y-XP_H,DNARR,A_XOR); +} + +void XpNeg(XP_C *xc) { + XP_S *xs=xc->s+xc->sel; + int z,z0=xs->i,d=0x8000|(0x8000u>>z0); + xs++; + z=xs->i; + if (z<0) d=~d; + while ((z>0?xs->i:-xs->i)>z0) { + if (z>0) xs->i|=d; + else { + xs->i&=d; + if (xs->i-8>0) xs->i|=0x8000; + } + xs++; + } +} + +typedef int (*__attribute__((stkparm)) XPLOOP_CB)(XP_C *xc,int key,void *ctx); +enum { XPLCB_CONT=0, XPLCB_QUIT=-1, XPLCB_BREAK=1, XPLCB_OPENDIR=2 }; +#define DEFINE_XPLOOP_CB(n) int __attribute__((stkparm)) n(XP_C *xc,int key,void *ctx) +DEFINE_XPLOOP_CB(std_callback) { + return XPLCB_CONT; +} +DEFINE_XPLOOP_CB(onlyfiles_callback) { + return key==KEY_ENTER && xc->s[xc->sel].t==2 ? XPLCB_OPENDIR : XPLCB_CONT; +} +XP_S *XpLoop(XP_C *xc,int y,XPLOOP_CB callback,void *ctx) { + int k,z; + if (!xc->s->i) return 0; + if (!callback) callback=std_callback; + DrawFrame(XP_X1-1,y-1,XP_X2,y+XP_H*XP_N); + do { + int cb_ret; + SCR_RECT sr={{XP_X1,y,XP_X2-1,y+XP_H*XP_N-1}}; + //LCD_save(Port); + ScrRectFill2(&sr,A_REVERSE); + //asm("0: bra 0b"); + XpDisp(xc,y); + callback(xc,0,ctx); + k=WaitLoop(NULL); + if ((cb_ret=callback(xc,k,ctx))) k=0; + if (cb_ret==XPLCB_OPENDIR) k=KEY_RIGHT; + #define xps_sel (xc->s[xc->sel]) + if (k==KEY_UP) xc->sel=XpMove(xc,-1); + else if (k==KEY_DOWN) xc->sel=XpMove(xc,1); + else if (k==(KEY_2ND|KEY_UP)) xc->sel=XpMove(xc,1-XP_N); + else if (k==(KEY_2ND|KEY_DOWN)) xc->sel=XpMove(xc,XP_N-1); + else if (k==KEY_LEFT) { + if ((z=xps_sel.i)>=2) + do xc->sel=XpMove(xc,-1); while ((unsigned)xps_sel.i>=(unsigned)z); + else if (xps_sel.t==1) + xps_sel.t=2,XpNeg(xc); + } else if (k==KEY_RIGHT && xps_sel.t==2) + xps_sel.t=1,XpNeg(xc); + else if (k==KEY_ENTER) + return &xps_sel; + z=xc->sel; + if (xc->sh>z) xc->sh=z; + if (xc->sh<(z=XpMove(xc,1-XP_N))) xc->sh=z; + } while (k!=KEY_ESC); + return NULL; +} + +long XpFatSub(XP_S *xs,char *acc,char *cfold) { + SYM_ENTRY *e=SymFindFirst(NULL,FO_RECURSE|FO_SKIP_TEMPS); + int n=0,n2=0,f=1; + while (e) { + long i=0x00010002; + if (!(e->flags.flags_n&SF_FOLDER)) { + CESI p=HeapDeref(e->handle); + if (p[1+*(unsigned int *)p]!=TEXT_TAG) goto nxt; + i=(f>=0?0xC0020003:0x00020003); +/* if (p[4]=='P') { + char *q=strchr(p+5,'\r'); + if (q) { + n2+=((q-(char *)p)-5)+1; + if (acc) strncpy(acc,p+5,(q-(char *)p)-5),e=(SYM_ENTRY *)acc,acc+=((q-(char *)p)-5),*acc++=0; + } + }*/ + f++; + } else { + if (!f) { + n--; + if (xs) xs--; + } + f=0; + if (!strcmp(e->name,cfold)) + f=0x8000,i--; + } + if (xs) { + *(long *)&xs->i=i; + xs->d=(void *)e->name; + xs++; + } + n++; + nxt: + e=SymFindNext(); + } + if (!f) { + n--; + if (xs) xs--; + } + if (xs) xs->i=0; + return n+((long)n2<<16); +} +XP_C *XpLoadFat(char *cfold) { + long r=XpFatSub(NULL,NULL,cfold); + int n=(int)r,n2=(int)(r>>16); + XP_C *xc=malloc(sizeof(XP_C)+(n+2)*sizeof(XP_S)+n2); + XP_S *xs; + if (!xc) return xc; + xs=(XP_S *)(xc+1); + xs->i=0; xs++; xc->s=xs; + XpFatSub(xs,(char *)(xs+(n+1)),cfold); + xc->sh=0; xc->sel=0; xc->msel=n-1; + return xc; +} +XP_C *XpLoadList(char **list,int n) { + XP_C *xc=malloc(sizeof(XP_C)+(n+2)*sizeof(XP_S)); + XP_S *xs; + if (!xc) return xc; + xs=(XP_S *)(xc+1); + xs->i=0; xs++; xc->s=xs; + xc->sh=0; xc->sel=0; xc->msel=n-1; + while (n--) + xs->i=1,xs->t=0,xs->d=*list++,xs++; + xs->i=0; + return xc; +} diff --git a/ti68k/ide/bin/gtc-ide.89z b/ti68k/ide/bin/gtc-ide.89z new file mode 100644 index 0000000000000000000000000000000000000000..51d058dd393fef67116af8a934e5ab0b4a694e06 GIT binary patch literal 30923 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 DH?-iN literal 0 HcmV?d00001 diff --git a/ti68k/ide/bin/gtc-ide.9xz b/ti68k/ide/bin/gtc-ide.9xz new file mode 100644 index 0000000000000000000000000000000000000000..dc8859cc2bbdec6a9edeefb7cd23d1bb08067da4 GIT binary patch literal 31019 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 Pb(JlP+39~Xz4CtoS_iLW literal 0 HcmV?d00001 diff --git a/ti68k/ide/bin/gtc-ide.v2z b/ti68k/ide/bin/gtc-ide.v2z new file mode 100644 index 0000000000000000000000000000000000000000..dc8859cc2bbdec6a9edeefb7cd23d1bb08067da4 GIT binary patch literal 31019 zcmeIbe|%F_x;MIZnuavQ5=w?su>+e>L#fzqL#NY;l_on$n}!lgQnACJ>=c?5ENvzf z#2l_ul*6g$D;;DUUXQQC>-F{ZayU*!J{%5*%T(krh>WK?4CCQ)5U~^n8SHQnYc1LL z`>dU`MUQje`?=@6f85V4>|blI^{i*D_3URozt&1|aYOA79QDNlTOC>1#{O^o2`q%% zv5w`-R<3AfGjV^{V~qW`B?Myq`{H_bEH2oLx{b`mSkxlBY%T1dc@8_qbj`YWR=^cy z%;-F(7${87s=sZDLufx=x5N zp$_Gz7L_uKc@vwVs!b;C9o{%fv;4rrTq3U4bp^Xo!zQ~i#)Rh^x4MVfPS3C!O)y7( z%<%g+@|kkOAG-guKQaIMNjU15znvKiSLeJI+@`^hV{~OqT%9u*?7sgqW(xiTJ@fqS z%tB>?+wT8tQhwnwK$ijCs6qcZhhFj|uy`ieUH1_)M;Lp)cv;;?VnuN6gNgRGn7BOB zx_oVGq@z6{u5Mq^+zP6s}8uW zZqZ#V#{;bkTnjoD99fX6)7OaGUMgy_B*iy!-Dw#q4@8W8qC)mAotL!Q^#^zTQF*7i4 z40bnced9=zC|Ta`edEaT{J0?c0-jj@)FL)f=V2CBgkxfGElTeVb}NTK$e76F@1t5MzNR` z+Z;wFy6q+EP+^-o5_~wgwx+?uY8t%0#j-ohNquSi+KwiocwV!bo~)X(&sHY`+MQHfR`!6C?wB4&^* zWvtaC>H6GdZ1s@TS;qFb+RT!!8_#=O?Kh-O$Ji~0T$DyF z7=yNYF5Vd=A?*6rl9o(K#UR(qF6F%p1bkD>37je{2fS@YDVtzauz+{-Vu=o9a+R72{o9p}Sq`^}GG*;LnZ+?ud>oeR}F$YU<+!tC=vjXdWW+{ahf!RaGZgGz%yDc4 zj&mo~45#|yb3Iqp5%K=ubLJvetg10RY7%iQi_f7q!RM%E9QVo=MMkUi-)wE+{YW>J z>VrR{Rw_(wDqLWh5;KLK4zQ@nG6jAAG`{M?mMO}W!V>kmEn76$+R)-QbUgi+^zI+>{_WruuHHpqhEWUc2bQTKtnO!!0X zHo0Tcc~`TpV^B=0C;Qxey_Va1b#GYsxrj|qUn|qsCF$#W%Vgv#V$TEnr1~PkuLpFh zfkRJz9l8d&n)T{70ye*L=;=GaPv4=2^d0I*-=UVV7I651ufqoxQ#0684X7uLJ+2&k zTsii*a_n&h+{yfpI;o4XtGlk^=IT|P=l$zHs{g3|&p0zLRf1}~{}HutP|WM~GB4Y; zi=K9&6}wpU#MS5t)@Ac{*_d~icUKg7=&cP|ZLAAtv=`|}@)9O=MGDh!!vnLSY!}Mz z+6CAryukVdQux^h$h)rEZ0u^+3EW4!sN=5k{8Tya@%97(A;>s)q24ak3-G7_cSr#= zygFgy@KI_PJFyG@0IjPliu+x-2Yl2>=Pso0LMwLhoL7PWRbXfXZpeqSD1@B!lHkyp zZh`GCDvMTJC76^mis}Iw5U4EW!AZMEzu^{nD8b8Hbd^PM8wGqX+KX=Ro&YrJF8+75 zOY6HR;noH4Xf+xTWj3CItS6#KARJh9SJZZb^6a860el-;unV0Gv^Zpd;;rKiK)+GX z(ESNC9`J39w*^B>{eP8eA=I@ql|^A1Q$mlL)P+W(Pon5~8hxtq1bQAl3?%XAy^4YV zkD_qi-Tz_GzKN9$b=?p`k{L*4>e@h|HOLn?VyHl;`9Hf{C}edMn;b8-FswY z7R#@_4Q)`BYj`Nb)TFI~%Wv_<40dG5? z4!zzXI!50Fyln)vLcKB$s#w9Hmg|7W)UfA~xoK$n2pc*TB50Sxo`9#_>Kh(9%Ax6l z+d^JSBWU`HTW}nOrr|iWopAgb)M;OXYWlx|IzyZfbr5=zAbazRSk?}YTwP$1ebXRe z`?!o)HK8i2D!a;1>il8}u=9{4wdjO;8TbvUm&RHWIU6dlQg!GN?u400E9p`NI2F_XP=QvML zzmQ$-tLpU#OYJ9F7n6lhrRVbO9CnZ-UPFVXiSHws+9g8gvO(vvcg}V*y&_4v#H8~r zee!u%!nw^Q38+!mCoiV@4azf13FBddhvlFZDaeQ$WS6Bx{k*}&DL2#hA!rBUT;qH} zk_&5{LRlpn-0pJd)=e5%dD303JMTH=3T%$)>U|Zu0Z>)HC**1RYTgsuZiTiIkczNQPM7hw{rk5Ju8e!ALI0mK6LU^ff6qc*XUutEOyv8gjVUt^%kKd|Y%{D%pl@oB{xXUah1(;WuU zl}Jj42pjH^-63z|U)5Key-eT!D!zjC8t(z1|5yH~k66Zbq+)|cE2?Vrx-3gVEH~U0lEbc; zfuKaMOS+?MlB^aD8X(shH1JUH_8bOZZVm9ZCpKWa7n5MR*(kw zXg#Ct%(M76Qd?mC_yTbB%gx9yMvaO-)TNy7fSo0JBU4jpR;Eu<)$jMl@0C5!r>%}; z${BXSmS!{S(6eT1ew6S_rV14+>|Ev^_iAIPYn=e=OFz0sIx=pc`DY@q5kw3&zT#Nc`h%{b#2d6 zv2yh65887LvU=2gi8<-1?V6MocEJXuD`O}9k}MfRF61;m_m=xlT{_8F#+0ccSveY( zl|!%~-v*n-rm~#v$(xF#8;32dhYsh>?bOeO$(yqKnvty&%A7YhZ+C}e#|CB$xMTHU zJ`QFFA89!+KUQ3pytzIs%dUV7+yt~}I{)UJ?dEmD(%QJ-Fzu;rFUZS}o|YiPD0#9c zliGG!(aRp?fPIE$W71@#0ufl`YFLaMBrMho&%IOb97#Rz4tan><1IJ@FiPbP=g5r^ zXdpT1a?1y<^X{_b$fmFdIC)|veB8v47hkBe-MC%|)dC;bL!xJ4*Rx>E0>H{BdzAqk zd+I*Yk6PL=g9De5CtyW6q}3S${f!i*>5sA3%A6xDk^rjC2k*&E2*GU*Hm{fA4{w4! za?=%}J^hP&T}{z)p+fKts|CSr^mUf&E1V-mT3+SKytkjR@-!dEY)DZV)Dp7$0(P((>*aDBA`bK{W=Cd%ee<}J)DnECS6>lq3q zYi0$LeaOFEqg1=|EB~oZ(SsD?3$tPc7zusffv+4rT`|+XuBe6in5dX=b}55NopMgf zuDi-AG?;_~{e5PrX}H_lyiUAZymL*-oom>gD@yNN!94A&<11TNw#9aWzr%|7V(COk zBpQeRK#r9<|JaQg5uO4{6I+Bj|6>G=pAE3s?S|a+VyP+ET{C>WM+_u{xDb3UlefyL zJ|Q{P&Jd&lL3-qmlV6mA3LvIW8GxR)f0;B#@EdsuZw*ykOT z2U3Pkj>$2|PCGT+CuGWfsh@o_-&iW_>Dyt!+c7o*Gb)`f$vIp=T)Z&(Bo(d^UG8P3wwY5E+~fyn`uPEtKou%7Qra0u4CPtZ%XU@VGiYb17^2@3asBk#Yn=pFTn z@^XjMF+qlA_37E4zYC~^-`0Z5H^#RhwMWAu)y3_wXJ|Cjo)BFL|x4Qwo1Nw2>l3$$i$9FJ{s&i<%|HtsWtjgIP?EX2YTcnvZ z7}{CpspKgEC2=W{xMpcqIUs-0|A9;61Cr3_>H*y4Ax^)}FV;i4+@R5}V0HMl?w=BhhLcen!PyV^M9n^9#rG$uH*euP`m)moWZh*5rM= z3tlNtG$c*vTL3>&zT~_y)V)CK2g>KDDa|Q0bk}H{tM9;#XETyGf4cy0&4lNT!+4j- zyaWAhDtF#^ectd52%?H?A2nMG1K_L=XPxrdi+g{ zZKpnij6Sn8r{=19wsfMV)z}uuC29)oH0Rwe%j59w7{z+kD9#GUcnQb1fnytlY<5(h z0~s|p+zFXTqZ67hxWBTT)o+bC(>05H9vRia6dUj~XkW_IJpYq&o??M~^?K+jeBt@) zz&%n!QWn=(PiS9mvZXn)qB*e?GgYFAW~Ougixx>Vnjd4OG}i5U$O`MIHky@6X?}SR zbJ2O4N6MXQumA0uFOki1;c0lVe+Av+AE?yqt_u2U%(CYHgp{H_FA4tM3tfe4jLa5t zQ<=V*PZ^o{r}Z8`i<#8QaRUH!C;d~-Ce5=mkUL;PUlTW*k|@(ri=g0Z=`JM zM~%*GaU<&hErQqA$nJ94_ow|#thVIC*E=mX1izydepJRb5(Vu44wO!zne%TL}(S5#LvBOovSjrx3acfcFfLqiTp`0l$sX+GVi z4nvA5(!NIRtehrz(~IHhp73!%y3JC|vYf6>uGlM8I%Q{Qi?St7vT&Un7)IE~+hBh| z55V8azXFX$rlVWSoj0F_c5Z0btuvHmT?m}?Jok>Yfmu#^60_p4BV9>WuzABbS5cp7 zyw^RP>W#3EUUN882b|E^__yf#9V}stg<&Z`uZe-`nBhP&wIfz7E^+AN*%5ZxyVM)< zEqYfSK)EMiDaijIncA=?nM$^LJFE`kik{wlV(yqR3OiqU88Z3$@%Gt#scZu{O~{}8>?o)O(rE<)=8($HUX`3TQ+!N^ zN4DEBqLTBo8+~4_ueIJ4L!1M1nYNrg@0C#Z7iYwf!&92$U*n<@d%8W^9MgB;vn83? zjq^ipd!Egfv3r>l9;T(NlFdhKlAXC&<$Y}aeQf4^OcYB?MK+6xY-L-A$XY2Bhb?c3 zBt*8hZOzJ9Tk{H$t!rP2Gbn$N&@g$?j3R8tC?p)zJmb)zXxlNWISjsH-SR59~QsOFg6}zUoBv*;+ zKGz)AT=sV?kNtddj(e&*2X&2u=?=LY7ljrzMnaLs@i;76w5UN4W(s1X=n)r-%;K1w zJ2O{Ygt}x)y=9@L%Ti~#kLt4cEe~2kq9m4x_gNY(4UlBU{%IT+oYFUZaU{UGee7|P z0K}D(%@SLu>%fQj zG1*9Ax0HDwAnGh_MV-SQV*iU)Abl=kKVpA*OUfLP%@P0d)?Bw_NI$HMibX7n;HM(? zXv@mhW?Y+F*EEaT`Bs?!Uin~qhq!WeytR3Cb6W?9^Rea*n&ZJg3&aXm4(o5~)c(d8 zn^;e0(+z&!%g^ihc?q3!hWNRkpO5kLW`6eavz^XH4#$|__fzRS;V3^R`FSp#4LpzG zaenWReRR!Uk`(wglzuj+pY@cge+jk=Xl+@$%w7Spcv)SzPQcZO^r9Hk9mVxWxE{jw zFLB+6tJ-dN>UF-YADMj&Fm!QTe~4=fu1j!LaBaY~(d-i@;wn4!$8pc3b~DaDXfqIu zHV4%&oaN_}{Cvo%H~3PY2Ym2Nynvj>HpaH$niWgnoE>YDoS!asu&CbQ{4}6x7|>eh zl$O@g^8?Gdp>Z@VpK|J!+2dG7t5CKFe!y7PrWiP* z?Ygp=^f>W2WIW!t>UzSLo%RiXB}tZ;rJ<|Gi|1!(?vX6fLCpJ1Z9pq;YiDX5Z!J^3 zkW}>mggaa4w8Fah??`gQRLqOX;=<`_nM_6Rxe2oR?u)()g^H z{KK`$n~dOZsq?TJPg6dGJbDaywYi>T+BCmLNr`I`9%vFK(m^i6`tpap-Cg+7xYe5^ zO0-dquu0EMWigiOhSZNXq`Cm_ajN@Im?i%3-nhEgO@5Ns9i_K3ULz|)Y6);T4ypEP zgneg65vVHVN6Gp8o2Hn+QGEWia}*!U?tt6@d-f3ic^?kU%$ zd)6vtY4hG!yEO=3?Nd##C@E_ijoR=W~mIKdACxhF1Jh9wae0C?kfSO<# z8(e~SJrQ>4XgMtWG&>F+Ldr{-IZ;ers-Aq1Y|}{X8tcVNl9mc6(^2nYrCX~v#zqpi z&?g&7=@93L^c%7-oyUk0g$f(#kFd``k(UlRoR{WGuosrYQh3Q0=2r9&tmqey!>aR_ zMivYDh6n8xSq)wZzE{b45faq{qttZq72pC}djdFK?C4){?2 zx_SSkwR@yBp~4amxqqLlRo~!IUM9#+y>Ixl!;+rT0q4bT@3A?Mv4%H(kST z)XPri#Z{ogCZZTWGyojKh&?u@V@cUpLlFc+kt~QdFD2^-s0UA=W87DjP;M99Rirav+qprdbeA2|hA# z8eS7Ka*bL~0U_yN8NH1A9oSdntg!+5vCFGL|2z zw+~;n)9kUGN~{|0owG=Cgo^p1Sbxp5%q56>OMkTwCkc{^2yNLew>X3@h^A zURZ}7Vqf-!9wR&z_T|w`?XBll%P|8^&dpZRlL6nd2dapzUqHv46Afs8F)|iXJ(@>O8}*lpdj~pj#d9y zZ}sP=ap|MJ>RT%&kaZo@_sPjLj3S~wt*0GKt6u`o z?x%QtHuP$yr-oiE6UN3@IW9Rr>5rxDg!m@?c<$4BZz%E2-uon)u5Eg{2InU`p_N?X zb;y}M9I8n7;b|#L2O5d7FAC=kf3lwXfqL_kHsDBh-rHa%mL44zRi9k6M2|j+Ra5t+)AxKk22mpKn9@Ep7jJL~A?J=R-r>Og(&a zSEh%-+tNMz`Ob0uacVRbcFOb9QLBDji}s?n5bDxN&W|tO(w-Ma%T<>FKK}Luof08O#)R!>-M1H$cB1!`Je0E828a>o@4> zkSn5WMWXqU#z5wU6q;HyWbyy#AG0JdI$;&!!8t54e$Lz7Pn>_sGm5nI51O3Ay#2 zdps=f9{5(+G`WT4t}hw3udh2TE+KmE4G%50mF5 z?G50*jNd=Prs1%rt(oKekF28H1$b83wP(R<37Ye??ghYSn!~;A-Fs@8l^}Q5R=8jd zt0$=bcn=_J9uk5EyVxi+zK#L;OY=1Om1b+iFHI{eW~Roidm;HabUYT$KQ#1VgeUd3^f`#{-BZqvIN2?z^ycjknDVyY$_os?Abidd|YXma!Xjx3( zX>=KtDdH4qmStAH$LKM4>Yp?`X>jFMjm#LD&^hB=)!?K1mlq6H4n02f_~88I(;q!Z zZzc_9^)fc8SCX_ce~mIv8a%l*&qxK+D<((?<^emT_cdL0C!RU7ar2XgPQ3S+$G_Kl zlU9sWxGIJDy5crwc9t*;_3e(@lW*RtN4{y=N~LD>4OcSMgVxn7@gBa^=R(wJwCMw2Z1Gb+Ik zF2PdTUrsjD^Y?9F-&KcjHmJk057tsa=VFs85b=Vve02z`*YI`Y7%JOfVb8r&2Ctj! zmR(qd0XbfsTZwNHoW}(3Wo5ewWh&KSCq`5<$8<{;&M#5V>uQ(<`g0@mFcA@R=inb1 z#FsqOw-E7egMfF=0T>tjfCwq(!=rdN*zc+$n|+&l6~~n_VBqjk&5pa6u5Y1McdCc# zmCWE+2T0y!JIk{Xl~;Mt(}sw=Kn+r^{PY+!%|i~v=?J0N!)CY87^{cWdKH>?PS z6q%5^4kyB znWkJn=xN`*)Tg`#nfj%Ne9BH(LxClHi{)BNBJ91*;B{@Viz0nA4U)N9U*!DF%Sbto zKA!*!%u)yQzxC-;hK&q=cOx!R%iXu|N3M0*Hm~UJun>$3e$BT62+*lMY=8vt3Loi% z^wpY7;*Wg624Co*`+nHGh91J6heYwdAdD5k#i^4N(NSd7EMTQM_FTi0s+u~`qLS5D#Yah+f2D^iteJim$g}qK9mqtt;1bAiSYI5^KhHPxhpKqA)}t zoLg{Jy+U3F@-6;mGva(J(91u0nCrA&kF%0>f?Mch-~4Pt4eP{cPbs|(HSY>;r%|*?Sr2l3qFUL4;q+S zgg$LV1euF$Ot9&=ghjDdoEtzrL_S_pZ`8UwzQ+Jk#Qdd6aP_(IPF z7*?`bl^X?f8G8NW+V8d^rua`!pnWl2m0&5D&Kwgyu7%gf`T@K?jv4TSFtwQaV+Bj4 zq#Q-A$iX;mDEEXG;2Ndbu+)5EOX>FzR0xk9`twS#I}d(a16pMRZ-dVXTvXX&$wU6B z&%L7@;3Lexvh<7rdBdIq9|Y#U2>YkO3gRNXm4%+)^_Jg-(bT*)_Wfblqn9A=9kX%Y z_NBg%7y7{!CAVzCXzJ?<=7h|QNbvLWtpd|w?cVLwt35hc@r3AQ*{xXebpDMN_?{`< z-?_~NOUjx7IM7oPg`8k`vZ zYolhVv?IQwIAC`Z4e&TF@Krx_bD^8oeHQx3<0g!v98| zb;W6I=p|uu-hU2r{L56eC(G`gR6)U}L5n@aGne z<{&&?Q_j#cA_I6ULGPGPl#`-syg$Yh>4>zp$0#Ung$P$fVrBCh=5KC|Gm}`?9$A6F zIB~g_XQv>Vh#$4koFc!jt`eOCh(pvpQSKagyvPNT`76ds&QYC^5`H4KjOWa9zp!cb?}p9IlHjnl=w2^I*gxMu zi8jaGOux<5?=HKWLHh1@+3N6iU11GujwR~4{jOMb1+!B-)-xx`02iL(-d_cgQSnA5 zcI2}Nd;3{v6X;pJUVMb~J+kTQ^@NuU?DX?#Tz-1YRvrAQ1C}ne12Yv_v~TdailW|V z{$gx|&tQmlF}o(y^C?`(N6>3_&7|i&xYF~>n3v9>>_<%%KRpJ^{~+u^h__*zaIeMN ztjC=eZPUghS6X=FN)wM#X%IbyX=SMWbEBC$O9Qe8ca1M{D1NloY49 z^$+#JcH0%~F7j)!VU1hktOsKf3ltkQ%1l_O9iHKvc9KJ{cWUKGZ-0CDnBH#liFH!t z#Qm_2Zz^Y+%s^v_n(S$xzc<5q5uMDS9~%6<7rVrI&md+wW0?@2bgqdZ)*NxcMbcz= zHVWGH+hjX5Bg%*9DR&fx`}Tq7j)^&n`S~s}OEKX2lyY^TON)IbDxyEBE)kT8mZhM~ zuN$gm`EfjNs9r)>e2s`9nISq!|J4)cz1US)|GVBw;Pj&VaYRRB-rghSk#~iiXqPM4 z#X9hI-9^N7trKj?!+YOH4>8tZ#4M$UB$OZg2YNPmnJ9wiQ))jnxOYw=0zq2p3)j?d z30Fgw-!0{}@1p*Lq^QG}y@6So@DNrn;rVvxm*A<&k~p(u`(3gtFMEl=I`i3Ivrge| zm$s6f%2D~!BIu;B)Qc+(@bRLbP0EfmT!F)#g0({9pb`zJ5+vWzRZZ|8W2c9)QFy<% z+){yY9%yCWPFCOLu#^d_9f)l&+~;mB!PWGHSK3JF%H_kjlY~VSOMjKQJF${N61=W` zuGJqZ`f9Io+&-gdG;&^cWk#K}K64wpjhSP5Xd+gvZn6Gi7ef1VMqTuBJiWUEA023z zPF7Sa)(7e_3a9rFO){ZH^1*8^VI5MJBO5m4zd$ed7i1d@tW@J+3x@xQxOc4wwcZnh zorakVyROs(e=22@=AVM^oV@kH?U0#&R)Hs24Df`0v<6%czUAL|46-xRq2594bm8S3 z=fk*wJK`zt#lJLrIoCOYE2SL3n?@wS2=tF;P?V& zNtN=9yyRf06JHl#bnS~9*>a2z#yxHFTIp?VF-J^?_ox9B98h01DR>>DHB?Xy z(3SFF8EgU67REIz*xF!Q;*rsL4p5A|lIdnGK_5N^`FT)YM6p+PSRck)%rdoNHWgwO zm@BV=?*Ftr-|PWBn{jT47KLC9RBT~77m(Na(_Zk!JjW_n(Lz(6>{1m2PaXLNY(z4f zWxz4u+z^EY=*@8}YDgL?G8RK4D3|A(U_~+(!IBhcW7eplT!5TApU!2TvJ!?hHV#;r zNE)$0bH2=@?RZQb_iU3^|EU&JYA(GkGv|pu$S=?!jzEsa``w5tpUCg7an0lmQ8dF} zs5#ymS>7ymG_UVq)hpXpXm<^G6g%2Qh{Y?M?7^0H#Hvulrr6%r`WW*>)->O}rWqkp z9V^#0vv6}HvAjjZjw;CC3P~^n^wE_aEl!$mQU|HMm8=oLPN{?c`Gnk-I#ixiJ7Hr& zkN&!GzQJ3Qum!54y2Lb4CH`=4(C$1}Q@tHxd_Aq?INIhcN%i*oDoRp^t8SA@Qb%B8 zV%%bs3rP@iRo13>C&_|ksG-bE_Cv(6&U0T)^@Hzq)qBC?asitOV)=wH`q$wt%f=d& ziLgT6fqq)D)Ef@)G#yU^fBm$YQkK>tpPr}XAA(_YgbLT+{3ce;qhWpp`4=(fx`I)u7mS*$RGM6@)AN`ZCXDc?7-$MuS8mx) zGjD&W>ky00#co4`h(Iubg3jUVdP$RVL1S|f3Gx=cP6esQp?Nc*cdijDR;0WlHN|7b zwYm?D*1UJL-d$YseuYckFG+}D66RZ|5B|#YCC-~;rXI4S?6BM(y@4@u0-`z&BBX;+ zn3$bMp)z)u!=?F|N6)i8p@3xQP9Ak+eBc`OaJqSnMhY|op3;{*xy@;FY^tMArz zGOXe3JMd3D{vqQBQ=ZSWjBDrfqpf^qw2e<_EmSv93!_XGLA&u=`i`aE%ge`ZP}ANJ zkVizGdY~c#)-Q+_U@>-~U(cWouVN)7OVtri!qu3z(v5OTE;qyOI-{}}HUaF~bP77l z=?wzy{?x#CR{BM6$t0{EJsGk@*x^mEke`8W*$;j44C#{)Kh~3OpN+R~y$ajrnSKvh zff~H9jGwMDK&FAzT*YU=(rj%c8n^a&XcZW22@_=c>aw6`U=H~5kX#Kt=`_5(ua;9} zer{|BVZ+}Qajrshm@)bU@bNxC_>`Bl0b`fK*L#;v;PVIg1Kt$S8}dNGCfSpbbmYnK z3s|%#iZ8TOz!DO`n$;U2i&zUSr_Sz2J6=NThIs2L##+~VO!Sa90D9RF=>h-yd*2T+ z!_ST*rWvXAE|R%EpT=dGX@Kz}pzeHtww5?X5u`i@)1^$sn?M~|hB#zfNYlNuEr>ru+qsqeJ>sxPY025o zQ!-DWUjwKz+cK*c^a8^r>^i z7Juh7nOHR$VZ`P{qCGLw1hdhDkwhCAXPjh1@=>yO>uwX*wl%MhH!r8K(&lxr>4+_n zHDdeno0`RV`m22n)0i)t8fI@3~ zyg6YqdD5_}7?4Dqc5|XF)1+^rSYrAg1&loa)9X5UHxRAdEZ}?Mm9VLrjP6gSwx>NS zyEC4Z`mIt4b{}*>PSiJ*r1@5-bg$76{0h>viIqTyuVV@y;bdxK#s{-L2Xa1Wi?LR3 zI+l&^X^1*jkLEEdr_<%4%F*;)Z1n9!h06sfF{HdkZ@KNTgc(aqST6SZfTRc-4PD%f${T}NAwG=R0S5OXPmmHFPcFVNYVrax&{}dJhWUj<1+Y z4)lyaxO!POGq4HF$p7VF&rL2Tkmrjqp&b{s=uSIUoHp>)#Gy`%iJ+!_(OY=G{1=of z%-8jm>fytN6)`in=$@n*$9JtlNVlnz?5{Q^yZo-kt+I@{P2)%?BlHKm%diioq$A&% z=B4+rkT1;qoWl?V@a>kI0*Z)$U%`^lfj-Vbf_b9NoG{@2bZlM1q$F@R6usfOq^g0L z(UH(o$U7Nn{+QfWh^q(tRticT!2`E>sWb;LkB|(P&_hS;R~*O_igNob-gl0BpQW5l zmuefAnynlgv-gk3(qe&5$l&?mYl&eofs`b+Sm4!AjM#Zl1a4iKnE>BJWd)+2QmbmP zN*^&PT+eJkyy-V}w4yORa6M^hKGM>*e2bQ5E7oWy9GzYWeU0hdpEBK@erRl4YCdHm zw6*~`B$}0y1xTlvEd|d>svEX5{dq+PjH4fx9qiRf?)Q&<5B61*UC8vxVXm`RXuH>h zd9Xa0&tr+mYE~0j-OL{7z{2g0$JqVgGYR(fzj-X!{3sPz1y;!FwX4{Mg3i&WXnQM` z*x^}YVHAp=5F_HcNGn!~XfJt*(E?<-cd{S0uT5kii(q$c?T?Df6V1dVOT-2+y>zW& zQ=|$?Q3H#q9f?N`$vo2p}Xs9g9{#-BR;wkS{FeAM+U#76)Uv9 z;Ia0#B`nhlZ*w%Vww13GID)lfm9|24= zW&c2>Z$*r}y z1M?=3;QBI+mbjw5ZFUFW4R@{>ff}9$i7B^)OP=uO=2sRchx@62YW~RPlupDrUdhOD z>0Zm@&m_qZ4_VE`%rkmRll*9;A#pTrZE(>#{m@3;M$RwavSs)sUlHpHy}@nu+71M?{)fZ+wEVlseE{X_wbhZl zMcvfz&``=jrTN+#Ku&2y30%&C)RiX7saI&^okz3_vqfY zuuWp8DktKQ#N^N+;?vK&$+nL^8Z^ov?I}c-F@^gfOAQzg#0qA1 zP+omj(qp!}Wi?*`E5;hl2qOJa!&1b|RkY?3eDYxIU&)-9z0|aRkqzpp%s_Kw(d<`;0d1u|x3Q@5Q{~q}a1aDBXyn4FS|(>!45ei zpm@|;n#Jc(Xb7+j36M;_0S{#nH>5gIR$CFBC;#x)lJT)}&5!OB7@W?Kb9cftMso>F zW*uwe+ILNU0g@@B!OR}P>FZ$ndOdv|N?%8A@f-+77R!Y$ct!JHLBq4iud5@<66t7&w~S6r>sDgA<2E{Vh`h+O@@U9Jy4{q-kzdX)STg~ubbL;Z<)m(|d#@u49*C)<| z#TTCisVT%Bcaj6yB#!R5lKDb-`plU##f83w_lJHc;+AAp9vxTgr@Bej)NIG1G2`9C z$~JC)$9(b=9G}s83j;V!W_1NPnNw|v8H-)oIzULVS2S3Vu5XL~k!*{gHCW@peg6oq zY7SUq2E?3Lqr;RBFqd*G?3rNqTw0^fCcFpD{4x&Cxxv>uiG$kHk|yys1DC=`&L>Ip zKJ0F;UV^6B!SIJGk02-5nX+_GSWs@lz=*vC5ou_+50(q97OY9RgqAm=U3~7_RuLkGv4`f3H)@+ndkxtr3t@iYdnVJlX1O{5hq!EVTF`ZU#X%|_FJ z$DhG}b>nSFh>J1-j?t14g?V(%Gpfm=#hEDZ@xlsG9$@*$@!)iqlGysjm2*%N8?t9^Ud{GE$&`1 zs*%H{TTdkrEe$EA+(nW_4i^u3-#Gti3*caFDPjt^{e5hO>3sIjBTNd{P`>#G{%HmB z6_Os{|Mk}1P)&sG>l|CRMV3%_`oE>OBJ5Y(y9pYisO>&&7Dq%K^5<*=TyP}bDg&j! zGQv~%XkonJo1UiGH!$9-C@)_v56$c4Uady-{50S25#kT$lC09X=Lv#FUkNy<^OduJ zH;6fR9Cj#S(zMnn(_brh?vWi?vX{JV%c~!t{U6Wcn@zrPPAowTfwpH_Ne7~T$^;9T z6zpqru;z0wu2|cte*rw6?{MZ!?{L=0q9@aF1=X072*k7DpE5c@B#6#Sq?7G=6~ zR04DXjW-jIkJRJo)LUZwb$c@~_J2Lb|8;`QQxV<9scbB|pXo|q3*?J5!Cm%#%q3g{om&`nDh0e&R=$do_jT3NBmM~%*14T`Fo1V_#n-pDJJ9P{IUKd zTrxbF?e7UuEEcCk1$n*;l(mwBIoMs%bR6 zHB9M&a_8TL=zW7n+j9dWvu*Be3L8Qs32fyDxt2+w@RznsNt)DvD6kc?-lg=vAE95R zSq{Gpwb4Guq*Tl?t=fSV!ot5bVN+4r-QbqolC&S5>)={gj9$fc4X!Wk>)Fqu=MfWa z0^j^u8=_nJoW$q2GB+%86ZyRGinf-T`pMzNK2fw=Yir*YE~Q|OhW-Cx&){q9&ZoL= z;6C)dgTXJmhH>Ywxwe1!&ZoOZemAUEq8IbcOIYKBC-^Td=+GaA?_vKDHD&wp7Dfhyii{#*4J;v zE`WD~dlW)?4?%k4^69@XBMLnB5cGYEjHpquVLf^k)~K@|+Kt$`iLreo{hqPLjnMYI zT8su#Igc+bW_tL6KIA)NU`7TGutFlT#t0SoM&bTnxZMND7EH>PTPT%;j2Zbct(egx@v6yA$x(p+ZR z16>wNxGOpg{;LBf+*?91R4Ley5tsTRjVAqC2mSg+;&H?q<)g*HNAPvK1A(T8t7ivClne{&b;UtGbr?n9q?=77dx;ANZyBZ7p@htejND^=Jg_xcn+9KFgU^eb`cTb6e&f|H z4Q{!PKi7oZ^?qb{ur}!B3BE-S@T>p+g+5r8f1*~YGt^1y1T{+)RHm|@uqrl#O=1&R z7R?WxtQRN^vLQBtcr0Y-RD0EP>YzHLj$mau?CoXvO)Ez`%X5@6Yk4V~y0^C7AjxGp z4y+&e)L)2RbYElaliKdLB;9~3F}-&q^nB*X*(QhFI+;xZ*O=5+?QpyQv?Kj%MzHrt zM&@_NC-pvY?tg<6r;mvw%f+UFbLZj?u~CBI&29MHS@p)Zab-hK()k+COT3A4gEt|6 zy_TPy!fvTHhfK9V2Q*4~<%QDdmG;QL5|HJVjCHIWjs!V(VO71 z>{-Am)Zl25%jI}e?Kv7Mdz&EH0u5W_MYlj&qQNQTwkQYW&1(1CA;tR*IC-1nM#iBS z35w&Os*b|B3XJl;4(G`bUn>aOn^A$DFTw~Em$$RI7458~tR2yJ6SsRL9ex#P#K}Hc zIA2#?(=n;Pz0ADb%~Q`+uutkLb=B2KZF6|ag->hCvOWoH!`KbTAIPBVLO0e=l;vQQ zCO8n)(;w;3?+t)66?F*wDwdhhPtSDd_69H_FYfoXy2`W9d&>0NJ#SjdC+@37-pv7d zwFyxmBJHBH-G}u|=JU6&(1p4}wI{vGho9g++!d}>uDLI%=M`9U&b!L8x4Yi7?5jg* zKT4ZXX1Z2pyBClsY70Bwp7bfFsZ7|TT-Tr|=YWAXgTYjxI_uXNEZCpL;^ensVG*j? zTO1R12oNm5#FoK?-ra)Dsjp#k2H4EcVDqGg$+|y_$LVjw<4MB7`Dgp$%-3o^hlpgB zn$FLd*+y&`U-3xk|KezTjpIGo2n?HTB+|G(EbC>{~r732H){%=n3Y+ka z8LFVCvtqeg_Q~G~{U=NQw9e=d=kwtCLMN=NW3~bABP2f;>H39!5IO9bPvkdl)z;Nw z#@tkz3z_Icnp?EUWl&7F6H$N)_FOSfU(cNHQK$Qn?@Eh+p7^WJQ%uZ0Cu_xPj8|0pEsLmRlp>idk%B^#Up*pId(o@oi$ zM;}bD8RKs$=O)g(J<;McZk?#l73_9$TScbD_xPB(e(U(M;5-F1HwrWh15cV+NivRO zH4eDQ^RqWFVy^IqX7GnxijhFfZM~9eo^T*B@G|1th(S@;_QX~xXLY#K^o6;ro(!LOAEXn9mU)haES$ak7UtwqAIM-6<3l5 zvXood`SYlzLcLDym$H^_&2TO31*I$Wzl}X~-G8#c#y{Z3{KwSP`){F!NlD8KE~P@6 zR+jBQY_lMalJ+O#6H9Tvp zN)g@|D=mfp88a1)g(jPmM9zP)@y}zC4=kMUe|`%d>=r!e=^J<)(eS{Rw?kY10xC4h zd7&+qd@H^vTLAlh-jSF2wsNSa1oTuGd$H0=IpEnsc+NmX?|iIDF07U2FjEE7d6|p; z&2ur6>{ANJCTh8(ifNMOQqc11+>qyxr)eOB)kX(>P1l)M{nb0Gu!=Ps5(W4HFgoV> zjOpabz#xAN1C46K@Gqlo{Pttq5Uk}rC1GRMe0w|Aio;(~E?ik)!aNJA5DF1BTWsR1 zc`Y3(*&Wy!{)Dyr%*`y{hjySaSnKi(z*ZZvp1)~>CXPR1ZQZr%dg}&Un{X||b=o7=M>ZQax9rYhEzvd8T9oM77G3mg ztRF{x^n7$UdNw*}&5a(l7DRVjr$@I>ITl@qWAT*UXx<%rqHIdh3$JyUuko9%}pcKgAI zc*mZ|v>B}t>y#6b+$qN*#)qdz^pn>q2d%lv%hqYiv-pj=u7~rL4y#3J#kC3PL0k)Q zorW|ct~%?~WkXi$vTN47Wml}`Wdl-V9K!u8xCE# zCww`)J$&xr{IC^=Ie2W5C3vjk~MeX zj@lRMOtmj8P-_1+P+9v@z>z!bTlM1`o&nD)&nf#3`G$SFylb9L4&m_5)47jLIp!{$ zr+4kXkGWo*a>DgYm8&XwZ{ptVKX}1;2FGC>JwN{N2Zw(g|3N`{uwuCN!1vbA)0Gw4 z@*St_2OWL(Lyn`?TnGBvu^Z3NBK-+mlSoe>Z3T{M9K|?tt-1GH$8i?NAsjobdG~bS zSc0Px$8;RbnkV(+IE>>3Yp%2z#|GTD;98HP9ETl8KGF=<+|m?|UL4!3d8No(iaJZ{ za4+Miz=3`$8OCuH#~B>xtCH>0DYv;ShY3rFSb$+IhPl+8BJmT=6qADL~`chA<_FV1H6e*1|1qJ0S0 z>$nc$dc}Uqe$IZb+&1?4{iCj55&E;Bl_-{@foe+_8;ep&)};6aqf)awt*SFGg@bCv5GUiR&n~v zR_k=LHSfD;thwJkWu5xn*KvKxYW?o>xbMJy6i2}wdkT(Qa|;enIb86pby`8xnqT0w z<`v)@DzG9w7teaD<&NX62kzM3dSKcIhAq=}TW!-`#kCq&SN?(9>#XMddK}d_95_r? z^Ir_&xP;^2W2-*`qR4Yy2H9|-Tqbc Pb(JlP+39~Xz4CtoS_iLW literal 0 HcmV?d00001 diff --git a/ti68k/ide/dialogs.h b/ti68k/ide/dialogs.h new file mode 100644 index 0000000..d90618a --- /dev/null +++ b/ti68k/ide/dialogs.h @@ -0,0 +1,332 @@ +#if 0 +void SearchDlg(int replace,int key) { + int r; + if ((r=DialogProcess(key))) + switch (r) { + case DLG_OK: + ResetSearch(); + if (!DoSearch(replace)) + return 0; + break; + } + return 1; +} +#endif + +#include "aXplore.h" + +void boxProcess(EDIT_LINE *e,int key) { + if (key==KEY_BACKSPACE) delEditLine(e,1); + else if (key>=14 && key<=255) { if (insEditLine(e,1)) getEditLinePos(e)[-1]=(char)key; } + else if (key==KEY_LEFT) ScrollUp(&e->scr); + else if (key==KEY_RIGHT) ScrollDn(&e->scr); +} +int checkProcess(int v,int a,int key) { + if (key==KEY_LEFT || key==KEY_RIGHT) + return v^a; + return v; +} + +/* Search dialog box : +Text to find [...] +Replace with [...] +[*] Whole word only +[*] Case-sensitive matching/Match case +[*] Search all files +[*] Create search results form +[*] Regular expression +*/ +#define SDLG_BUF_SIZE 128 +#define SDLG_LEFT_MARGIN 14 +#define SDLG_NUM_OPTS 3 +void boxDisp(EDIT_LINE *e, + char *s,int x,int y,int sel,int blink,char *buf,char *inittext,int x0,int x1,int init) { + if (init) { + newEditLine(e,buf,SDLG_BUF_SIZE,x0,x1-1,y+1); + insEditLine(e,strlen(inittext)); + strcpy(buf,inittext); + } + VariableDStr(x,y+1,s); + updEditLine(e); + drawEditLine(e,sel,blink); +} + +enum { SDLG_WW=0x1, SDLG_CS=0x2, SDLG_SA=0x4, SDLG_ALL=0x40, SDLG_REPL=0x80, }; +char text_find[SDLG_BUF_SIZE],text_repl[SDLG_BUF_SIZE]; +int search_attr=0; +int search_coord=0; +int SearchDlg(int rep) { + WIN_RECT win; + int key; + int n_it=1+rep+SDLG_NUM_OPTS,sel_it=0,blink=0; + int a=search_attr,s; + char buf_find[SDLG_BUF_SIZE],buf_repl[SDLG_BUF_SIZE]; + EDIT_LINE box_find,box_repl; + int init=1,x,y; + PushScr(); + while (1) { + dialog((rep?"Replace text":"Find text"),120,8+(rep?8:0)+6*SDLG_NUM_OPTS,B_MOVEAROUND|B_ROUNDED,&win); + x=physical_to_virtual(win.x0); y=win.y0; + boxDisp(&box_find,"Text to find:",x,y,sel_it-0,blink, + buf_find,text_find,x+SDLG_LEFT_MARGIN,win.x1>>2,init), y+=8; + if (rep) + boxDisp(&box_repl,"Replace with:",x,y,sel_it-1,blink, + buf_repl,text_repl,x+SDLG_LEFT_MARGIN,win.x1>>2,init), y+=8; + s=sel_it-rep-1; + drawCheckBox("Whole word only", a,SDLG_WW,x,y,s-0), y+=6; + drawCheckBox("Case-sensitive", a,SDLG_CS,x,y,s-1), y+=6; + drawCheckBox("Search all files",a,SDLG_SA,x,y,s-2), y+=6; + init=0; + key=WaitLoop(&blink); + if (!key) continue; + blink=0; + if (key==KEY_UP && sel_it) sel_it--; + else if (key==KEY_DOWN && sel_it='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || c=='_' || c=='$') +int DoSearch() { + int a=search_attr,f=0; + if (*text_find) { + char *p=tptr+curpos,*q=text_find; + char v=*q++,v2=(!(a&SDLG_CS) && isalpha(v)?v^0x20:v),c,d; + int n,need_nonidch=(a&SDLG_WW?is_c_idch(v):0); + while (*p) { + if ((*p==v && (p++,1)) || *p++==v2) { + char *s=p; + if (need_nonidch && is_c_idch(p[-2])) continue; + if (a&SDLG_CS) { + while ((c=*q++)) + if (*p++!=c) goto not_here; + } else { + while ((c=*q++)) + if ((d=*p++)!=c) { + if ((d^=c)!=0x20) goto not_here; + c|=d; + if (!(c>='a' && c<='z')) goto not_here; + } + } + if ((a&SDLG_WW) && is_c_idch(p[-1]) && is_c_idch(*p)) goto not_here; + // we have a match :) + f++; + sel1=cpos=(s-tptr)-1; + sel2=curpos=selpos=cpos+strlen(text_find); + if (a&SDLG_REPL) { + sel_del(); // this is legal because we updated sel1 & sel2 + insert(n=strlen(text_repl)); + selpos=cpos; + cpos=selpos-n; + memcpy(tptr+cpos,text_repl,n); + } + if (!(a&SDLG_ALL)) return 1; + not_here: + p=s; + q=text_find+1; + } + } + } + if (f) return -1; + PushScr(); + SimpleDlg("Find text","\nText not found!\n",B_CENTER,W_NORMAL); + PopScr(); + return 0; +} + +char wzTitle[40]; +char *wzStepPtr=0; +#define wzStep (*wzStepPtr) +int wzSuccess=0; +int wzText(char *prompt,char *dest,int n) { + WIN_RECT win; + int key; + int blink=0; + EDIT_LINE box; + int init=1,x,y; + char buf[n+1]; + wzStep++; + PushScr(); + while (1) { + dialog(wzTitle,120,12,B_CENTER|B_ROUNDED,&win); + x=win.x0>>2; y=win.y0+2; + boxDisp(&box,prompt,x,y,0,blink, + buf,dest,x+strlen(prompt)+1,win.x1>>2,init), y+=8; + init=0; + key=WaitLoop(&blink); + if (!key) continue; + blink=0; + boxProcess(&box,key); + if (key==KEY_ENTER) { + strcpy(dest,buf); + PopScr(); + return 1; + } else if (key==KEY_ESC) { + wzStep-=2; + PopScr(); + return 0; + } + } +} +int wzTextClr(char *prompt,char *dest,int n) { + dest[0]=0; + return wzText(prompt,dest,n); +} +int wzChoice(char *prompt,char **choice,int choicen,int *dest) { + wzStep++; + XP_C *xc=XpLoadList(choice,choicen); + int h=8; + WIN_RECT win; + PushScr(); + dialog(wzTitle,120,h+XP_H*XP_N,B_CENTER|B_ROUNDED,&win); + VariableDStr(physical_to_virtual(win.x0),win.y0,prompt); + xc->sel=*dest; + if (!XpLoop(xc,win.y0+h,NULL,NULL)) { + PopScr(); + wzStep-=2; + free(xc); + return 0; + } else { + PopScr(); + *dest=xc->sel; + free(xc); + return 1; + } +} +int wzChoiceDeflt(char *prompt,char **choice,int choicen,int *dest,int v) { + *dest=v; + return wzChoice(prompt,choice,choicen,dest); +} +void wzStart(char *title,char *numSteps) { + strcpy(wzTitle,title); + strcat(wzTitle," - Step "); + wzStepPtr=wzTitle+strlen(wzTitle); + strcat(wzTitle,"x of "); + strcat(wzTitle,numSteps); + wzSuccess=0; + wzStep='0'; +} +void wzDone(char *text) { + wzSuccess=1; + wzTitle[strlen(wzTitle)-sizeof("- Step x of y")]='\0'; +// asm("0:bra 0b"); + PushScr(); + SimpleDlg(wzTitle,text,B_CENTER,W_NORMAL|ICO_INFO); + PopScr(); +} +#define wzList(a...) ((char *[]){a}),sizeof((char *[]){a})/sizeof(char *) +#define wzErr(m) ({SimpleDlg(wzTitle,m,B_CENTER,W_NORMAL|ICO_ERROR);continue;}) + +#if 0 +typedef struct { + int t,id,x,y; + union { + TEXT txt; + SCROLL sc; + char *s; + } d; +} DLG_ITEM; +typedef struct { + SCROLL sel; + char *title; + int w,h,a; // width, height, attr + DLG_ITEM i[]; +} DLG; + +int DialogProcess(int key) { + DLG *d=cur_dlg; + DLG_ITEM *i; + int s; + if (key==KEY_UP) + ScrollUp(&d->sel); + else if (key==KEY_DOWN) + ScrollDn(&d->sel); + else if (key==KEY_ENTER) + return DLG_OK; + else if (key==KEY_ESC) + return DLG_ESC; + ScrollUpdNoWrap(&d->sel); + s=d->sel.sel; + i=&d->i[s]; + if (i->t<=0) + return DialogProcess(key); + switch (i->t) { + case DT_TBOX: + cur_text=i->d.txt; + return KeyProcess(key,TM_DIALOG); + case DT_MLTBOX: + cur_text=i->d.txt; + return KeyProcess(key,TM_DIALOG|TM_MULTILINE); + case DT_CBOX: + case DT_DROPDOWN: + if (key==KEY_LEFT) + ScrollUp(&i->d.sc); + else if (key==KEY_RIGHT) + ScrollDn(&i->d.sc); + ScrollUpd(&i->d.sc); + break; + case DT_TEXT: + break; + } + return 0; +} + +void DialogDisp() { + DLG *d=cur_dlg; + int n=cur_dlg->sel.n; + DLG_ITEM *i=d->i; + dialog(d->title,d->w,d->h,d->a); + while (n--) { + switch (i->t) { + case DT_TEXT: + VariableDStr(i->x,i->y,i->d.s); + break; + } + i++; + } +} + +enum { +#define DL_SKIP(x) -(x) + DL_END=0, + +}; +int DialogLoadSub(int *p,DLG_ITEM *i,int x0) { + int n=0,x=x0,y=0,z; + while (*p) { + switch ((z=*p++)) { + case DL_TEXT: + if (i) { + i->t=DT_TEXT; + i->id=*p++; + i->x=x; i->y=y; + i->d.s=p; + while (*p++); + } else { p++; while (*p++); } + n++; + y+=char_height+1; + break; + default: // DL_SKIP(-z) + p-=z; + break; + } + } +} +void DialogLoad(int *p) { +} +#endif diff --git a/ti68k/ide/display.h b/ti68k/ide/display.h new file mode 100644 index 0000000..b07521a --- /dev/null +++ b/ti68k/ide/display.h @@ -0,0 +1,652 @@ +// Displaying routines +void *Port=0; +int ycur=0; +#ifdef FORCE_SMALL_FONT +#define char_width 4 +#define virtual_char_width 1 +#define char_height 6 +#define physical_to_virtual(px) ((px)>>2) +#define virtual_to_physical(vx) ((vx)<<2) +typedef char CHAR[char_height]; +#else +int small_font = -1; +int char_width = 0; +int virtual_char_width = 0; +int char_height = 0; +enum { FONT_MEDIUM = 0, FONT_SMALL = 1 }; +void set_font(int font) { + small_font = font; + char_width = font==FONT_MEDIUM ? 6 : 4; + virtual_char_width = font==FONT_MEDIUM ? 6 : 1; + char_height = font==FONT_MEDIUM ? 8 : 6; +} +int physical_to_virtual(int px) { + if (small_font) + return px>>2; + return px; +} +int virtual_to_physical(int vx) { + if (small_font) + return vx<<2; + return vx; +} +#endif + +#ifdef __GTC__ +void SmallDChar(int x,int y,char c) __attribute__((__regparm__(3,0))); +void SmallDCharS(int x,int y,char c) __attribute__((__regparm__(3,0))); +void SmallDCharX(int x,int y,char c) __attribute__((__regparm__(3,0))); +#define xregparm(g,d,a) __attribute__((regparm(d,a))) +#else +void __attribute__((__regparm__(3))) SmallDChar(int x,int y,char c); +void __attribute__((__regparm__(3))) SmallDCharS(int x,int y,char c); +void __attribute__((__regparm__(3))) SmallDCharX(int x,int y,char c); +#define xregparm(g,d,a) __attribute__((regparm(g))) +#endif +#ifdef __GTC__ +#define SECTION_FONT +asm { + even +SmallDCharX: + and.w #0xFF,d2 + add.w d2,d2 + move.w d2,a1 + add.w d2,d2 + add.w a1,d2 + lea font(pc),a1 + add.w d2,a1 + add.w d1,d1 + move.w d1,d2 + lsl.w #4,d1 + sub.w d2,d1 + moveq #0x0000000F,d2 + asr.w #1,d0 + bcs.s \X_ok_d2 + moveq #0xFFFFFFF0,d2 +\X_ok_d2: + move.l Port,a0 + add.w d1,d0 + add.w d0,a0 + move.b (a1)+,d0 + and.b d2,d0 + eor.b d0,(a0) + move.b (a1)+,d0 + and.b d2,d0 + eor.b d0,30(a0) + move.b (a1)+,d0 + and.b d2,d0 + eor.b d0,60(a0) + move.b (a1)+,d0 + and.b d2,d0 + eor.b d0,90(a0) + move.b (a1)+,d0 + and.b d2,d0 + eor.b d0,120(a0) + move.b (a1),d0 + and.b d2,d0 + eor.b d0,150(a0) + rts + even +SmallDCharS: + move.l Port,a0 + and.w #0xFF,d2 + add.w d2,d2 + move.w d2,a1 + add.w d2,d2 + add.w a1,d2 + lea font(pc),a1 + add.w d2,a1 + add.w d1,d1 + move.w d1,d2 + lsl.w #4,d1 + sub.w d2,d1 + moveq #0x0000000F,d2 + asr.w #1,d0 + bcs.s \S_ok_d2 + moveq #0xFFFFFFF0,d2 +\S_ok_d2: + add.w d1,d0 + add.w d0,a0 + move.b (a1)+,d0 + not.b d0 + and.b d2,d0 + or.b d0,(a0) + move.b (a1)+,d0 + not.b d0 + and.b d2,d0 + or.b d0,30(a0) + move.b (a1)+,d0 + not.b d0 + and.b d2,d0 + or.b d0,60(a0) + move.b (a1)+,d0 + not.b d0 + and.b d2,d0 + or.b d0,90(a0) + move.b (a1)+,d0 + not.b d0 + and.b d2,d0 + or.b d0,120(a0) + move.b (a1),d0 + not.b d0 + and.b d2,d0 + or.b d0,150(a0) + rts + even +SmallDChar: + and.w #0xFF,d2 + add.w d2,d2 + move.w d2,a1 + add.w d2,d2 + add.w a1,d2 + lea font(pc),a1 + add.w d2,a1 + add.w d1,d1 + move.w d1,d2 + lsl.w #4,d1 + sub.w d2,d1 + moveq #0x0000000F,d2 + asr.w #1,d0 + bcs.s \ok_d2 + moveq #0xFFFFFFF0,d2 +\ok_d2: + move.l Port,a0 + add.w d1,d0 + add.w d0,a0 + move.b (a1)+,d0 + and.b d2,d0 + or.b d0,(a0) + move.b (a1)+,d0 + and.b d2,d0 + or.b d0,30(a0) + move.b (a1)+,d0 + and.b d2,d0 + or.b d0,60(a0) + move.b (a1)+,d0 + and.b d2,d0 + or.b d0,90(a0) + move.b (a1)+,d0 + and.b d2,d0 + or.b d0,120(a0) + move.b (a1),d0 + and.b d2,d0 + or.b d0,150(a0) + rts +} +#else +#define ASM_SECTION_FONT //".section fontmanip" +#define SECTION_FONT //__attribute__((section("fontmanip"))) +asm(ASM_SECTION_FONT " + .even + .globl SmallDCharX +SmallDCharX: + and.w #0xFF,%d2 + add.w %d2,%d2 + move.w %d2,%a1 + add.w %d2,%d2 + add.w #262,%d2 /* to be able to use PC-relative font */ + add.w %a1,%d2 + lea font-262(%pc,%d2.w),%a1 /* this offset should be 2 (0 doesn't seem to work) */ + add.w %d1,%d1 + move.w %d1,%d2 + lsl.w #4,%d1 + sub.w %d2,%d1 + moveq #0x0000000F,%d2 + asr.w #1,%d0 + bcs.s DChX_ok_d2 + moveq #0xFFFFFFF0,%d2 +DChX_ok_d2: + move.l Port,%a0 + add.w %d1,%d0 + add.w %d0,%a0 + move.b (%a1)+,%d0 + and.b %d2,%d0 + eor.b %d0,(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + eor.b %d0,30(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + eor.b %d0,60(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + eor.b %d0,90(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + eor.b %d0,120(%a0) + move.b (%a1),%d0 + and.b %d2,%d0 + eor.b %d0,150(%a0) + rts + .even + .globl SmallDCharS +SmallDCharS: + move.l Port,%a0 + and.w #0xFF,%d2 + addq.w #8,%d2 /* to be able to use PC-relative font */ + add.w %d2,%d2 + move.w %d2,%a1 + add.w %d2,%d2 + add.w %a1,%d2 + lea font-48(%pc,%d2.w),%a1 + add.w %d1,%d1 + move.w %d1,%d2 + lsl.w #4,%d1 + sub.w %d2,%d1 + moveq #0x0000000F,%d2 + asr.w #1,%d0 + bcs.s DChS_ok_d2 + moveq #0xFFFFFFF0,%d2 +DChS_ok_d2: + add.w %d1,%d0 + add.w %d0,%a0 + move.b (%a1)+,%d0 + not.b %d0 + and.b %d2,%d0 + or.b %d0,(%a0) + move.b (%a1)+,%d0 + not.b %d0 + and.b %d2,%d0 + or.b %d0,30(%a0) + move.b (%a1)+,%d0 + not.b %d0 + and.b %d2,%d0 + or.b %d0,60(%a0) + move.b (%a1)+,%d0 + not.b %d0 + and.b %d2,%d0 + or.b %d0,90(%a0) + move.b (%a1)+,%d0 + not.b %d0 + and.b %d2,%d0 + or.b %d0,120(%a0) + move.b (%a1),%d0 + not.b %d0 + and.b %d2,%d0 + or.b %d0,150(%a0) + rts + .even + .globl SmallDChar +SmallDChar: + and.w #0xFF,%d2 + add.w %d2,%d2 + move.w %d2,%a1 + add.w %d2,%d2 + add.w %a1,%d2 + lea font(%pc,%d2.w),%a1 + add.w %d1,%d1 + move.w %d1,%d2 + lsl.w #4,%d1 + sub.w %d2,%d1 + moveq #0x0000000F,%d2 + asr.w #1,%d0 + bcs.s DCh_ok_d2 + moveq #0xFFFFFFF0,%d2 +DCh_ok_d2: + move.l Port,%a0 + add.w %d1,%d0 + add.w %d0,%a0 + move.b (%a1)+,%d0 + and.b %d2,%d0 + or.b %d0,(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + or.b %d0,30(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + or.b %d0,60(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + or.b %d0,90(%a0) + move.b (%a1)+,%d0 + and.b %d2,%d0 + or.b %d0,120(%a0) + move.b (%a1),%d0 + and.b %d2,%d0 + or.b %d0,150(%a0) + rts +"); +#endif + +const unsigned short SECTION_FONT font[]={ + #include "font.h" +}; +#define DOTS "\xA0\x01" +#define DOTS1 '\xA0' +#define DOTS2 '\x01' +#define UPARR '\x13' +#define DNARR '\x14' +char icons[]={ + 0b11111100, + 0b11111100, + 0b11000100, + 0b10110100, + 0b10110100, + 0b11000100, + 0b11111100, + + 0b11111100, + 0b11001100, + 0b10110100, + 0b10000100, + 0b10110100, + 0b10110100, + 0b11111100, + + 0b00000000, + 0b00000000, + 0b00111000, + 0b01001000, + 0b01001000, + 0b00111000, + 0b00000000, +#ifdef _89 + 0b00000000, + 0b00100000, + 0b01110000, + 0b11111000, + 0b01110000, + 0b00100000, + 0b00000000, + + 0b00000000, + 0b00100000, + 0b01110000, + 0b11111000, + 0b01110000, + 0b01110000, + 0b00000000, +#else + 0b00000000, + 0b00100000, + 0b01110000, + 0b11111000, + 0b01110000, + 0b01110000, + 0b00000000, + + 0b00000000, + 0b00100000, + 0b01110000, + 0b11111000, + 0b01110000, + 0b00100000, + 0b00000000, +#endif + 0b00000000, + 0b00110000, + 0b01001000, + 0b00010000, + 0b00100000, + 0b01111000, + 0b00000000, +}; + +/*void __attribute__((__regparm__(3))) SmallDChar(int x,int y,char c) { + char *p=((CHAR *)font)[c&255],*s=Port+(x>>1)+y*30; + int m; + if (x&1) m=0x0F; + else m=0xF0; + s[30*0]|=(*p++)&m; + s[30*1]|=(*p++)&m; + s[30*2]|=(*p++)&m; + s[30*3]|=(*p++)&m; + s[30*4]|=(*p++)&m; + s[30*5]|=(*p++)&m; +} +void __attribute__((__regparm__(3))) SmallDCharS(int x,int y,char c) { + char *p=((CHAR *)font)[c&255],*s=Port+(x>>1)+y*30; + int m; + if (x&1) m=0x0F; + else m=0xF0; + s[30*0]|=(~*p++)&m; + s[30*1]|=(~*p++)&m; + s[30*2]|=(~*p++)&m; + s[30*3]|=(~*p++)&m; + s[30*4]|=(~*p++)&m; + s[30*5]|=(~*p++)&m; +} +*/ + +void xregparm(2,2,1) SmallDStr(int x,int y,char *s) { + while (*s) + SmallDChar(x,y,*s++),x++; +} +void xregparm(3,3,1) SmallDStrS(int x,int y,char *s,int w) { + SmallDChar(x-1,y,0); + while (*s) + SmallDCharS(x,y,*s++),x++,w--; + while (--w>0) + SmallDCharS(x,y,' '),x++; +} +void xregparm(3,3,1) SmallDStrC(int x,int y,char *s,int w) { + while (*s) { + if (--w<0) return; + SmallDChar(x,y,*s++),x++; + } + while (--w>0) + SmallDChar(x,y,' '),x++; +} +void xregparm(3,3,1) SmallDStrCS(int x,int y,char *s,int w) { + SmallDChar(x-1,y,0); + while (*s) { + if (--w<0) return; + SmallDCharS(x,y,*s++),x++; + } + while (--w>0) + SmallDCharS(x,y,' '),x++; +} +#ifdef FORCE_SMALL_FONT +#define VariableDStr SmallDStr +#define VariableDStrS SmallDStrS +#define VariableDStrC SmallDStrC +#define VariableDStrCS SmallDStrCS +#define VariableDChar SmallDChar +#define VariableDCharS SmallDCharS +#define DChar SmallDChar +#define DCharS SmallDCharS +#define DCharX SmallDCharX +#define DStr SmallDStr +#define DStrS SmallDStrS +#else +void xregparm(2,2,1) MediumDStr(int x,int y,char *s) { + while (*s) + MediumDChar(x,y,*s++),x++; +} +void xregparm(3,3,1) MediumDStrS(int x,int y,char *s,int w) { + MediumDChar(x-1,y,0); + while (*s) + MediumDCharS(x,y,*s++),x++,w--; + while (--w>0) + MediumDCharS(x,y,' '),x++; +} +void xregparm(3,3,1) MediumDStrC(int x,int y,char *s,int w) { + while (*s) { + if (--w<0) return; + MediumDChar(x,y,*s++),x++; + } + while (--w>0) + MediumDChar(x,y,' '),x++; +} +void xregparm(3,3,1) MediumDStrCS(int x,int y,char *s,int w) { + MediumDChar(x-1,y,0); + while (*s) { + if (--w<0) return; + MediumDCharS(x,y,*s++),x++; + } + while (--w>0) + MediumDCharS(x,y,' '),x++; +} +void xregparm(2,2,1) VariableDStr(int x,int y,char *s) { + if (small_font) + SmallDStr(x,y,s); + MediumDStr(x,y,s); +} +void xregparm(3,3,1) VariableDStrS(int x,int y,char *s,int w) { + if (small_font) + SmallDStrS(x,y,s,w); + MediumDStrS(x,y,s,w); +} +void xregparm(3,3,1) VariableDStrC(int x,int y,char *s,int w) { + if (small_font) + SmallDStrC(x,y,s,w); + MediumDStrC(x,y,s,w); +} +void xregparm(3,3,1) VariableDStrCS(int x,int y,char *s,int w) { + if (small_font) + SmallDStrCS(x,y,s,w); + MediumDStrCS(x,y,s,w); +} +#endif + +void ScrRectFill2(SCR_RECT *scr,int attr) { + int y=scr->xy.y0,n=scr->xy.y1-y; + int x0=scr->xy.x0,x1=scr->xy.x1; + do { + FastDrawHLine(Port,x0,x1,y,attr); y++; + } while (n--); +} +void DrawFrame(int x0,int y0,int x1,int y1) { + FastDrawHLine(Port,x0+1,x1-1,y0,A_NORMAL); + FastDrawHLine(Port,x0+1,x1-1,y1,A_NORMAL); + FastDrawLine(Port,x0,y0+1,x0,y1-1,A_NORMAL); + FastDrawLine(Port,x1,y0+1,x1,y1-1,A_NORMAL); +} + +#define B_MOVEAROUND 0 +#define B_CENTER 0x8000 +int disp_box(int x1,int x2,int height,int attr,WIN_RECT *win) { + WIN_RECT wbox; SCR_RECT box; + if (attr&B_ROUNDED) height+=2; + wbox.x0=virtual_to_physical(x1)-3; wbox.x1=virtual_to_physical(x2)+1; + if (ycur+6+height+4>=_89_92(100-8,128-8) || (attr&B_CENTER) || ycur>=_89_92((100-8)/2,(128-8)/2)) { + wbox.y0=ycur-height-4, wbox.y1=ycur-1; + if (wbox.y0<0 || (attr&B_CENTER)) + wbox.y0=_89_92((100-8)/2-2,(128-8)/2-2)-height/2,wbox.y1=wbox.y0+height+3; + } else + wbox.y0=ycur+6, wbox.y1=ycur+5+height+4; + box.xy.x0=wbox.x0; + box.xy.x1=wbox.x1; + box.xy.y0=wbox.y0; + box.xy.y1=wbox.y1; + ScrRectFill2(&box,A_REVERSE); + DrawClipRect(&wbox,ScrRect,A_NORMAL|attr); + if (win) *win=wbox; + return box.xy.y0+2; +} + +void dialog(char *title,int width,int height,int attr,WIN_RECT *w) { + WIN_RECT win; + int h=height,x0=(X-width)/2,x1=x0+width,y0; + if (title) h+=8; + x0 = physical_to_virtual(x0); + x1 = physical_to_virtual(x1-1)+1; + y0 = disp_box(x0,x1,h,attr,&win); + x0 = virtual_to_physical(x0); + x1 = virtual_to_physical(x1); + if (title) { + SmallDStr((X/4)/2-strlen(title)/2,y0,title); + FastDrawHLine(Port,x0-2,x1,y0+6,A_NORMAL); + y0+=8; + } + if (w) w->x0=x0,w->x1=x1,w->y0=y0,w->y1=y0+height; /* I doubt that w->y1 will ever be used, but... */ +} + +enum { + W_NORMAL=0, + W_NOKEY=0x10, + W_ALLOW_F1=0x10<<1, W_ALLOW_F2=0x10<<2, W_ALLOW_F3=0x10<<3, W_ALLOW_F4=0x10<<4, W_ALLOW_F5=0x10<<5, +}; +int SimpleDlg(char *title,char *text,int attr,int wattr); + +#define SDLG_BUF_SIZE 128 +extern char text_find[SDLG_BUF_SIZE],text_repl[SDLG_BUF_SIZE]; +extern int search_attr; +int SearchDlg(int rep); +int DoSearch(); +void FindDlg() { +/* while (!kbhit()) + dialog("Find text",100,40,B_ROUNDED,NULL), LCD_restore(Port); + ngetchx();*/ + SearchDlg(1); +} + +LCD_BUFFER *scr_stk[8],**scr_sptr=0; +#define NOT_MEMORY 2 +void PushScr() { + LCD_BUFFER *p=malloc(LCD_SIZE); + *scr_sptr++=p; + if (p) memcpy(p,Port,LCD_SIZE); +} +void PopScr() { + LCD_BUFFER *p=*--scr_sptr; + if (p) { + memcpy(Port,p,LCD_SIZE); + free(p); + } +} + +/*void TestDisp() { + void *PortSave=Port; + Port=LCD_MEM; + while (!kbhit()) { + int c='a'; + memset(Port,0,30*92); + while (c<='z') { + int y=90; + do { + int x=40; + while (x--) DChar(x,y,c); + } while ((y-=6)>=0); + c++; + } + } + Port=PortSave; +}*/ + +#ifdef _89 +long MenuBar[5*8]={ + 0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFE, + 0x80000000,0x80000000,0x80000000,0x80000000,0x80000001, + 0x90000000,0xB0000000,0xB0000000,0xA0000000,0xB8000001, + 0xB0000000,0x88000000,0x88000000,0xA8000000,0xA0000001, + 0x90000000,0x90000000,0x90000000,0xB8000000,0xB0000001, + 0x90000000,0xA0000000,0x88000000,0x88000000,0x88000001, + 0xB8000000,0xB8000000,0xB0000000,0x88000000,0xB0000001, + 0x80000000,0x80000000,0x80000000,0x80000000,0x80000001, +}; +#define NMENU 5 +#else +long MenuBar[8*8]={ + 0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFE,0, + 0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000001,0, + 0x90000000,0xB0000000,0xB0000000,0xB0000000,0xB0000000,0xA0000000,0xB8000001,0, + 0xB0000000,0x88000000,0x88000000,0x88000000,0x88000000,0xA8000000,0xA0000001,0, + 0x90000000,0x90000000,0x90000000,0x90000000,0x90000000,0xB8000000,0xB0000001,0, + 0x90000000,0xA0000000,0x88000000,0x88000000,0x88000000,0x88000000,0x88000001,0, + 0xB8000000,0xB8000000,0xB0000000,0xB0000000,0xB0000000,0x88000000,0xB0000001,0, + 0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000000,0x80000001,0, +}; +//#error Adapt 'MenuBar' to the 92+ +#define NMENU 7 +#endif +void PutLine(void *src,int y) { + memcpy(Port+30*y,src,30); +} +char **MenuContents=0; +void DrawMenuBar() { + void *p=MenuBar; + int y; + for (y=Y-8;y1 && tptr[pos-2]!=NEWLINE) pos--; + cur=pos; + while (cur1 && tptr[pos-2]!=NEWLINE) pos--; + return pos; +} +char * __attribute__((__regparm__(1))) nonwhite(char *p) { + while (isspace(*p)) p++; + return p; +} +unsigned int down(unsigned int pos,int xd) { + char c,*p=tptr+pos; + int d=WIDTH,n=0; + while ((c=*p++)) { + if (--d<=0) return p-1-tptr; + if (c==NEWLINE) { + if (n || xd>d) return p-1-tptr; + p++; + n++; d=xd; + } + } + return p-1-tptr; +} +unsigned int up(unsigned int pos,int xd) { + char c,*p=tptr+pos; + int d=WIDTH-1,w,z; + while ((c=*--p),p>tptr) { + if (--d<=0 && p[-1]!=NEWLINE) return p-tptr; + if (c==NEWLINE) + goto loop2; + } + return 1; +loop2: + if (p==tptr+1) + return 1; + w=-1; z=0; + while ((c=*--p),p>tptr) { + w++; + if (c==NEWLINE) { + w--; + break; + } + } + if (p==tptr) w++; + while (w>=WIDTH-1) + w-=WIDTH-1, z+=WIDTH-1; + if (w>=xd-1) w=xd-1; + return w+z+(p==tptr?1:2+(p-tptr)); +} +/*void scroll(int d) { + +}*/ +int need_go_down() { + char c,*p=tptr+spos; + int x=1,y=2,d=curpos+1-spos; +#ifdef TITLEBAR + y=8; +#endif + if (is_nl) x=0; + while ((c=*p++)) { + if (!--d) return 0; + if (c==NEWLINE) { + x=0; if ((y+=6)>=YMAX) return 1; + } else if (++x>=WIDTH) { + x=1; + if ((y+=6)>=YMAX) return 1; + } + } + return --d; +} +unsigned int go_down() { + char c,*p=tptr+spos; + int x=1,y=0,d=curpos+1-spos; + if (is_nl) x=0; + while ((c=*p++)) { + if (!--d) return 0; + if (c==NEWLINE) { + x=0; if (++y>=(NLINES+1)/2) return p-1-tptr; + } else if (++x>=WIDTH) { + x=1; + if (++y>=(NLINES+1)/2) return p-1-tptr; + } + } +#ifndef NDEBUG + if (--d) msg="GO_DOWN"; +#endif + return 0; +} +void view_cursor() { + if (is_nl) spos++; + while (curpos=0) +int get_zone(unsigned int pos) { + int z=0; + char *lb=tptr+linebegin(pos),*nwlb=nonwhite(lb); +// char pline=(lb>tptr+1?lb[-2]:0); +// unsigned int accol[20],accoldeep=0; + if (*nwlb=='#') z|=CF_PREPROC; + if (nwlb==tptr+pos) z|=CF_DECL; + if (nwlb==lb) z|=CF_GLOBAL; + return z; +} +#ifdef TITLEBAR +char curFileName[8+1],curFileExt[4+1],curFileFullName[17+1]; +int numOpenFiles=0,curFileNum=0; +int CompUnderWay=0; +/* 89 title bar : + * [--------------------------------------] + * [GT-Dev - 12345678.text Compiling..] + * [GT-Dev - 12345678.prgm 10/12] + * [--------------------------------------] + */ +#define TBAR_HEIGHT 7 +void TBarDisp() { + char b[100]; + memset(Port,0,30*TBAR_HEIGHT); + sprintf(b,"GT-Dev - %s.%s",curFileName,curFileExt); + SmallDStr(1,1,b); + sprintf(b,"%d/%d",curFileNum+1,numOpenFiles); + if (CompUnderWay) sprintf(b,"Compiling"DOTS); + SmallDStr(_89_92(39,59)-strlen(b),1,b); + ScrRectFill2(&(SCR_RECT){{0,0,239,TBAR_HEIGHT-1}},A_XOR); + DrawPix(0,0,A_XOR); + DrawPix(0,TBAR_HEIGHT-1,A_XOR); + DrawPix(_89_92(159,239),0,A_XOR); + DrawPix(_89_92(159,239),TBAR_HEIGHT-1,A_XOR); +} +#endif +void display(int z) { + char c,*p=tptr+spos; + int x=1,y=2,d=curpos+1-spos; +#ifdef TITLEBAR + TBarDisp(); + y=TBAR_HEIGHT+1; +#endif + unsigned int j=spos-1; + int newline=is_nl; +#ifndef RELEASE + xcur=-1; +#endif + while ((c=*p++)) { + if (!--d) { xcur=x,ycur=y; + if (!z) FastDrawLine(Port,virtual_to_physical(x)-1,y,virtual_to_physical(x)-1,y+char_height-2,A_XOR) + /*FastDrawVLine(Port,virtual_to_physical(x)-1,y,y+4,A_XOR)*/; } + j++; + if (newline) { + VariableDChar(0,y,':'), newline=0; + continue; + } + if (c==NEWLINE) { + if (j>=sel1 && j>=1; + p=Port+(y*30+x); + n=6; while (n--) { + int i=30-x; + while (i--) *p++=0xFF; + p+=x; + } + } + x=1; if ((y+=6)>=YMAX) return; + newline=1; + } else { + if ((j>=sel1 && j=WIDTH) { + x=1; + if ((y+=6)>=YMAX) return; + } + } + } + if (!--d) { xcur=x,ycur=y; if (!z) FastDrawLine(Port,virtual_to_physical(x)-1,y,virtual_to_physical(x)-1,y+char_height-2,A_XOR); } +} +int last_act=0; +void sel_del() { + int n=sel2-sel1; + if (!n) { + selpos=0; + return; + } + curpos=sel1; + view_cursor(); /* otherwise spos might be in the middle of a line */ + memmove(tptr+sel1,tptr+sel2,size+1+1-sel2); + size-=n; curpos=cpos=sel1; selpos=0; +} +void insert(int n) { + size+=n; + if (size+2+1+1>hsize) + HeapUnlock(hd), HeapRealloc(hd,2+(hsize=size+100+2+1+1)), tptr=4+HLock(hd); + memmove(tptr+cpos+n,tptr+cpos,size-n+1+1-cpos); + cpos+=n; + last_act=1; +} +void text_enclose(char *l,char *r) { + int n=sel2-sel1; + int a=strlen(l),b=strlen(r); + unsigned int cps; + if (!n) insert(a+b),cpos-=b,memcpy(tptr+(cpos-a),l,a),memcpy(tptr+cpos,r,b); + else { + cps=cpos; + cpos=sel1; + insert(a); sel2+=a; + memcpy(tptr+sel1,l,a); sel1+=a; + cpos=sel2; + insert(b); + sel2-=b; + memcpy(tptr+sel2+1,r,b); + cpos=cps+a; + selpos+=a; + } +} +#define isidch(x) ({char __x=(x); \ + (__x>='0' && __x<='9') || (__x>='A' && __x<='Z') || (__x>='a' && __x<='z') || __x=='_' \ + || __x=='$' || __x=='#';}) +#define isnum(x) ({char __x=(x); __x>='0' && __x<='9';}) +int chk_curword(char *curword,unsigned int pos,int store_cwpos) { + char w[MAX_CURWORD+2],*p=tptr+pos; + int res; + if (!sel1) { + while (isidch(*--p) && p>tptr); + p++; + if (p==tptr || p[-1]==NEWLINE) p++; /* since we may have the sequence : #NEWLINE "C" ... */ + while (isnum(*p)) p++; + if (store_cwpos) { + cwpos=p-tptr; + if (cwpos>pos) goto invalid; /* may appear with numbers, for example : 123|456 */ + } /* (note : if store_cwpos==0, then it isn't a number :] ) */ + memcpy(w,p,MAX_CURWORD+2); + p=w; + p[MAX_CURWORD+1]=0; + while (isidch(*p++)); + p[-1]=0; + if (p==&w[MAX_CURWORD+2]) goto invalid; + res=strcmp(curword,w); + if (res) memcpy(curword,w,MAX_CURWORD+1); + return res; + } +invalid: + if (store_cwpos) cwpos=0; + res=curword[0]; + curword[0]=0; + return res; +} + +FILE *pchfile[MAX_OPEN_PCH]; +char *pchdata[MAX_OPEN_PCH]; +#undef pchhead +#define pchhead ((PCH_HEAD **)pchdata) +int pchnum = 0; +int add_pch(char *name) { + if (pchnum>=MAX_OPEN_PCH) + return 0; + char b[30]; + sprintf(b,"zheader\\%s",name); + if (!(pchfile[pchnum] = fopen(b, "rb"))) return 0; +#ifdef PC + pchdata[pchnum] = malloc(MAX_PCHDATA_SIZE); + fread(pchdata[pchnum],1,MAX_PCHDATA_SIZE,pchfile[pchnum]); + if (((PCH_HEAD *)pchdata[pchnum])->magic!= + ((long)'P'<<0)+((long)'C'<<8)+((long)'H'<<16)) + return 0; +#else + if (((PCH_HEAD *)(pchdata[pchnum] = *(char **)(pchfile[pchnum])))->magic!= + ((long)'P'<<24)+((long)'C'<<16)+((long)'H'<<8)) { + fclose(pchfile[pchnum]); + return 0; + } +#endif + pchnum++; + return 1; +} +void add_all_pch() { + /* first add standard headers: if MAX_CATALOG_ENTRIES is reached then we still have those */ + add_pch("keywords"); + add_pch("stdhead"); + SYM_ENTRY *se = SymFindFirst($(zheader), FO_SINGLE_FOLDER); + while (se) + add_pch(se->name), se = SymFindNext(); +} +void close_pch(void) { + while (pchnum) { + pchnum--; +#ifdef PC + free(pchdata[pchnum]); +#endif + fclose(pchfile[pchnum]); + } +} +#define MAX_MATCH 16 +int nmatch=0; +char *match[MAX_MATCH]={0}; +//char *str="SSORT"; +void ssort(char **match,int n) { + char **zsp=&match[n-1]; + while (zsp>match) { + #define cs (*csp) + char **csp=match,*ms=cs,**msp=csp; + /* ms=max string */ + /* cs=current string */ + do { + csp++; + if (strcmp(ms,cs)<0) msp=csp,ms=cs; + } while (cspdic_off; + if (*proto) + return sUnpack(proto,sUnpackBuf,p0); + if (args) { + char *d=sUnpackBuf; + *d++='_'; + *d++='('; + p=args; + while (*p) { + while ((*d++=*p++)); + d--; + } + strcpy(d,") = \xA0\x01"); + } else if (*defn) { + char *d=sUnpackBuf; + if (flags&PCHID_PACKED) sUnpack(defn,d,p0); + else strcpy(d,defn); + } else return ""; + return sUnpackBuf; + } +#else +/*char *PchRCB_editMsg(char *name,char *args,char *defn,char *proto,char *param) {*/ +PU_HANDLER (editMsg) { + char *d=sUnpackBuf; + if (*proto) { + strcpy(d,proto); + return d; + } + if (*args) + sprintf(d,"_%s;",args); + else if (*defn) { + if (!strncmp(defn,"_rom_call(",10)) { + char *s=defn+10; + d=write_until(d,&s,','); + if (d[-1]!='*') *d++=' '; + *d++='_'; + d=write_until(d,&s,','); + *d++=';'; + *d=0; + } else + strcpy(d,defn); + } else + return ""; + return sUnpackBuf; +} +#endif +SCROLL ac_s={0,0,0,0}; +//char *str="PCH_SEARCH"; +#define PUSH(x) asm("move.w %0,-(%%sp)"::"r" ((int)x)) +#define POP(x) asm("move.w (%%sp)+,%d0":"=d" (z)) +/* --- CAUTION : */ +/* USAGE OF PUSH AND POP MAKES IT VERY COMPILER-DEPENDENT */ +/* (for example, stack frames are necessary) */ +char *pch_search(char *curword,int ac_test,int MM,char **match) { /* match may be NULL if ac_test is 0 */ + /* >>> !!! the routine does NOT reset nmatch !!! <<< */ + int n=pchnum,nm=MM; char **mp=match; + #define search ac_test + /*int search; + search=(strlen(curword)<3)?0:ac_test; + if (ac_test) nmatch=0;*/ + while (n--) { + unsigned char *p0=pchdata[n],*p,c,*q; int z=PCH_HEAD_SIZE; + PUSH(0); + do { + p=p0+z; q=curword; + while ((c=*q++) && c==*p++); + if (!c) { + if (!*p) { + /* p+=1+2*3; + while (*p++); + return sUnpack(p,sUnpackBuf,p0+((PCH_HEAD *)p0)->dic_off);*/ +#ifdef NO_PCH_UTIL + return pch_help(p0+z,p0); +#else + return PchUnpack(editMsg,p0+z,p0); +#endif + } else if (search) { + *mp++=p0+z; + if (!--nm) search=0; + else { + while (*p++); + z=(p[2]<<8)|p[3]; + if (z) PUSH(z); + goto cont; + } + } else p++; + } + if ((c=p[-1])) while (*p++); + if (c=6?6:nmatch)),B_NORMAL,NULL); + ac_s.n=nmatch; ac_s.h=h; + ScrollUpd(&ac_s); + cs=&match[n=ac_s.scr]; + while (h--) { + if (!has_sel || n!=ac_s.sel) DStr(5,y,*cs++); + else DChar(3,y,0),DCharS(4,y,' '),DStrS(5,y,*cs++,35+1-5); + y+=6; n++; + } + if (ScrollHasUpArrow(&ac_s)) DCharX(4,y-6*6,UPARR); + if (ScrollHasDnArrow(&ac_s)) DCharX(4,y-6*1,DNARR); +} +void ac_do() { + char *s; int l=strlen(curword),n; + /* it's reasonable to assume that 'ac_disp' has already been called :) */ + ScrollUpd(&ac_s); + s=match[ac_s.sel]; + cpos=cwpos+l; selpos=0; + insert(n=strlen(s)-l); + memcpy(&tptr[cpos-n],s+l,n); +} + +#define SEQ(x) x "\0" +char charmap[]= + SEQ("'") + SEQ("_") + SEQ(";") + SEQ(":") + SEQ("\"") + SEQ("\\") + SEQ("<") + SEQ(">") + SEQ("!") + SEQ("&") + SEQ("@") + SEQ("<=") + SEQ(">=") + SEQ("!=") + SEQ(" // ") + SEQ("#") + SEQ(" ") + SEQ("int ") + SEQ("long ") + SEQ("char ") + SEQ("unsigned ") + SEQ("void ") + SEQ(""); +#define KEY_UMINUS 173 +#define KEY_STO 22 +/*#define KEY_CONVERT 18*/ +#define KEY_HOME 0x115 +#define KEY_CATALOG 0x116 +#define KEY_APPS 0x109 +#define KEY_2ND 4096 +#define KEY_DMD 16384 +#define KEY_SHF 8192 +int key89[]={ +#define pair(k) 337+k,340+k + pair(0),pair(KEY_2ND),pair(KEY_DMD),pair(KEY_SHF),pair(KEY_SHF+KEY_2ND),pair(KEY_SHF+KEY_DMD), +#undef pair +#define pair(k) 338+k,344+k + pair(0),pair(KEY_2ND),pair(KEY_SHF),pair(KEY_SHF+KEY_2ND), +#undef pair + KEY_BACKSPACE,16384+KEY_BACKSPACE, /* BACKSPACE/DELETE */ + KEY_DMD+4096,KEY_DMD+8192,KEY_DMD+KEY_ESC, /* CUT/COPY/PASTE */ + KEY_DMD, /* for DIAMOND+# (kbdprgm#) */ + KEY_CATALOG, /* CATALOG */ + KEY_F8,KEY_DMD+KEY_F3, /* find/replace */ + KEY_HOME, /* HOME */ + KEY_2ND+'+', /* CHAR */ + #ifdef EVHOOK + // Forbidden keys + KEY_2ND+'6',KEY_2ND+'3',KEY_2ND+'-',KEY_2ND+KEY_ENTER, /* MEM/UNITS/VAR-LINK/ENTRY */ + KEY_2ND+KEY_HOME,KEY_DMD+'|', /* CUSTOM/HELPKEYS */ + KEY_DMD+',',KEY_DMD+KEY_UMINUS, /* SYSDATA/HOMEDATA */ + 0, + #endif + // Special keys + KEY_2ND+'=',KEY_DMD+KEY_MODE,KEY_2ND+'9', + KEY_2ND+'4',KEY_2ND+'1',KEY_2ND+'2',KEY_2ND+'0', + KEY_2ND+'.',KEY_DMD+'/',KEY_DMD+'*',KEY_DMD+KEY_STO, + KEY_DMD+'0',KEY_DMD+'.',KEY_DMD+'=',KEY_DMD+')', + KEY_DMD+',',KEY_UMINUS, + 18/*KEY_2ND+KEY_MODE*/,151/*KEY_2ND+KEY_CATALOG*/,KEY_2ND+KEY_APPS, /* int/long/char */ + KEY_DMD+KEY_CATALOG,KEY_DMD+KEY_APPS, /* unsigned/void */ + 0 +}; +#undef KEY_DMD +#undef KEY_SHF +#define KEY_DMD 8192 +#define KEY_SHF 16384 +#ifdef PEDROM +#define KA_MOD 32 +#else +#define KA_MOD 0 +#endif +int key92[]={ +#define pair(k) 338+k,344+k + pair(0),pair(KEY_2ND),pair(KEY_DMD),pair(KEY_SHF),pair(KEY_SHF+KEY_2ND),pair(KEY_SHF+KEY_DMD), +#undef pair +#define pair(k) 337+k,340+k + pair(0),pair(KEY_2ND),pair(KEY_SHF),pair(KEY_SHF+KEY_2ND), +#undef pair + KEY_BACKSPACE,8192+KEY_BACKSPACE, /* BACKSPACE/DELETE */ + KEY_DMD+KA_MOD+'X',KEY_DMD+KA_MOD+'C',KEY_DMD+KA_MOD+'V', /* CUT/COPY/PASTE */ + KEY_DMD, /* DIAMOND+# (kbdprgm#) */ + KEY_2ND+'2', /* CATALOG */ + KEY_2ND+KEY_F3,KEY_DMD+KEY_F3, /* find/replace */ + KEY_DMD+KA_MOD+'Q', /* HOME */ + KEY_2ND+'+', /* CHAR */ + #ifdef EVHOOK + // Forbidden keys + #error missing for 92 + #endif + // Special keys + KEY_2ND+KA_MOD+'B',KEY_2ND+KA_MOD+'P',KEY_2ND+KA_MOD+'M', + KEY_2ND+136/*key_theta*/,KEY_2ND+KA_MOD+'L',KEY_2ND+'=',KEY_2ND+'0', + KEY_2ND+'.',KEY_2ND+KA_MOD+'H',KEY_2ND+KA_MOD+'W',KEY_2ND+KA_MOD+'R', + KEY_DMD+'0',KEY_DMD+'.',KEY_DMD+'=',KEY_2ND+KA_MOD+'X', + KEY_2ND+KA_MOD+'T',1, + 1,1,1, // -> disable + 1,1, // -> disable +// 18/*KEY_2ND+KEY_MODE*/,151/*KEY_2ND+KEY_CATALOG*/,KEY_2ND+KEY_APPS, /* int/long/char */ +// KEY_DMD+KEY_CATALOG,KEY_DMD+KEY_APPS, /* unsigned/void */ + 0 +}; +#undef KEY_DMD +#undef KEY_SHF +#define KEY_DMD q89(16384,8192) +#define KEY_SHF q89(8192,16384) + + +void DrawStatus() { + int x=64; char *p=icons; + if (MenuContents && !(ST_flagsL & (x-1))) { DrawMenuBar(); return; } + char *q0=Port+_89_92((100-7)*30,(128-7)*30),*q; + memset(q0-30,0xFF,30); + memset(q0,0,30*7); + DStr(2,LCD_HEIGHT-6,msg); + while ((x>>=1)) { + if (ST_flagsL & x) { + int n=7; + q=q0; + while (n--) *q=*p++, q+=30; + } else + p+=7; + } +} +char msgBuf[58+1]; /* max string length on 92/V200 is 240/4-2=58 */ +int *get_keylist() { + return _89_92(key89,key92); +} +char *Catalog(); +char CharDlg(); +int cKID=200,cBKD=35; +void Off() { + off(); + OSInitKeyInitDelay(cKID); + OSInitBetweenKeyDelay(cBKD); +} +char **catmatch=0; int catnum=0; +void FreeMem() { + if (catmatch) free(catmatch),catmatch=0; +} + +int ac_on=0,ac_disp=0; diff --git a/ti68k/ide/editor.h b/ti68k/ide/editor.h new file mode 100644 index 0000000..b45acd9 --- /dev/null +++ b/ti68k/ide/editor.h @@ -0,0 +1,227 @@ +// Text Editor +#include "Workspace.h" +int onopen_gotoline=-1; +char *onopen_gotofile=NULL; +//void Edit(SYM_STR sym_text,char *text_name) { +void Edit(char *text_path) { + if (!(Port=malloc(LCD_SIZE))) + return; + PortSet(Port,239,127); + onopen_gotoline=-1; + +editor_reopen: + if (onopen_gotofile!=NULL) + text_path = onopen_gotofile, onopen_gotofile = NULL; + char sym_buf[1+8+1+8+1]; + *sym_buf = 0; + strncpy(sym_buf+1,text_path,sizeof(sym_buf)-1); + SYM_STR sym_text = sym_buf+1; + while (*sym_text) sym_text++; + char *text_name = strrchr(text_path,'\\'); + if (!text_name) + text_name = text_path; + +editor_reopen_samefile: { + int key,k,n,z=0; + void *ptr; int *kp; + unsigned int ST_f; + #ifdef HD2 + #define hdx hd2 + HANDLE hd2; + #else + #define hdx hd + #endif + int CU_state,KID,BKD,EDH_proc; + HSym hs; int arch=0; + if (!(hs=SymFind(sym_text)).folder) + goto editor_quit; + hdx=DerefSym(hs)->handle; + NLINES=(LCD_HEIGHT-10)/6; + YMAX=2+6*NLINES; +#ifdef TITLEBAR + NLINES--; +#endif + hs=SymFind(sym_text); // because malloc may cause garbage collection (shouldn't change HSym, but...) + if (DerefSym(hs)->flags.bits.archived) + arch=1 + #ifndef HD2 + , EM_moveSymFromExtMem(sym_text,HS_NULL), hdx=DerefSym(hs)->handle + #endif + ; + #ifdef HD2 + hsize=*(unsigned int *)HeapDeref(hdx); + hd=HeapAlloc(2+hsize); + if (!hd) return; + ptr=HLock(hd); + memcpy(ptr,HeapDeref(hdx),2+hsize); + #else + ptr=HLock(hd); + #endif + tptr=ptr+4; + spos=0; selpos=0; sel1=0; sel2=0; + curpos=cpos=((unsigned int *)ptr)[1]; + if (onopen_gotoline>=0) { + cpos=1; + while (--onopen_gotoline) + while (tptr[cpos]) { + if (tptr[cpos]==NEWLINE) { + cpos+=2; + break; + } + cpos++; + } + //cpos=down(cpos,0); + curpos=cpos; + onopen_gotoline=-1; + } +/* tptr=" test-123123123123123123123123123123123123123\n \n \n OK :)" + "\n \n \n end\n \n \n of\n \n \n file" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";*/ +/* tptr=" test-123123123123123123123123123123123123123\n \n \n \n \n OK :)" + "\n \n \n \n \n end\n \n \n \n \n of\n \n \n \n \n file\0\0\0\0\0\0\0";*/ + size=strlen(tptr); hsize=*((unsigned int *)ptr); + if (!cpos || cpos>size) + cpos=1; + InitSearch(); +// is_nl=1; + CU_state=CU_start(); + scr_sptr=scr_stk; +#ifndef PEDROM + KID=OSInitKeyInitDelay(cKID); + BKD=OSInitBetweenKeyDelay(cBKD); +#endif + view_cursor(); + msg="Welcome to GTC IDE !"; + curword[0]=0; + pchnum=0; + last_act=0; ac_on=0; ac_disp=0; + add_all_pch(); + //add_pch("std"); + //add_pch("stdhead"); + //add_pch("gen"); + //add_pch("extgraph"); + //add_pch("graphx"); + //add_pch("keywords"); + OSTimerRestart(APD_TIMER); + { +#if 0 + char *p=(char *)sym_text; + while (*--p); + strcpy(curFileFullName,p+1); +#else + strcpy(curFileFullName,text_path); +#endif + } + strcpy(curFileName,text_name); + strcpy(curFileExt,GetFTString(hdx)); + strtolower(curFileExt); +// WspNew(); +// WspNew(); + editor_exit_requested=0; // as the init in the loop is not sufficient... + do { + unsigned int par1s=par1; + memset(Port,0,LCD_SIZE); + par1=0; par2=0; + if (!sel1) { + unsigned int pos=cpos; + int deep=0; + while (pos>1 && tptr[pos-2]!=NEWLINE) { + pos--; + if (tptr[pos]==')') deep--; + if (tptr[pos]=='(' && (++deep)>0) { par1=pos; break; } + } + if (par1) { + while (tptr[pos] && tptr[pos]!=NEWLINE) { + pos++; + if (tptr[pos]=='(') deep++; + if (tptr[pos]==')' && (--deep)<=0) { par2=pos; break; } + } + if (!par2) par1=0; + } + } + if (chk_curword(curword,cpos,1) || (!curword[0] && par1!=par1s)) { +// char *tp; + nmatch=0; + if (curword[0] && (msg=pch_search(curword,strlen(curword)>=2,MAX_MATCH,match))) + msg=msg; + else if (chk_curword(parword,par1,0) && (msg=pch_search(parword,0,0,NULL))) msg=msg; + else msg=0; + if (msg) { msg=memcpy(msgBuf,msg,58); msg[58]=0; } + ac_disp=nmatch?last_act:0; + ac_on=0; + } + display(z); + if (ac_disp) ac_display(ac_on); +#ifndef RELEASE + if (xcur<0) msg="Cursor not encountered", xcur=1; + if (!curpos || tptr[curpos-1]==NEWLINE) msg="Invalid curpos"; +#endif + DrawStatus(); + LCD_restore(Port); + in_loop: + ST_f=ST_flagsL; + while (!(key=kbhit()) && !OSTimerExpired(CURSOR_TIMER) + && !OSTimerExpired(APD_TIMER) && ST_f==ST_flagsL) + idle(); + if (ST_f!=ST_flagsL) { + DrawStatus(); + LCD_restore(Port); + goto in_loop; + } else if (OSTimerExpired(APD_TIMER)) { + Off(); + OSTimerRestart(APD_TIMER); + continue; + } + OSTimerRestart(CURSOR_TIMER); + z=~z; + if (!key) continue; + OSTimerRestart(APD_TIMER); + last_act=0; + key=ngetchx(); + editor_exit_requested=0; + KeyProcess(key,TM_MULTILINE); + z=0; + } while (key!=KEY_ESC && !editor_exit_requested); + close_pch(); +#ifndef PEDROM + OSInitKeyInitDelay(KID); + OSInitBetweenKeyDelay(BKD); +#endif + if (!CU_state) CU_stop(); + ((unsigned int *)tptr)[-1]=cpos; + ((unsigned int *)tptr)[-2]=size+2+1+1; + FreeMem(); + #ifdef HD2 + if (memcmp(tptr,2+2+HeapDeref(hdx),size+1+1)) { + SimpleDlg(NULL,"\n Saving file"DOTS" \n",B_CENTER,W_NOKEY); + LCD_restore(Port); + hs=SymFind(sym_text); + if (arch) + EM_moveSymFromExtMem(sym_text,HS_NULL), hdx=DerefSym(hs)->handle; + HeapFree(hdx); + HeapUnlock(hd); + HeapRealloc(hd,size+2+2+1+1); + hs=SymFind(sym_text); + DerefSym(hs)->handle=hd; + if (arch) + if (!EM_moveSymToExtMem(sym_text,HS_NULL)) + ST_helpMsg("!!! MEMORY !!!"),ngetchx(); + } else HeapUnlock(hd), HeapFree(hd); + #else + HeapUnlock(hd); + HeapRealloc(hd,size+2+2+1+1); + if (arch) + EM_moveSymToExtMem(sym_text,HS_NULL); + #endif + if (editor_exit_requested==EDEX_COMPILE) { + SimpleDlg(NULL,"\n Compiling project"DOTS" \n",B_CENTER,W_NOKEY); + LCD_restore(Port); + Compile(curFileFullName,PLUGIN_GTC); + goto editor_reopen; + } + } +editor_quit: + PortRestore(); + free(Port); +} diff --git a/ti68k/ide/editui.h b/ti68k/ide/editui.h new file mode 100644 index 0000000..6063722 --- /dev/null +++ b/ti68k/ide/editui.h @@ -0,0 +1,551 @@ +// Text editing User Interface routines + +/* Common routines */ +int repeated=0; // was the last key repeated? +int WaitLoop(int *blink) { + int key=0; // this is necessary when blinking + unsigned int ST_f; + DrawStatus(); + LCD_restore(Port); + in_loop: + ST_f=ST_flagsL; + while (OSdequeue(&key,kbdq) && (!blink || !OSTimerExpired(CURSOR_TIMER)) + && !OSTimerExpired(APD_TIMER) && ST_f==ST_flagsL) + idle(); + if (!key) { // to avoid a potential race condition that would 'forget' that keypress + if (ST_f!=ST_flagsL) { + DrawStatus(); + LCD_restore(Port); + goto in_loop; + } else if (OSTimerExpired(APD_TIMER)) { + Off(); + OSTimerRestart(APD_TIMER); + goto in_loop; + } + } + OSTimerRestart(CURSOR_TIMER); + if (blink) *blink=~(*blink); +#ifndef DONT_USE_KBDQ + if (key) OSTimerRestart(APD_TIMER); + repeated=key&0x0800; + return key&0xF7FF; +#else + if (!key) return 0; + OSTimerRestart(APD_TIMER); + return ngetchx(); +#endif +} +typedef struct { + char *buf; + int sz; + int x0,y,w; + WIN_RECT win; + SCROLL scr; +} EDIT_LINE; +void newEditLine(EDIT_LINE *e,char *buf,int sz,int x0,int x1,int y) { + int w=x1-x0; + e->buf=buf; buf[0]=0; e->sz=sz; + e->x0=x0; e->y=y; e->w=w; + e->win.x0=virtual_to_physical(x0)-2; + e->win.x1=virtual_to_physical(x1)+1; + e->win.y0=y-2; + e->win.y1=y+char_height+2; + e->scr.n=1; e->scr.h=0; + ScrollInit(&e->scr); +} +int insEditLine(EDIT_LINE *e,int n) { + if (e->scr.n+n<=e->sz) { + memmove(e->buf+e->scr.sel+n,e->buf+e->scr.sel,e->scr.n-e->scr.sel); + e->scr.n+=n; + e->scr.sel+=n; + return 1; + } + return 0; +} +#define getEditLinePos(e) ((e)->buf+(e)->scr.sel) +int delEditLine(EDIT_LINE *e,int n) { + if (e->scr.sel>=n) { + e->scr.n-=n; + e->scr.sel-=n; + memmove(e->buf+e->scr.sel,e->buf+e->scr.sel+n,e->scr.n-e->scr.sel); + return 1; + } + return 0; +} +void updEditLine(EDIT_LINE *e) { /* to be called when buffer content changes */ + int l=strlen(e->buf); + e->scr.n=l+1; + if (l>e->w) l=e->w; + e->scr.h=l+1; +} +void DrawVLine(void *p,int x,int y1,int y2,int a) { + FastDrawLine(p,x,y1,x,y2,a); +} +void drawEditLine(EDIT_LINE *e,int inactive,int blink) { +// asm("0:jbra 0b"); + updEditLine(e); + ScrollUpdNoWrapDots(&e->scr); + VariableDStrC(e->x0,e->y,e->buf+e->scr.scr,e->w); + if (inactive) return; + DrawClipRect(&e->win,ScrRect,A_NORMAL); + if (!blink) DrawVLine(Port,((e->x0-e->scr.scr+e->scr.sel)<<2)-1,e->y,e->y+char_height-2,A_XOR); +} +void drawCheckBox(char *s,int v,int f,int x,int y,int inactive) { + if (!inactive) VariableDStr(x,y,"[ ]"); + VariableDChar(x+virtual_char_width,y,(v&f)?3:2); + VariableDStr(x+3*virtual_char_width,y,s); +} + +typedef long DLG_ICON[8]; +DLG_ICON DlgIcons[4]={ + {0x03000480,0x08400860,0x13201330,0x23102318,0x4308430C,0x80048306,0x8306400E,0x3FFC1FF8}, + {0x07801FE0,0x3FF077B8,0x631CF03C,0xF87EF87E,0xF03E631E,0x77BC3FFC,0x1FF80FF0,0x03C00000}, + {0x0FC03030,0x4308430C,0x80048706,0x83068306,0x430E478C,0x301C1E38,0x073000B0,0x00700030}, + {0x0FC03030,0x47884CCC,0x8CC48186,0x83068006,0x430E430C,0x301C1E38,0x073000B0,0x00700030}, +}; +enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 }; + +void DrawText(char *p,int x,int y,int w,int h0,int hM,int *wp,int *hp,int draw) { + /* NB: x&y only needed in draw */ + char c,*word=p; int cx=x,cy=y-h0,yM=y+hM; + if (cy=yM) return; else if (cy==y) draw=-draw; } +// else if (c==' ') + else { + if (draw>0) DChar(cx,cy,c); + cx++; if (!draw && *wp=w) { cx=x,cy+=6,(*hp)+=6; if (cy>=yM) return; else if (cy==y) draw=-draw; } + } + } +} +void dialog(char *title,int width,int height,int attr,WIN_RECT *w); +#define MAX_TEXT_LINENUM 0x1000 +#define MAXH 10 +asm("identity: rts"); +int __attribute__((regparm)) identity(int x); +int SimpleDlg(char *title,char *text,int attr,int wattr) { + int dummy1,dummy2; WIN_RECT win; + int w=116/4,h=6,rh; + int h0=0,xsh=0,key; + if (wattr&ICO_MASK) w-=5; + DrawText(text,0,0,w,0,MAX_TEXT_LINENUM,&w,&h,0); + rh=h; + if (h>MAXH*6) h=MAXH*6,xsh=2; + if (wattr&ICO_MASK) xsh+=5; + if (!(wattr&W_NOKEY)) PushScr(); + while (1) { + dialog(title,(w+xsh)<<2,h,attr|B_ROUNDED,&win); + DrawText(text,(win.x0>>2)+xsh,win.y0,w,h0,h,&dummy1,&dummy2,1); + if (wattr&ICO_MASK) { + // 'identity 'fixes TIGCC bug :p + Sprite16(((win.x0>>2)+xsh-5)<<2,win.y0,16,(short *)(DlgIcons[identity(wattr&ICO_RMASK)]),Port,A_OR); + } + if (h0) DChar(win.x0>>2,win.y0,UPARR); + if (h0+MAXH*6>2,win.y0+(MAXH-1)*6,DNARR); + if (wattr&W_NOKEY) return 0; + key=WaitLoop(NULL); + if (key==KEY_UP && h0) h0-=6; + else if (key==KEY_DOWN && h0+MAXH*6=KEY_F1 && key<=KEY_F5 && (wattr&(0x10<<(key-KEY_F0)))) return key-KEY_F0; + } +} +int YesNoDlg(char *title,char *text) { + char ntext[300]; + strcpy(ntext,text); + strcat(ntext,"\n\n [ENTER]=Yes\n [ESC] =No"); + return SimpleDlg(title,ntext,B_CENTER,W_NORMAL|ICO_QUEST); +} +#ifdef NEED_DEBUG_MSG +void debug_msg(char *s) { + char b[200]; + sprintf(b,"\n %s \n",s); + SimpleDlg("Debug",b,B_CENTER,W_NORMAL|ICO_INFO); +} +#endif + + +/* CHAR LIST */ +char CharDlg() { + static int sel=32; + while (1) { + int scr=(sel>=128); + int c=scr?128:0,maxc=c+128; int y,key; WIN_RECT w; + char title[]="Char list - Page x"; + title[sizeof("Char list - Page x")-2]='1'+scr; + dialog(title,(16+1)*8,6*8/* =48 */,B_CENTER|B_NORMAL,&w); + y=w.y0; + DChar(w.x0>>2,y+(scr?0:6*(8-1)),(scr?UPARR:DNARR)); + while (c>2)+3,n=16; + while (n--) { + if (c>=16) { + if (c==sel) + DCharS(x,y,c),DChar(x-1,y,0); + else DChar(x,y,c); + } + c++,x+=2; + } + y+=6; + } + if (!(key=WaitLoop(NULL))) continue; + if (key==KEY_ESC) break; + else if (key==KEY_LEFT) sel--; + else if (key==KEY_RIGHT) sel++; + else if (key==KEY_UP) sel-=16; + else if (key==KEY_DOWN) sel+=16; + else if (key==KEY_ENTER) + return sel; + if (sel<16) sel+=256-16; + if (sel>=256) sel-=256-16; + } + return 0; +} + + +/* CATALOG */ +/*int __attribute__((__regparm__(2))) cat_ins(char *p,char **match,int n) { + char *s1,*s2,c; + int a=0,b=n-1,m; + while (a<=b) { + m=(a+b)>>1; + s1=p; + s2=match[m]; + do { + if (!(c=*s2++) && !*s1) + return n; + } while (*s1++==c); + if (s1[-1]>1; + s1=p; + s2=mp[m]; +/* asm volatile( + "comp_loop:" + "move.b (%1)+,%%d0;" + "beq.s check_dup;" + "check_dup_false:" + "move.b (%2)+,%%d1;" + "eor.b %%d1,%%d0;" + "and.b %5,%%d0;" + "beq.s comp_loop;" + "bpl.s change_a;" + "change_b:" + "subq.w #1,%6;" + "move.w %6,%4;" + "bra ok_comp;" + "check_dup:" + "tst.b (%2);" + "bne check_dup_false;" + "bra cont_lbl;" + "change_a:" + "subq.w #1,%6;" + "move.w %6,%3;" + "ok_comp:" + : "+&a" (s1),"+&a" (s2), "+g" (a), "+g" (b) + : "d" ((char)0xDF), "d" (m) + : "d0","d1");*/ + do { + if (!(c=*s2++) && !*s1) { + if (!(c=strcmp(mp[m],p))) + goto cont; + c+=OR_VAL; // very important to be '+' !!! + break; + } + c|=OR_VAL; + } while ((*s1++|OR_VAL)==c); + if ((s1[-1]|OR_VAL)=0 + dual_memmove4_plus4((long *)mp,(long *)&mdata[b],nm-b); + *mp=p; mdata[b]=p0; + if (++nm>=MM) return nm-1; + } +/* if (*p && (nm=cat_ins(p,match,nm))>=MM) + return 0;*/ +// asm volatile("cont_lbl: ziorjieog"); + cont: + while (*p++); + z=(p[2]<<8)|p[3]; + if (z) PUSH(z); + z=(*p++)<<8; z+=*p; + if (!z) POP(z); + } while (z); + } + return nm-1; +} + +/*int cat_prep(int MM,char **match) { + int nm_old=nmatch,n; + pch_search("",1,MM,match); + n=nmatch; + nmatch=nm_old; + return n; +}*/ +void cat_list(SCROLL *s,char **match,int x,int w,int y) { + int i,h; char **cs; + ScrollUpd(s); + cs=&match[i=s->scr]; + h=s->h; + while (h--) { + if (i!=s->sel) DStr(x,y,*cs++); + else DStrS(x,y,*cs++,w); + y+=6; i++; + } +} +#define SEARCH_FUNC(name,TYPE,comp,conv) void cat_##name##_search(SCROLL *s,char **match,TYPE c) { \ + char **p=&match[s->sel]; int sel=s->sel; \ + c=conv(c); \ + if (comp(c,*p)<0) p=match,sel=0; \ + while (comp(c,*p)>0) p++,sel++; \ + if (sel>=s->n) sel=s->n-1; \ + if (s->sel!=sel) s->scr=s->n-s->h/* (max value for s->scr) */,s->sel=sel; \ +} +#define toindiff(x) ((x)|0x20) +int strcmpindiff(char *a,char *b) { + char c; + do { + c=*a++; + if (toindiff(c)-toindiff(*b++)) + return toindiff(c)-toindiff(b[-1]); + } while (c); + return 0; +} +#define letter_comp(ch,s) ((ch)-toindiff(*(s))) +SEARCH_FUNC(letter,char,letter_comp,toindiff) +#define identity(x) (x) +SEARCH_FUNC(str,char *,strcmpindiff,identity) + +//char str[]="CATALOG"; +int flags(char *p) { + while (*p++); + return ((char *)p)[2*3-2]<<8; +} +#ifdef NO_PCH_UTIL + //char pchUnpackBuf[500]; + char *pch_unpack(char *p,char *p0) { + char *name=p,*args=NULL,*defn,*proto; + int flags; + while (*p++); + p+=2*3; + if ((flags=((char *)p)[-2]<<8)&PCHID_MACRO) { + args=p; + while (*p) + while (*p++); + p++; + } + defn=p; + while (*p++); + proto=p; + p0+=((PCH_HEAD *)p0)->dic_off; + if (*proto) + return sUnpack(proto,sUnpackBuf,p0); + if (args) { + char *d=sUnpackBuf; + *d++='_'; + *d++='('; + p=args; + while (*p) { + while ((*d++=*p++)); + d--; + } + strcpy(d,") = " DOTS); + } else if (*defn) { + char *d=sUnpackBuf; + strcpy(d,"_ = "); d+=4; + if (flags&PCHID_PACKED) sUnpack(defn,d,p0); + else strcpy(d,defn); + } else return "[no prototype]"; + return sUnpackBuf; + } + char *pch_unpack2(char *p,char *p0) { + char *name=p,*args=NULL,*defn,*proto; + int flags; char *d; + while (*p++); + p+=2*3; + if ((flags=((char *)p)[-2]<<8)&PCHID_MACRO) { + args=p; + while (*p) + while (*p++); + p++; + } + defn=p; + while (*p++); + proto=p; + p0+=((PCH_HEAD *)p0)->dic_off; + if (*proto) + return sUnpack(proto,sUnpackBuf,p0); + d=sUnpackBuf; + d+=sprintf(d," > Implementation :\n"); + if (args || *defn) { + d+=sprintf(d,"#define %s",name); + if (args) { + *d++='('; + p=args; + while (*p) { + while ((*d++=*p++)); + d--; + } + *d++=')'; + } + *d++=' '; + if (flags&PCHID_PACKED) sUnpack(defn,d,p0); + else strcpy(d,defn); + while (*d++); d--; + } + if (*proto) { + *d++='\n'; + sUnpack(proto,d,p0); + } + return sUnpackBuf; + } +#else +PU_HANDLER (catHelp) { + char *d=sUnpackBuf; + d+=sprintf(d," > Implementation :\n"); + if (*args || *defn) { + d+=sprintf(d,"#define %s%s %s",name,args,defn); + if (*trueproto) *d++='\n'; + } + if (*trueproto) + d+=sprintf(d,"%s",trueproto); + return sUnpackBuf; +} +PU_HANDLER (catMsg) { + char *d=sUnpackBuf; + if (*proto) { + strcpy(d,proto); + return d; + } + if (*args) + sprintf(d,"_%s = "DOTS,args); + else if (*defn) + sprintf(d,"_ = %s",defn); + else + return "[no prototype]"; + return d; +} +#endif +char cat_retbuf[80]; +char *Catalog() { + int n; char *ret=NULL; + char **match,**mdata; + if (!catmatch) { + if (!(catmatch=match=malloc(MAX_CATALOG_ENTRIES*4*2))) return ret; + mdata=match+MAX_CATALOG_ENTRIES; + SimpleDlg(NULL,"\n Loading catalog"DOTS" \n",B_CENTER,W_NOKEY); + LCD_restore(Port); + catnum=n=cat_prep(MAX_CATALOG_ENTRIES,match,mdata); + } else n=catnum,match=catmatch,mdata=match+MAX_CATALOG_ENTRIES; + #ifndef PEDROM + unsigned char alphaState; + alphaLockOn(&alphaState); + #endif + if (n) { + int key,height; SCROLL s; char title[100]; WIN_RECT win; + int last_sel=-1; + EDIT_LINE search; + sprintf(title,"Catalog - %d entries",n); + s.h=min(_89_92(12,16),n); s.n=n; ScrollInit(&s); + if (curword[0]) + cat_str_search(&s,match,curword); + // true_h = s.h*6 + 8(title) + 4(border) + 8(search line) + height=s.h*6; + while (1) { + dialog(title,128,height,B_ROUNDED|B_CENTER,&win); + cat_list(&s,match,win.x0>>2,((win.x1-win.x0)>>2)+1,win.y0); + if (s.sel!=last_sel) +#ifdef NO_PCH_UTIL + last_sel=s.sel, memcpy(msgBuf,pch_unpack(match[s.sel],mdata[s.sel]),58), msg=msgBuf, msgBuf[58]=0; +#else + last_sel=s.sel, memcpy(msgBuf,PchUnpack(catMsg,match[s.sel],mdata[s.sel]),58), + msg=msgBuf, msgBuf[58]=0; +#endif + if (!(key=WaitLoop(NULL))) continue; + if (key==KEY_ESC) break; + else if (key==KEY_ENTER) { + strcpy(ret=cat_retbuf,match[s.sel]); break; + } else if (key==KEY_UP) + repeated=0, ScrollUp(&s); + else if (key==KEY_DOWN) + repeated=0, ScrollDn(&s); + else if (key==KEY_2ND+KEY_UP) + ScrollChgWrapOnlyAtEnd(&s,-s.h); + else if (key==KEY_2ND+KEY_DOWN) + ScrollChgWrapOnlyAtEnd(&s,s.h); + else if (key==KEY_DMD+KEY_UP) + s.sel=0; + else if (key==KEY_DMD+KEY_DOWN) + s.sel=-1; + else if (key>=32 && key<=255 && isidch(key)) + cat_letter_search(&s,match,key); + else if (key==KEY_F1) +#ifdef NO_PCH_UTIL + SimpleDlg("Help",pch_unpack2(match[s.sel],mdata[s.sel]),B_CENTER,W_NORMAL); +#else + SimpleDlg("Help",PchUnpack(catHelp,match[s.sel],mdata[s.sel]),B_CENTER,W_NORMAL); +#endif + if (repeated) // happens only if the key was repeated AND 'repeated' wasn't cleared + ScrollUpdNoWrap(&s); + } + } + #ifndef PEDROM + SetAlphaStatus(alphaState); + #endif + return ret; +} + +#include "Dialogs.h" diff --git a/ti68k/ide/files.h b/ti68k/ide/files.h new file mode 100644 index 0000000..e64732a --- /dev/null +++ b/ti68k/ide/files.h @@ -0,0 +1,98 @@ +// Files misc mgt routines + +// internal filetypes... +enum { + IFT_INVALID=0, + IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC, + IFT_PACK /* (?) */, IFT_EXPR, +}; +// remark : currently IFT_XFUNC and IFT_PACK are never generated... +int IFTIcons[]={ + [IFT_INVALID] 0, + [IFT_OTH] 3, + [IFT_TEXT] 4, + [IFT_RES] 5, + [IFT_C] 6, + [IFT_H] 7, + [IFT_PRGM] 8, + [IFT_FUNC] 8, + [IFT_XFUNC]8, + [IFT_PACK] 9, + [IFT_EXPR] 10, +}; + +HANDLE FindFile(char *f) { + HSym hs; + if (!(hs=SymFind(SYMSTR(f))).folder) + return H_NULL; + SYM_ENTRY *se=DerefSym(hs); + return se->handle; +} +int GetIFT(HANDLE h) { + ESI tagptr=HToESI(h); + switch (*tagptr) { + case OTH_TAG: + tagptr--; + while (*--tagptr); + tagptr++; + switch (*tagptr) { + case 'C': + if (!strcmp(tagptr,"C")) return IFT_C; + break; + case 'H': + if (!strcmp(tagptr,"H")) return IFT_H; + break; + case 'R': + if (!strcmp(tagptr,"RES")) return IFT_RES; + break; + } + return IFT_OTH; + case TEXT_TAG: + return IFT_TEXT; + case USERFUNC_TAG: + return IFT_PRGM; + } + return IFT_EXPR; +} +char *GetFTString(HANDLE h) { +#ifndef PEDROM + ESI tagptr=HToESI(h); + if (*tagptr==OTH_TAG) { + tagptr--; + while (*--tagptr); + tagptr++; + return tagptr; + } + return DataTypeNames(*tagptr); +#else + return "???"; +#endif +} + +XP_C *XpLoadItems(int filter) { + WITEM *wi=wsp->items; + int n=wsp->nitems; + XP_C *xc=malloc(sizeof(XP_C)+(n+2)*sizeof(XP_S)); + XP_S *xs; + if (!xc) return xc; + xs=(XP_S *)(xc+1); + xs->i=0; xs++; xc->s=xs; + xc->sh=0; xc->sel=0; xc->msel=n-1; + while (n--) { + if (wi->d.type==WI_FOLD) { + *(long *)&xs->i=0x00010002; + xs->d=wi->d.title; + } else { + int t=GetIFT(FindFile(wi->f.name)); + if (filter&(1<i=0xC002; + xs->t=IFTIcons[t]; + xs->d=wi->f.name; + } + xs++; + skipit: + wi++; + } + xs->i=0; + return xc; +} diff --git a/ti68k/ide/font.bin b/ti68k/ide/font.bin new file mode 100644 index 0000000000000000000000000000000000000000..026f4e1f3e47d35376f327e658f9f4cb967659d2 GIT binary patch literal 1536 zcmeH`!EFOk2t=ucTBwCusD)ang&Oh(NA@Wv`w&I>DSXj5T^zvBF z=2&@@TXb|95RLniO7bR$pNWb^y;0GJT=ri!ban$rFHIozQap-E z*|yb-iWR4j$#|GyP_HnAM~-i#U{r`xw3eg^f1no|VqiOq6t*7TrFJXmQH_8!zY5Sv z3fjT4(?^(=CGa~68k1S;n4vm#Cjj5%jPgM|{BEa(tCjz&DO&vz)l0MPRO?AnArem# z=XLv~PEXj%ezWDp~ZaC-PCHcAExo>WKV~g+SKBFi2bsf*r#}fWKALIHb`h5<3 E0h{#e6#xJL literal 0 HcmV?d00001 diff --git a/ti68k/ide/font.h b/ti68k/ide/font.h new file mode 100644 index 0000000..a914f8f --- /dev/null +++ b/ti68k/ide/font.h @@ -0,0 +1,66 @@ +#define __UNAVAILABLE_CHAR__ 0x33DD,0xBBFF,0xBBFF + + 0x1111,0x1111,0x1111, 0x0000,0x0000,0x8800, 0x00EE,0xAAEE,0x0000, 0x00EE,0xEEEE,0x0000, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, 0x0044,0xEE00,0x0000, + 0x0000,0xEE44,0x0000, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + 0x0000,0x0000,0x0000, 0x4444,0x4400,0x4400, 0xAAAA,0x0000,0x0000, 0xAAEE,0xAAEE,0xAA00, + 0x66CC,0xEE66,0xCC00, 0x8822,0x4488,0x2200, 0x44AA,0x44AA,0x6600, 0x4444,0x0000,0x0000, + 0x2244,0x4444,0x2200, 0x8844,0x4444,0x8800, 0x00AA,0x44AA,0x0000, 0x0044,0xEE44,0x0000, + 0x0000,0x0044,0x8800, 0x0000,0xEE00,0x0000, 0x0000,0x0000,0x4400, 0x2222,0x4488,0x8800, + 0x44AA,0xAAAA,0x4400, 0x44CC,0x4444,0xEE00, 0xCC22,0x4488,0xEE00, 0xCC22,0x4422,0xCC00, + 0x88AA,0xEE22,0x2200, 0xEE88,0xCC22,0xCC00, 0x6688,0xEEAA,0xEE00, 0xEE22,0x4488,0x8800, + 0xEEAA,0xEEAA,0xEE00, 0xEEAA,0xEE22,0xCC00, 0x0044,0x0044,0x0000, 0x0044,0x0044,0x8800, + 0x2244,0x8844,0x2200, 0x00EE,0x00EE,0x0000, 0x8844,0x2244,0x8800, 0xCC22,0x4400,0x4400, + 0xCC22,0xAAAA,0x4400, 0x44AA,0xEEAA,0xAA00, 0xCCAA,0xCCAA,0xCC00, 0x6688,0x8888,0x6600, + 0xCCAA,0xAAAA,0xCC00, 0xEE88,0xCC88,0xEE00, 0xEE88,0xCC88,0x8800, 0x6688,0xAAAA,0x6600, + 0xAAAA,0xEEAA,0xAA00, 0xEE44,0x4444,0xEE00, 0x2222,0x22AA,0x4400, 0xAAAA,0xCCAA,0xAA00, + 0x8888,0x8888,0xEE00, 0xAAEE,0xAAAA,0xAA00, 0xCCAA,0xAAAA,0xAA00, 0xEEAA,0xAAAA,0xEE00, + 0xCCAA,0xCC88,0x8800, 0x44AA,0xAAEE,0x6600, 0xCCAA,0xCCAA,0xAA00, 0x6688,0x4422,0xCC00, + 0xEE44,0x4444,0x4400, 0xAAAA,0xAAAA,0xEE00, 0xAAAA,0xAA44,0x4400, 0xAAAA,0xAAEE,0xAA00, + 0xAAAA,0x44AA,0xAA00, 0xAAAA,0x4444,0x4400, 0xEE22,0x4488,0xEE00, 0x6644,0x4444,0x6600, + 0x8888,0x4422,0x2200, 0xCC44,0x4444,0xCC00, 0x44AA,0x0000,0x0000, 0x0000,0x0000,0x00EE, + 0x8844,0x0000,0x0000, 0x0066,0xAAAA,0x6600, 0x88CC,0xAAAA,0xCC00, 0x0066,0x8888,0x6600, + 0x2266,0xAAAA,0x6600, 0x0044,0xAACC,0x6600, 0x6688,0xCC88,0x8800, 0x0066,0xAA66,0x22CC, + 0x88CC,0xAAAA,0xAA00, 0x4400,0x4444,0x4400, 0x2200,0x2222,0xAA44, 0x8888,0xAACC,0xAA00, + 0xCC44,0x4444,0x4400, 0x00AA,0xEEAA,0xAA00, 0x00CC,0xAAAA,0xAA00, 0x0044,0xAAAA,0x4400, + 0x00CC,0xAAAA,0xCC88, 0x0066,0xAAAA,0x6622, 0x00AA,0xCC88,0x8800, 0x0066,0xCC22,0xCC00, + 0x88EE,0x8888,0x6600, 0x00AA,0xAAAA,0x6600, 0x00AA,0xAAAA,0x4400, 0x00AA,0xAAEE,0xAA00, + 0x00AA,0x4444,0xAA00, 0x00AA,0xAAAA,0x4488, 0x00EE,0x4488,0xEE00, 0x6644,0x8844,0x6600, + 0x4444,0x4444,0x4400, 0xCC44,0x2244,0xCC00, 0x66CC,0x0000,0x0000, 0x0044,0xEEEE,0x4400, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + 0x00EE,0xAAAA,0xAA00, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + 0x2244,0xEE00,0xEE00, 0x22EE,0x44EE,0x8800, 0x8844,0xEE00,0xEE00, __UNAVAILABLE_CHAR__, + 0x0000,0x0000,0xAA00, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + 0x44AA,0x4400,0x0000, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, + __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, __UNAVAILABLE_CHAR__, diff --git a/ti68k/ide/gtdev-apphdr.h b/ti68k/ide/gtdev-apphdr.h new file mode 100644 index 0000000..612327a --- /dev/null +++ b/ti68k/ide/gtdev-apphdr.h @@ -0,0 +1,122 @@ +#define OO_APP_MAGIC (377180989U) +#define OO_HANDLE (0xFF000000u) +#define OO_SYSTEM_FRAME OO_HANDLE +#define MAKE_OO_HANDLE(h) ((h) | OO_HANDLE) +#define OO_GET_HANDLE(h) ((h) & ~OO_HANDLE) +#define IS_OO_HANDLE(h) ((h) > OO_HANDLE) +typedef enum {OO_RW=0, OO_RO=1, + OO_SEQ=0, OO_KEYED=2} OO_Flags; +typedef struct +{ + ULONG key; + void *value; +} OO_Attr; +#define pFrame _pFrameX +typedef ULONG pFrame; +typedef int AppID; +typedef struct SFrameHdr +{ + pFrame parent; + pFrame prototype; + OO_Flags flags; + ULONG first; + ULONG count; +} OO_Hdr; +typedef struct SFrame +{ + OO_Hdr head; + union + { + void *value[65000]; + OO_Attr pair[65000]; + } attr; +} Frame; +typedef void (* const OO_MethodPtr)(void); +#define STRING_FRAME(name, parent, proto, first, count) \ +const OO_Hdr name = \ +{ \ + (pFrame)parent, \ + (pFrame)proto, \ + OO_RO | OO_SEQ, \ + first, \ + count \ +}; \ +static const char * const name##Attr[count] = \ +{ +#define FRAME(name, parent, proto, first, count) \ +const OO_Hdr name = \ +{ \ + (pFrame)parent, \ + (pFrame)proto, \ + OO_RO | OO_KEYED, \ + first, \ + count \ +}; \ +static const OO_Attr name##Attr[count] = \ +{ +#define ATTR(selector, val) {selector, (void *)(val)}, +#define STRING_ATTR(sel, s) {OO_FIRST_STRING+(sel), s}, +#define ENDFRAME }; +#define MAX_APPLET_NAME_SIZE (8) +typedef struct SAppHdr +{ + ULONG magic; + UCHAR name[MAX_APPLET_NAME_SIZE]; + BYTE zeros[24]; + USHORT flags; + ULONG dataLen; + ULONG codeOffset; + ULONG initDataOffset; + ULONG initDataLen; + ULONG optlen; +} AppHdr; +typedef enum {APPHDR_LOCALIZER=0x0001} APPHDR_FLAGS; +typedef void (* APP_EXT_FUNC)(void); +typedef struct SAppExtension +{ + unsigned long name; + unsigned long help; + unsigned short index; +} APP_EXTENSION; +typedef struct SAppExtEntry +{ + APP_EXT_FUNC extension; + unsigned short flags; +} APP_EXT_ENTRY; +enum {APP_EXT_PROGRAM=0x0000, APP_EXT_FUNCTION=0x0001}; +typedef enum +{ + ACB_BUILTIN =0x0001, + ACB_INSTALLED =0x0002, + ACB_LOCALIZER =0x0004, + ACB_LOCK =0x0008, + ACB_JT_VERSION=0x0010, + ACB_SELECTED =0x0020, + ACB_COLLAPSE =0x0800, + ACB_BG =0x1000, + ACB_COMPRESS =0x4000, + ACB_DELETE =0x8000 +} ACB_Flags; +typedef struct SACB +{ + USHORT flags; + AppID myID; + AppID next; + AppID prev; + ULONG publicstorage; + AppHdr const *appHeader; + BYTE const *certhdr; + pFrame appData; +} ACB; +#define MY_ACB(p) ((ACB*)((BYTE*)&(p)-OFFSETOF(ACB,appData))) +#define MY_APP_ID(p) (MY_ACB(p)->myID) +#define OO_FIRST_STRING 2048 +#define OO_FIRST_APP_STRING 2048 +#define OO_APPSTRING (OO_FIRST_STRING+OO_FIRST_APP_STRING) +#define OO_FIRST_APP_ATTR 0x10000 +typedef enum {APP_NONE=0, + APP_INTERACTIVE=1, + APP_CON=2, + APP_ACCESS_SYSVARS=4, + APP_BACKGROUND=8} + APP_Flags; diff --git a/ti68k/ide/gtdev-plugins.h b/ti68k/ide/gtdev-plugins.h new file mode 100644 index 0000000..712f95d --- /dev/null +++ b/ti68k/ide/gtdev-plugins.h @@ -0,0 +1,58 @@ +#define PLUGIN_GTBASIC 0 +#define PLUGIN_GTC 1 +#define PluginName(x) ((x)?"GTC":"GTDEVBAS") + +#define ET_FATAL -2 +#define ET_WARNING -1 +#define ET_ERROR 0 +#define ET_INTERNAL_WARNING 1 +#define ET_INTERNAL_FAILURE 2 +#define et_isinternal(x) ((x)>0) +typedef void CALLBACK (*Msg_Callback_t)(char *message,int err_type,char *func,char *file,int line,int chr); +#define MAX_PROGRESS 65535 +typedef void CALLBACK (*Progr_Callback_t)(char *func,char *file,unsigned int fprogress); +#define GTC_Compile ((int(*CALLBACK)(char *in,char *out,Msg_Callback_t msg_process, \ + Progr_Callback_t progr_process)) st->sft[0]) + +void CALLBACK message_cb(char *message,int err_type,char *func,char *file,int line,int chr); +void CALLBACK progr_cb(char *func,char *file,unsigned int fprogress); + +//#define DEBUG_COMPILE +#ifdef DEBUG_COMPILE +#define NEED_DEBUG_MSG +void debug_msg(char *s); +#endif + +int Compile(char *in_file,int plugin) { +//#ifdef DEBUG_COMPILE +// debug_msg("Compile step#1"); +//#endif + SecureTab *st=GetAppSecureTable(PluginName(plugin)); + if (!st) return 0; +//#ifdef DEBUG_COMPILE +// debug_msg("Compile step#2"); +//#endif + int res=-1; + if (plugin==PLUGIN_GTC) { +#ifdef COMPILE_ONLY + ST_helpMsg("Compiling..."); +#endif +//#ifdef DEBUG_COMPILE +// debug_msg("Compile step#3"); +//#endif + res=GTC_Compile(in_file,"main\\outbin",message_cb,progr_cb); +//#ifdef DEBUG_COMPILE +// { +// char b[100]; +// sprintf(b,"\n Compile step#4: r=%d \n",res); +// debug_msg(b); +// } +//#endif +#ifdef COMPILE_ONLY + if (!res) ST_helpMsg("Compile successful!"); + else if (res==1) ST_helpMsg("error"); + else if (res==2) ST_helpMsg("couldn't open"); +#endif + } + return res; +} diff --git a/ti68k/ide/gtdev-securecomm.h b/ti68k/ide/gtdev-securecomm.h new file mode 100644 index 0000000..4078a35 --- /dev/null +++ b/ti68k/ide/gtdev-securecomm.h @@ -0,0 +1,28 @@ +#ifdef USE_ABSOLUTE_PATHS +#include "E:\Paul\89\Ti-GCC\Projects\GT-Dev\SecureCommDef.h" +#else +#include "securecommdef.h" +#endif + +#ifndef PEDROM +SecureTab *GetAppSecureTable(char *name) { + int appid=EV_getAppID(name); + void *tmp; + AppHdr *hdr; + if (appid<=0) return NULL; + tmp=HeapDeref(appid); + (const AppHdr *)hdr=((ACB *)tmp)->appHeader; + if (hdr->magic!=OO_APP_MAGIC || strcmp(hdr->name,name)) + return NULL; + return *(SecureTab **)(((void *)hdr)+hdr->codeOffset); +} +#else +SecureTab *GetAppSecureTable(char *name) { + long *ptr=ROM_base+0x30000; + #define MK_TAG2(a,b) (((long)(a)<<8)+(b)) + #define MK_TAG(a,b,c,d) MK_TAG2(MK_TAG2(MK_TAG2(a,b),c),d) + if (*ptr++!=MK_TAG('G','T','C','.') || *ptr++!=MK_TAG('t','a','g',' ')) + return NULL; + return *(SecureTab **)ptr; +} +#endif diff --git a/ti68k/ide/handlers.h b/ti68k/ide/handlers.h new file mode 100644 index 0000000..33ff968 --- /dev/null +++ b/ti68k/ide/handlers.h @@ -0,0 +1,224 @@ +// Keyboard Handlers + +enum { + TM_MULTILINE=0x1, TM_DIALOG=0x2, +}; +void KeyProcess(int key,int tmode) { + int *kp; + int k,n; +#ifdef EVHOOK + int EDH_proc=0; + keyproc: +#endif + kp=get_keylist(); + /* UP/DOWN mode=0/2nd/Dmd/Shift/2nd+Shift/Dmd+Shift */ + if (key==*kp++) { + if (ac_disp) { ac_on=1; ScrollUp(&ac_s); } + else if (tmode&TM_MULTILINE) cpos=up(curpos,xcur),tab_chk_r(cpos),selpos=0; +/* else if (tmode&TM_DIALOG) + DialogMsg(DLG_UP);*/ + } else if (key==*kp++) { + if (ac_disp) { if (ac_on) ScrollDn(&ac_s); else ac_on=1; } + else if (tmode&TM_MULTILINE) cpos=down(curpos,xcur),tab_chk_r(cpos),selpos=0; +/* else if (tmode&TM_DIALOG) + DialogMsg(DLG_DN);*/ + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + n=NLINES; cpos=curpos; while (n--) cpos=up(cpos,xcur); + tab_chk_l(cpos); selpos=0; + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + n=NLINES; cpos=curpos; while (n--) cpos=down(cpos,xcur); + tab_chk_l(cpos); selpos=0; + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + cpos=1; tab_chk_l(cpos); selpos=0; + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + cpos=curpos; while (tptr[cpos]) cpos=down(cpos,xcur); + tab_chk_l(cpos); selpos=0; + } else if (key==*kp++) selpos=up(curpos,xcur),tab_chk_r(selpos); + else if (key==*kp++) selpos=down(curpos,xcur),tab_chk_r(selpos); + else if (key==*kp++ && (tmode&TM_MULTILINE)) { + n=NLINES; selpos=curpos; while (n--) selpos=up(selpos,xcur); + tab_chk_l(selpos); + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + n=NLINES; selpos=curpos; while (n--) selpos=down(selpos,xcur); + tab_chk_l(selpos); + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + selpos=1; tab_chk_l(selpos); + } else if (key==*kp++ && (tmode&TM_MULTILINE)) { + selpos=curpos; while (tptr[selpos]) selpos=down(selpos,xcur); + tab_chk_l(selpos); + } + /* LEFT/RIGHT mode=0/2nd/Shift/2nd+Shift */ + else if (key==*kp++) { + if (sel1) cpos=sel1, selpos=0; + else if (curpos>1) { + cpos=curpos; + cpos--; if (tptr[cpos-1]==NEWLINE) cpos--; + selpos=0; tab_chk_l(cpos); + } + } else if (key==*kp++) { + if (sel2) cpos=sel2; + else if (cpos1 && tptr[cpos-2]!=NEWLINE) cpos--; selpos=0; + } else if (key==*kp++) { + cpos=curpos; while (tptr[cpos] && tptr[cpos]!=NEWLINE) cpos++; selpos=0; + } else if (key==*kp++) { if (curpos>1) { + selpos=curpos; selpos--; if (tptr[selpos-1]==NEWLINE) selpos--; tab_chk_l(selpos); + } } else if (key==*kp++) { if (curpos1 && tptr[selpos-2]!=NEWLINE) selpos--; + } else if (key==*kp++) { + selpos=curpos; while (tptr[selpos] && tptr[selpos]!=NEWLINE) selpos++; + } else if ((k=0,key==*kp++) || (k++,key==*kp++)) { /* BACKSPACE / DELETE */ + last_act=-1; + if (sel1!=sel2) sel_del(); + else { + if (k && cpos1) { + int n=tptr[cpos-2]==NEWLINE || !tab_chk(cpos-1)?2:1; + memmove(tptr+cpos-n,tptr+cpos,size+1+1-cpos); + size-=n; cpos-=n; + } + } + } else if ((k=0,key==*kp++) || (k=1,key==*kp++)) { /* CUT/COPY */ + if (sel1!=sel2) { + CB_replaceTEXT(tptr+sel1,sel2-sel1,0); + if (!k) sel_del(); + } + } else if (key==*kp++) { /* PASTE */ + HANDLE hd; long len; + if (CB_fetchTEXT(&hd,&len)) + sel_del(), insert((unsigned short)len), + memcpy(tptr+(cpos-(unsigned short)len),HeapDeref(hd),(unsigned short)len); // multitask-unsafe ! + } else if (key==KEY_ENTER) { + if (tmode&TM_MULTILINE) { + unsigned int dpos=0; + if (ac_on) ac_do(); + else { + sel_del(); + n=whitespace(cpos,cpos); + if (tptr[cpos-1]=='{') { + if (whitespace(cpos+2,-1)<=n) { + int i=n+2; + insert(2+i), tptr[cpos-i-2]=NEWLINE; + do tptr[cpos-i-1]=' '; while (i--); + dpos=cpos; + } else n+=2; + } + insert(2+n), tptr[cpos-n-2]=NEWLINE; + do tptr[cpos-n-1]=' '; while (n--); + if (dpos) cpos=dpos; + } + } /*else if (tmode&TM_DIALOG) + DialogMsg(DLG_OK);*/ + } else if (key==KEY_ESC && ac_disp) { + key=0; ac_disp=ac_on=0; + } else if (key==KEY_CLEAR) { + int n; + if (ac_on) ac_do(); + if (linebegin(sel1)!=linebegin(sel2)) { /* tabify selection */ + msg="Not implemented yet"; + } else + sel_del(), insert(n=even(cpos)+1), tptr[cpos-n]=' ', tptr[cpos-1]=' '; + } else if (key=='(' || key=='[' || key=='{') { + int x=key=='('?0:(key=='['?1:2); + if (ac_on) ac_do(); + text_enclose(((char *[]){"(","[","{"})[x],((char *[]){")","]","}"})[x]); + } else if (key>=256 && ((k=key&~(32|4096|8192|16384))=='X' || k=='Y' || k=='Z' || k=='T')) { + k-='X'; if (k<0) k=3; k+=k; + if (key&4096) k++; + text_enclose(((char *[]){"if (","if (","for (","for (","while (","while (","else ","else {"})[k], + #ifdef PERFECT + ((char *[]){")\n\t\n\b",") {\n\t\n\b}\n"})[k&1]); + #else + #if 0 + ( + #endif + ((char *[]){") ",") {}",") ",") {}",") ",") {}","","}"})[k]); + #endif + } else if (k==KEY_ON && key!=k) { + if (key&4096) key=KEY_ESC; + Off(); + } else if ((k=(key&*kp++))>='1' && k<='9' && key>=256) { /* kbdprgm# - custom shortcuts */ + + } else if (key==*kp++) { /* CATALOG */ + char *p; + if ((p=Catalog())) + sel_del(), insert(n=strlen(p)), memcpy(tptr+cpos-n,p,n); + } else if (key==*kp++) { /* Find text */ + if (SearchDlg(0)) DoSearch(); + } else if (key==*kp++) { /* Replace text */ + if (SearchDlg(1)) DoSearch(); + } else if ((k=(key-KEY_F1+1))>=1 && k<=8) { /* Function key F# */ + /*if (k==1) TestDisp(); + else*/ + if (k==3) { + if (*text_find) DoSearch(); + else SearchDlg(0); + } else if (k==5) { + editor_exit_requested=EDEX_COMPILE; + } + } else if (key==*kp++) { /* HOME */ + + } else if (key==*kp++) { /* CHAR */ + char c; + if ((c=CharDlg()) && c>NEWLINE) + sel_del(), insert(1), tptr[cpos-1]=c; + } else { /* other keys */ + char *str=charmap; + while (*kp) { + if (key==*kp++) { + sel_del(), insert(n=strlen(str)), memcpy(tptr+cpos-n,str,n); + break; + } + while (*str++); + } + if (!*str && key>=14 && key<=255) { + if (!isidch(key) && ac_on) ac_do(); + sel_del(), insert(1), tptr[cpos-1]=key; + } + } +#ifdef EVHOOK + else if (key!=KEY_ESC && !EDH_proc && (key&0xFFF0)!=0x0150 /* arrow keys [they seem to bug] */) { + int k2=0; + void EVh(EVENT *ev) { + if (ev->Type==CM_KEYPRESS) k2=ev->extra.Key.Code+1; + else if (ev->Type==CM_STRING) { + char *p=ev->extra.pasteText; int n; + sel_del(), insert(n=strlen(p)), memcpy(tptr+cpos-n,p,n); + } + ER_throwVar(1); + } + EVENT e; + while ((k=*kp++)) if (key==k) goto keydone; + e.Type=CM_KEYPRESS; + e.extra.Key.Code=key; +// e.extra.Key.Mod =key&0xF000; + EV_captureEvents((EVENT_HANDLER)EVh); + PortRestore(); + TRY + EV_defaultHandler(&e); + ONERR + EV_captureEvents(NULL); + ENDTRY + PortSet(Port,239,127); + key=k2; + EDH_proc=1; + goto keyproc; +/* } else { + char b[100]; + sprintf(b,"[0x%x]",key); + text_enclose(b,"");*/ + } + keydone: +#endif + curpos=selpos?:cpos; + if (selpos) { + if (selpos +//#include +#include +#define GTC_IDE + +typedef unsigned long TI_LONG; +typedef unsigned short TI_SHORT; +#ifdef USE_ABSOLUTE_PATHS +#include "E:\Paul\89\_Projex\GtC\pch.h" +#include "E:\Paul\89\Ti-GCC\Projects\Gt-Dev\apphdr.h" +#include "E:\Paul\89\Ti-GCC\Projects\Gt-Dev\SecureComm.h" +#include "E:\Paul\89\Ti-GCC\Projects\Gt-Dev\Plugins.h" +#else +#include "pch.h" +#include "gtdev-apphdr.h" +#include "gtdev-securecomm.h" +#include "gtdev-plugins.h" +#endif + +/*#undef ST_flags +#define ST_flags _ROM_CALL_443 +extern unsigned long ST_flags;*/ +void *kbdq=0; +//#define ST_flags (*(unsigned long *)_rom_call_addr(443)) +//#define ST_flagsL ((unsigned int)ST_flags) +#ifndef PEDROM +#define ST_flagsL (*(unsigned int *)(_rom_call_addr(443)+2)) +#else +unsigned int ST_flagsL=0; +#endif + +char sUnpackBuf[500]; +#ifndef ONE_CALC +int calc=0; +void init_calc() { + calc=CALCULATOR; +} +#endif +#undef CALCULATOR +#ifdef _89 +#define CALCULATOR 0 +#define _89_92(x,y) (x) +#else +#define CALCULATOR 1 +#define _89_92(x,y) (y) +#endif +#define HD2 +#include "Util.h" +#include "PchUtil.h" +#include "Display.h" +#include "Edit.h" +#include "Handlers.h" +#include "EditUI.h" +#include "Plugins.h" +#include "Editor.h" + +#include "autoint_fix.h" + +char _ti89[0],_ti92plus[0]; + +void memquit() { + ST_helpMsg("Not enough memory!"); + ngetchx(); +} + +#if 0 +void _main(void) { + ESI ap; + char *fold=(char *)$(source); +// int X=LCD_WIDTH,Y=LCD_HEIGHT; + char *port; + char b[50]; + int key,sel=0; + if (AMS_1xx) { + ST_showHelp("Works only on AMS 2.0x"); + ngetchx(); + return; + } + kbdq=kbd_queue(); + #ifndef ONE_CALC + init_calc(); + #endif +/*#undef AMS_2xx +#define AMS_2xx 1 + if (AMS_2xx) ST_flags &= ~(0x100000);*/ + InitArgPtr(ap); + if (GetArgType(ap) == STR_TAG) { + fold=(char *)GetSymstrArg(ap); + } + if (GetArgType(ap) != END_TAG) { + ST_helpMsg("Syntax: explore(\"folder\")"); + ngetchx(); + return; + } + if (!SymFindHome(fold).folder) { + int ok=1; char c,*p=fold; + while ((c=*--p)) if (!(c=='_' || c>='a' || c<='z' || c>='0' || c<='9')) ok=0; + if (ok) + ok=FolderAdd(fold); + if (!ok) { + ST_helpMsg("Invalid folder name"); + ngetchx(); + return; + } + } + if (!(port=malloc(LCD_SIZE))) { memquit(); return; } + do { + char *data=malloc(400*9); + SYM_ENTRY *SymPtr; + int but[5]; + int n=0,i,st,M; + void __attribute__((stkparm)) Button(int i,char *t) { + int x=i*32; char b[100]; + but[i]=1; + sprintf(b,"F%d %s",i+1,t); + DrawLine(x+2,Y-9,x+31-2,Y-9,A_NORMAL); + DrawLine(x,Y-7,x,Y-1,A_NORMAL); + DrawLine(x+31,Y-7,x+31,Y-1,A_NORMAL); + DrawPix(x+1,Y-8,A_NORMAL); + DrawPix(x+31-1,Y-8,A_NORMAL); + DrawStr(x+2,Y-7,b,A_NORMAL); + } + if (!data) { memquit(); break; } + #define name(x) data+((x)+((x)<<3)) + SymPtr = SymFindFirst(fold,1); + while (SymPtr) { + if (SymPtr->handle) { + unsigned int *p=HLock(SymPtr->handle); + if (((unsigned char *)p)[*p+1]==TEXT_TAG) + strcpy(name(n), SymPtr->name), n++; + HeapUnlock(SymPtr->handle); + } + SymPtr = SymFindNext(); + } + PortSet(port,239,127); + ClrScr(); + DrawLine(1,0,X-2,0,A_NORMAL); + DrawLine(0,Y-1,X-1,Y-1,A_NORMAL); + DrawLine(0,1,0,Y-1,A_NORMAL); + DrawLine(X-1,1,X-1,Y-1,A_NORMAL); + memset(but,0,5*2); + FontSetSys(0); + Button(0,"New"); + if (n) { + Button(1,"Setup"); + Button(2,"Build"); + Button(3,"Run"); + } + Button(4,"About"); + /* 89 : 11 files / 92+/V200 : 14 files */ + FontSetSys(1); + M=CALCULATOR?14:11; + st=sel-(M+1)/2; + if (st>n-M) st=n-M; + if (st<0) st=0; + for (i=0;i=n) break; + if (i==sel-st) { + SCR_RECT rect={{3,(i<<3)+1,X-3,(i<<3)+9}}; + ScrRectFill(&rect,ScrRect,A_NORMAL); + } + DrawStr(3,(i<<3)+2,name(st+i),A_XOR); + } + + PortRestore(); + LCD_restore(port); + key=ngetchx(); + if (key==(int)KEY_UP) sel--; + else if (key==(int)KEY_DOWN) sel++; + else if ((i=key-KEY_F1)>=0 && i<5 && but[i]) { + if (i==0) { + char buffer[21] = {0}; + HANDLE handle = DialogNewSimple (140, 55); + DialogAddTitle(handle, "NEW PROJECT", BT_OK, BT_CANCEL); + DialogAddText(handle, 3, 20, "Follow the steps to create a new program"); + DialogAddRequest(handle, 3, 30, "Program name :", 6, 20, 14); + DialogAddText(handle, 3, 40, "Program type :"); + if (DialogDo(handle, CENTER, CENTER, buffer, NULL) == KEY_ENTER) + DlgMessage("GREETINGS", buffer, BT_OK, BT_NONE); + + } else if (i==4) { + ST_flags &= ~(0x100000); + DlgMessage("ABOUT GTC", + "\n GTC C Compiler & IDE\n\n(c) 2001-2002 by Paul Froissart\n", + BT_OK,BT_NONE); + ST_flags |= 0x100000; + } + } else if (key==KEY_ENTER) { + char *p=fold; + while (*--p); + *b=0; + sprintf(b+1,"%s\\%s",p+1,name(sel)); + free(port); + Edit(b+1+strlen(b+1),b+1+strlen(p+1)+1); + port=malloc(LCD_SIZE); + } + if (sel>=n) sel-=n; + if (sel<0) sel+=n; + free(data); + } while (key!=264); + free(port); +// if (AMS_2xx) ST_flags |= 0x100000; +} +#else +void _main(void) { +#ifndef PEDROM + if (AMS_1xx) { + ST_helpMsg("Please upgrade to AMS 2.0x"); + ngetchx(); + return; + } +#endif + kbdq=kbd_queue(); + #ifndef ONE_CALC + init_calc(); + #endif + ESI ap; + char cfold[20]; strcpy(cfold,"source"); + InitArgPtr(ap); + if (GetArgType(ap) == STR_TAG) { + strcpy(cfold,GetStrnArg(ap)); + } + FixAutoint(); + while (1) { + Port=malloc(LCD_SIZE); + if (!Port) return; + PortSet(Port,239,127); + ClrScr(); + XP_C *xc=XpLoadFat(cfold); + if (!xc) break; + XP_S *xs=XpLoop(xc,8,std_callback,NULL); + if (!xs) { free(xc); break; } + char file[20]; strcpy(file,(char *)xs->d); + while (xs->t!=1) xs--; + char fold[20]; strcpy(fold,(char *)xs->d); + strcpy(cfold,fold); + free(xc); + PortRestore(); + free(Port); +#if 0 + char b[100]; + *b=0; + sprintf(b+1,"%s\\%s",fold,file); + Edit(b+1+strlen(b+1),file); +#else + char path[8+1+8+1]; + sprintf(path,"%.8s\\%.8s",fold,file); + Edit(path); +#endif + } + RestoreAutoint(); + PortRestore(); + free(Port); +} +#endif diff --git a/ti68k/ide/pchutil.h b/ti68k/ide/pchutil.h new file mode 100644 index 0000000..584b79c --- /dev/null +++ b/ti68k/ide/pchutil.h @@ -0,0 +1,113 @@ +// PCH Utils file + +#define PU_HANDLER(f) char *PchRCB_##f \ + (char *name,char *args,char *defn,char *proto,char *trueproto,char *param) + +#define PchUnpack(f,p,p0) (pch_read(p,p0,PchRCB_##f,NULL)) +#define PchUnpackP(f,p,p0,cbp) (pch_read(p,p0,PchRCB_##f,cbp)) + +short __attribute__((stkparm)) sUnpackSize(char *in,char *dic); + +typedef char *(*PCHREAD_CB)(char *name,char *args,char *defn,char *proto,char *trueproto,char *param); +char *write_until(char *d,char **s,char c) { + char *p=*s; + while (*p && *p!=c) + *d++=*p++; + *s=p+1; + return d; +} +char *pch_read(char *p,char *p0,PCHREAD_CB cb,char *cbparam) { + char *name=p,*args0=NULL,*defn0,*proto0; + char *args,*defn,*proto,*pseudoproto; + int flags; + while (*p++); + p+=2*3; + if ((flags=((char *)p)[-2]<<8)&PCHID_MACRO) { + args0=p; + while (*p) + while (*p++); + p++; + } + defn0=p; + while (*p++); + proto0=p; + p0+=((PCH_HEAD *)p0)->dic_off; + proto=alloca(sUnpackSize(proto0,p0)); + sUnpack(proto0,proto,p0); + pseudoproto=proto; + if (args0) { + char *d; + args=d=alloca(defn0-args0); + *d++='('; + p=args0; + if (*p) + while (1) { + while ((*d++=*p++)); + d--; + if (!*p) break; + *d++=','; + } + *d++=')'; + *d=0; + } else args=""; + if ((flags&PCHID_PACKED)) { + defn=alloca(sUnpackSize(defn0,p0)); + sUnpack(defn0,defn,p0); + } else defn=defn0; + if (*defn=='_' && !strncmp(defn,"_rom_call(",10)) { + char *s=defn+10,*d=alloca(strlen(s)+2); + pseudoproto=d; + d=write_until(d,&s,','); + if (d[-1]!='*') *d++=' '; + *d++='_'; + d=write_until(d,&s,')'); + *d++=')'; + *d++=';'; + *d=0; + } + return cb(name,args,defn,pseudoproto,proto,cbparam); +} + +asm(" + xdef sUnpackSize +sUnpackSize: + move.l 4(%sp),%a0 + moveq #1,%d0 + moveq #126,%d1 + moveq #0,%d2 + move.b (%a0)+,%d2 + beq sus_quit + bmi sus_special +sus_copy_lp: + addq.w #1,%d0 +sus_next: + move.b (%a0)+,%d2 + bgt sus_copy_lp + beq sus_quit +sus_special: + subq.b #1,%d2 + bmi sus_not_escape + move.b (%a0)+,%d2 + bra sus_copy_lp +sus_not_escape: + addq.b #2,%d2 + bmi sus_not_romcall + +sus_not_romcall: + add.b %d1,%d2 + move.l 8(%sp),%a1 + dbf %d2,sus_search_loop + bra sus_search_done +sus_search_loop: + tst.b (%a1)+ + bne sus_search_loop + dbf %d2,sus_search_loop +sus_search_done: + addq.w #1,%d0 + move.b (%a1)+,%d2 + bne sus_search_done + subq.w #1,%d0 + moveq #0,%d2 + bra sus_next +sus_quit: + rts"); diff --git a/ti68k/ide/plugins.h b/ti68k/ide/plugins.h new file mode 100644 index 0000000..a1cfb0d --- /dev/null +++ b/ti68k/ide/plugins.h @@ -0,0 +1,51 @@ +extern int onopen_gotoline; +void CALLBACK message_cb(char *message,int err_type,char *func,char *file,int line,int chr) { + char *title="GT-Dev - Error",sprint[340]; + int icon=0; + strcpy(sprint,"In file '%s' (line %d), in function '%s' :\n\n"); + switch (err_type) { +#define ET_FATAL -2 +#define ET_WARNING -1 +#define ET_ERROR 0 +#define ET_INTERNAL_WARNING 1 +#define ET_INTERNAL_FAILURE 2 + case ET_FATAL: + strcat(sprint,"Fatal error!\n%s"); + icon=ICO_ERROR; + break; + case ET_ERROR: + strcat(sprint,"Error : %s"); + icon=ICO_ERROR; + break; + case ET_WARNING: + strcat(sprint,"Warning : %s"); + icon=ICO_WARN; + break; + case ET_INTERNAL_WARNING: + strcat(sprint,"An unexpected event has occurred (%s); " + "it might be possible to continue, but the generated code may " + "contain bugs.\nPlease report this bug to the developer\n\n" + "Continue?"); + icon=ICO_QUEST; + break; + case ET_INTERNAL_FAILURE: + strcat(sprint,"An internal error has occurred (%s).\n\n" + "Please report this bug to the developer"); + icon=ICO_ERROR; + break; + } + char sprinted[400]; + if (onopen_gotoline<0) onopen_gotoline=line; + sprintf(sprinted,sprint,file,line,func,message); + SimpleDlg(title,sprinted,B_CENTER,W_NORMAL|icon); +} +void CALLBACK progr_cb(char *func,char *file,unsigned int fprogress) { + char b[100]; + sprintf(b,func?"Function '%s', %d%% of '%s'":"%s%d%% of '%s'",func,fprogress,file); + b[58]=0; + char *msg_old=msg; + msg=b; + DrawStatus(); + LCD_restore(Port); + msg=msg_old; +} diff --git a/ti68k/ide/sunpack.c b/ti68k/ide/sunpack.c new file mode 100644 index 0000000..182e404 --- /dev/null +++ b/ti68k/ide/sunpack.c @@ -0,0 +1,73 @@ +#ifdef PC +char *sUnpack(char *in,char *out,char *dic) { + char c; char *out0=out; + while ((c=*in++)) { + if ((char)c>=0) *out++=c; + else { + if (c==(char)0x80) *out++=*in++; + else if (c==(char)0xFF) { + + } else { + char *dp=dic; + c-=(char)0x81; + while (c--) { + while (*dp++); + } + strcpy(out,dp); + while (*out++); out--; + } + } + } + *out++=0; + return out0; +} +#else +char *__attribute__((stkparm)) sUnpack(char *in,char *out,char *dic); +asm( +" xdef sUnpack\n" +"sUnpack:\n" +"/* bra.s sUnpack*/\n" +" move.l 4(%sp),%a0\n" +" move.l 8(%sp),%a1\n" +" moveq #126,%d1\n" +" moveq #0,%d0\n" +" move.b (%a0)+,%d0\n" +" beq su_quit\n" +" bmi su_special\n" +"su_copy_lp:\n" +" move.b %d0,(%a1)+\n" +"su_next:\n" +" move.b (%a0)+,%d0\n" +" bgt su_copy_lp\n" +" beq su_quit\n" +"su_special:\n" +" subq.b #1,%d0\n" +" bmi su_not_escape\n" +" move.b (%a0)+,(%a1)+\n" +" bra su_next\n" +"su_not_escape:\n" +" addq.b #2,%d0\n" +" bmi su_not_romcall\n" +" \n" +"su_not_romcall:\n" +" add.b %d1,%d0\n" +" move.l %a0,%d2\n" +" move.l 12(%sp),%a0\n" +" dbf %d0,su_search_loop\n" +" bra su_search_done\n" +"su_search_loop:\n" +" tst.b (%a0)+\n" +" bne su_search_loop\n" +" dbf %d0,su_search_loop\n" +"su_search_done:\n" +" move.b (%a0)+,(%a1)+\n" +" bne su_search_done\n" +" subq.w #1,%a1\n" +" move.l %d2,%a0\n" +" moveq #0,%d0\n" +" bra su_next\n" +"su_quit:\n" +" move.b %d0,(%a1)+\n" +" move.l 8(%sp),%a0\n" +" rts"); +#endif diff --git a/ti68k/ide/tags b/ti68k/ide/tags new file mode 100644 index 0000000..adef263 --- /dev/null +++ b/ti68k/ide/tags @@ -0,0 +1,600 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.7 // +ACB gtdev-apphdr.h /^} ACB;$/;" t typeref:struct:SACB +ACB_BG gtdev-apphdr.h /^ ACB_BG =0x1000,$/;" e enum:__anon17 +ACB_BUILTIN gtdev-apphdr.h /^ ACB_BUILTIN =0x0001,$/;" e enum:__anon17 +ACB_COLLAPSE gtdev-apphdr.h /^ ACB_COLLAPSE =0x0800,$/;" e enum:__anon17 +ACB_COMPRESS gtdev-apphdr.h /^ ACB_COMPRESS =0x4000,$/;" e enum:__anon17 +ACB_DELETE gtdev-apphdr.h /^ ACB_DELETE =0x8000$/;" e enum:__anon17 +ACB_Flags gtdev-apphdr.h /^} ACB_Flags;$/;" t typeref:enum:__anon17 +ACB_INSTALLED gtdev-apphdr.h /^ ACB_INSTALLED =0x0002,$/;" e enum:__anon17 +ACB_JT_VERSION gtdev-apphdr.h /^ ACB_JT_VERSION=0x0010,$/;" e enum:__anon17 +ACB_LOCALIZER gtdev-apphdr.h /^ ACB_LOCALIZER =0x0004,$/;" e enum:__anon17 +ACB_LOCK gtdev-apphdr.h /^ ACB_LOCK =0x0008,$/;" e enum:__anon17 +ACB_SELECTED gtdev-apphdr.h /^ ACB_SELECTED =0x0020,$/;" e enum:__anon17 +APPHDR_FLAGS gtdev-apphdr.h /^typedef enum {APPHDR_LOCALIZER=0x0001} APPHDR_FLAGS;$/;" t typeref:enum:__anon15 +APPHDR_LOCALIZER gtdev-apphdr.h /^typedef enum {APPHDR_LOCALIZER=0x0001} APPHDR_FLAGS;$/;" e enum:__anon15 +APP_ACCESS_SYSVARS gtdev-apphdr.h /^ APP_ACCESS_SYSVARS=4,$/;" e enum:__anon18 +APP_BACKGROUND gtdev-apphdr.h /^ APP_BACKGROUND=8}$/;" e enum:__anon18 +APP_CON gtdev-apphdr.h /^ APP_CON=2,$/;" e enum:__anon18 +APP_EXTENSION gtdev-apphdr.h /^} APP_EXTENSION;$/;" t typeref:struct:SAppExtension +APP_EXT_ENTRY gtdev-apphdr.h /^} APP_EXT_ENTRY;$/;" t typeref:struct:SAppExtEntry +APP_EXT_FUNC gtdev-apphdr.h /^typedef void (* APP_EXT_FUNC)(void);$/;" t +APP_EXT_FUNCTION gtdev-apphdr.h /^enum {APP_EXT_PROGRAM=0x0000, APP_EXT_FUNCTION=0x0001};$/;" e enum:__anon16 +APP_EXT_PROGRAM gtdev-apphdr.h /^enum {APP_EXT_PROGRAM=0x0000, APP_EXT_FUNCTION=0x0001};$/;" e enum:__anon16 +APP_Flags gtdev-apphdr.h /^ APP_Flags;$/;" t typeref:enum:__anon18 +APP_INTERACTIVE gtdev-apphdr.h /^ APP_INTERACTIVE=1,$/;" e enum:__anon18 +APP_NONE gtdev-apphdr.h /^typedef enum {APP_NONE=0,$/;" e enum:__anon18 +ASM_SECTION_FONT display.h 177;" d +ATTR gtdev-apphdr.h 57;" d +AppHdr gtdev-apphdr.h /^} AppHdr;$/;" t typeref:struct:SAppHdr +AppID gtdev-apphdr.h /^typedef int AppID;$/;" t +BATCH_COMPILE main.c 6;" d file: +B_CENTER display.h 517;" d +B_MOVEAROUND display.h 516;" d +CALCULATOR main.c 89;" d file: +CALCULATOR main.c 91;" d file: +CALCULATOR main.c 94;" d file: +CF_ASM edit.h /^ CF_C=0x4, CF_ASM=0x8, CF_LIBFUNCS=0x10,$/;" e enum:__anon8 +CF_C edit.h /^ CF_C=0x4, CF_ASM=0x8, CF_LIBFUNCS=0x10,$/;" e enum:__anon8 +CF_DECL edit.h /^ CF_GLOBAL=0x20, CF_DECL=0x40,$/;" e enum:__anon8 +CF_EXPR edit.h /^ CF_EXPR=0x80, CF_STMT=0x100,$/;" e enum:__anon8 +CF_GLOBAL edit.h /^ CF_GLOBAL=0x20, CF_DECL=0x40,$/;" e enum:__anon8 +CF_LIBFUNCS edit.h /^ CF_C=0x4, CF_ASM=0x8, CF_LIBFUNCS=0x10,$/;" e enum:__anon8 +CF_PREPROC edit.h /^ CF_TYPE=0x1, CF_PREPROC=0x2,$/;" e enum:__anon8 +CF_STMT edit.h /^ CF_EXPR=0x80, CF_STMT=0x100,$/;" e enum:__anon8 +CF_TYPE edit.h /^ CF_TYPE=0x1, CF_PREPROC=0x2,$/;" e enum:__anon8 +CHAR display.h /^typedef char CHAR[char_height];$/;" t +Catalog editui.h /^char *Catalog() {$/;" f +CharDlg editui.h /^char CharDlg() {$/;" f +CompUnderWay edit.h /^int CompUnderWay=0;$/;" v +Compile gtdev-plugins.h /^int Compile(char *in_file,int plugin) {$/;" f +DChar display.h 446;" d +DCharS display.h 447;" d +DCharX display.h 448;" d +DEFINE_XPLOOP_CB axplore.h /^DEFINE_XPLOOP_CB(onlyfiles_callback) {$/;" f +DEFINE_XPLOOP_CB axplore.h /^DEFINE_XPLOOP_CB(std_callback) {$/;" f +DEFINE_XPLOOP_CB axplore.h 114;" d +DEFINE_XPLOOP_CB workspace.h /^DEFINE_XPLOOP_CB(callback) {$/;" f +DLG_ICON editui.h /^typedef long DLG_ICON[8];$/;" t +DNARR display.h 318;" d +DOTS display.h 314;" d +DOTS1 display.h 315;" d +DOTS2 display.h 316;" d +DStr display.h 449;" d +DStrS display.h 450;" d +DlgIcons editui.h /^DLG_ICON DlgIcons[4]={$/;" v +DoSearch dialogs.h /^int DoSearch() {$/;" f +DrawFrame display.h /^void DrawFrame(int x0,int y0,int x1,int y1) {$/;" f +DrawMenuBar display.h /^void DrawMenuBar() {$/;" f +DrawSStr axplore.h 2;" d +DrawStatus edit.h /^void DrawStatus() {$/;" f +DrawText editui.h /^void DrawText(char *p,int x,int y,int w,int h0,int hM,int *wp,int *hp,int draw) {$/;" f +DrawVLine editui.h /^void DrawVLine(void *p,int x,int y1,int y2,int a) {$/;" f +EDEX_COMPILE edit.h /^enum { EDEX_NONE=0, EDEX_COMPILE };$/;" e enum:__anon7 +EDEX_NONE edit.h /^enum { EDEX_NONE=0, EDEX_COMPILE };$/;" e enum:__anon7 +EDH_proc textedit.h /^int EDH_proc=0;$/;" v +EDIT_LINE editui.h /^} EDIT_LINE;$/;" t typeref:struct:__anon9 +ENDFRAME gtdev-apphdr.h 59;" d +ET_ERROR gtdev-plugins.h 7;" d +ET_ERROR plugins.h 9;" d +ET_FATAL gtdev-plugins.h 5;" d +ET_FATAL plugins.h 7;" d +ET_INTERNAL_FAILURE gtdev-plugins.h 9;" d +ET_INTERNAL_FAILURE plugins.h 11;" d +ET_INTERNAL_WARNING gtdev-plugins.h 8;" d +ET_INTERNAL_WARNING plugins.h 10;" d +ET_WARNING gtdev-plugins.h 6;" d +ET_WARNING plugins.h 8;" d +Edit editor.h /^void Edit(char *text_path) {$/;" f +FILENAME workspace.h /^typedef char FILENAME[8+1+8+1];$/;" t +FONT_MEDIUM display.h /^enum { FONT_MEDIUM = 0, FONT_SMALL = 1 };$/;" e enum:__anon5 +FONT_SMALL display.h /^enum { FONT_MEDIUM = 0, FONT_SMALL = 1 };$/;" e enum:__anon5 +FRAME gtdev-apphdr.h 46;" d +FindDlg display.h /^void FindDlg() {$/;" f +FindFile files.h /^HANDLE FindFile(char *f) {$/;" f +FixAutoint autoint_fix.h /^void FixAutoint() {$/;" f +Frame gtdev-apphdr.h /^} Frame;$/;" t typeref:struct:SFrame +FreeMem edit.h /^void FreeMem() {$/;" f +GTC_Compile gtdev-plugins.h 14;" d +GTC_IDE main.c 54;" d file: +GetAppSecureTable gtdev-securecomm.h /^SecureTab *GetAppSecureTable(char *name) {$/;" f +GetFTString files.h /^char *GetFTString(HANDLE h) {$/;" f +GetIFT files.h /^int GetIFT(HANDLE h) {$/;" f +HANDLER textedit.h /^typedef int (*HANDLER)(int);$/;" t +HD2 main.c 97;" d file: +ICO_ERROR editui.h /^enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 };$/;" e enum:__anon10 +ICO_INFO editui.h /^enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 };$/;" e enum:__anon10 +ICO_MASK editui.h /^enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 };$/;" e enum:__anon10 +ICO_QUEST editui.h /^enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 };$/;" e enum:__anon10 +ICO_RMASK editui.h /^enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 };$/;" e enum:__anon10 +ICO_WARN editui.h /^enum { ICO_WARN=0x8, ICO_ERROR=0x9, ICO_INFO=0xA, ICO_QUEST=0xB, ICO_MASK=0xF, ICO_RMASK=0x7 };$/;" e enum:__anon10 +IFTIcons files.h /^int IFTIcons[]={$/;" v +IFT_C files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_EXPR files.h /^ IFT_PACK \/* (?) *\/, IFT_EXPR,$/;" e enum:__anon11 +IFT_FUNC files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_H files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_INVALID files.h /^ IFT_INVALID=0,$/;" e enum:__anon11 +IFT_OTH files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_PACK files.h /^ IFT_PACK \/* (?) *\/, IFT_EXPR,$/;" e enum:__anon11 +IFT_PRGM files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_RES files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_TEXT files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IFT_XFUNC files.h /^ IFT_OTH, IFT_TEXT, IFT_RES, IFT_C, IFT_H, IFT_PRGM, IFT_FUNC, IFT_XFUNC,$/;" e enum:__anon11 +IS_OO_HANDLE gtdev-apphdr.h 6;" d +InitSearch dialogs.h /^void InitSearch() {$/;" f +IntVec autoint_fix.h 49;" d +IntVec autoint_fix.h 91;" d +KA_MOD edit.h 592;" d +KA_MOD edit.h 594;" d +KEY_2ND edit.h 553;" d +KEY_APPS edit.h 552;" d +KEY_CATALOG edit.h 551;" d +KEY_DMD edit.h 554;" d +KEY_DMD edit.h 587;" d +KEY_DMD edit.h 589;" d +KEY_DMD edit.h 626;" d +KEY_DMD edit.h 628;" d +KEY_F0 editui.h 157;" d +KEY_HOME edit.h 550;" d +KEY_SHF edit.h 555;" d +KEY_SHF edit.h 588;" d +KEY_SHF edit.h 590;" d +KEY_SHF edit.h 627;" d +KEY_SHF edit.h 629;" d +KEY_STO edit.h 548;" d +KEY_UMINUS edit.h 547;" d +KeyProcess handlers.h /^void KeyProcess(int key,int tmode) {$/;" f +LIMITS_H_ limits.h 3;" d +MAKE_OO_HANDLE gtdev-apphdr.h 4;" d +MAXH editui.h 125;" d +MAX_APPLET_NAME_SIZE gtdev-apphdr.h 60;" d +MAX_BLOCK1 autoint_fix.h 7;" d +MAX_BLOCK2 autoint_fix.h 8;" d +MAX_CURWORD edit.h 13;" d +MAX_MATCH edit.h 362;" d +MAX_OPEN_PCH limits.h 5;" d +MAX_PCHDATA_SIZE limits.h 8;" d +MAX_PROGRESS gtdev-plugins.h 12;" d +MAX_TEXT_LINENUM editui.h 124;" d +MIN_AMS main.c 47;" d file: +MIN_AMS main.c 49;" d file: +MK_TAG gtdev-securecomm.h 23;" d +MK_TAG2 gtdev-securecomm.h 22;" d +MY_ACB gtdev-apphdr.h 111;" d +MY_APP_ID gtdev-apphdr.h 112;" d +MediumDStr display.h /^void xregparm(2,2,1) MediumDStr(int x,int y,char *s) {$/;" f +MediumDStrC display.h /^void xregparm(3,3,1) MediumDStrC(int x,int y,char *s,int w) {$/;" f +MediumDStrCS display.h /^void xregparm(3,3,1) MediumDStrCS(int x,int y,char *s,int w) {$/;" f +MediumDStrS display.h /^void xregparm(3,3,1) MediumDStrS(int x,int y,char *s,int w) {$/;" f +MenuBar display.h /^long MenuBar[5*8]={$/;" v +MenuBar display.h /^long MenuBar[8*8]={$/;" v +MenuContents display.h /^char **MenuContents=0;$/;" v +Msg_Callback_t gtdev-plugins.h /^typedef void CALLBACK (*Msg_Callback_t)(char *message,int err_type,char *func,char *file,int line,int chr);$/;" t +NDEBUG main.c 44;" d file: +NEED_DEBUG_MSG gtdev-plugins.h 22;" d +NEWLINE edit.h 8;" d +NLINES edit.h /^int YMAX=0,NLINES=0;$/;" v +NMENU display.h 618;" d +NMENU display.h 631;" d +NOT_MEMORY display.h 575;" d +NUM_DEFLTTYPE workspace.h 11;" d +ONE_CALC main.c 12;" d file: +OO_APPSTRING gtdev-apphdr.h 115;" d +OO_APP_MAGIC gtdev-apphdr.h 1;" d +OO_Attr gtdev-apphdr.h /^} OO_Attr;$/;" t typeref:struct:__anon13 +OO_FIRST_APP_ATTR gtdev-apphdr.h 116;" d +OO_FIRST_APP_STRING gtdev-apphdr.h 114;" d +OO_FIRST_STRING gtdev-apphdr.h 113;" d +OO_Flags gtdev-apphdr.h /^ OO_SEQ=0, OO_KEYED=2} OO_Flags;$/;" t typeref:enum:__anon12 +OO_GET_HANDLE gtdev-apphdr.h 5;" d +OO_HANDLE gtdev-apphdr.h 2;" d +OO_Hdr gtdev-apphdr.h /^} OO_Hdr;$/;" t typeref:struct:SFrameHdr +OO_KEYED gtdev-apphdr.h /^ OO_SEQ=0, OO_KEYED=2} OO_Flags;$/;" e enum:__anon12 +OO_MethodPtr gtdev-apphdr.h /^typedef void (* const OO_MethodPtr)(void);$/;" t +OO_RO gtdev-apphdr.h /^typedef enum {OO_RW=0, OO_RO=1,$/;" e enum:__anon12 +OO_RW gtdev-apphdr.h /^typedef enum {OO_RW=0, OO_RO=1,$/;" e enum:__anon12 +OO_SEQ gtdev-apphdr.h /^ OO_SEQ=0, OO_KEYED=2} OO_Flags;$/;" e enum:__anon12 +OO_SYSTEM_FRAME gtdev-apphdr.h 3;" d +OR_VAL editui.h 267;" d +OSKeyScan autoint_fix.h 2;" d +Off edit.h /^void Off() {$/;" f +PCHREAD_CB pchutil.h /^typedef char *(*PCHREAD_CB)(char *name,char *args,char *defn,char *proto,char *trueproto,char *param);$/;" t +PEDROM main.c 23;" d file: +PLUGIN_GTBASIC gtdev-plugins.h 1;" d +PLUGIN_GTC gtdev-plugins.h 2;" d +POP edit.h 447;" d +POP editui.h 252;" d +PUSH edit.h 446;" d +PUSH editui.h 251;" d +PU_HANDLER edit.h /^PU_HANDLER (editMsg) {$/;" f +PU_HANDLER editui.h /^PU_HANDLER (catHelp) {$/;" f +PU_HANDLER editui.h /^PU_HANDLER (catMsg) {$/;" f +PU_HANDLER pchutil.h 3;" d +PchUnpack pchutil.h 6;" d +PchUnpackP pchutil.h 7;" d +PluginName gtdev-plugins.h 3;" d +PopScr display.h /^void PopScr() {$/;" f +Port display.h /^void *Port=0;$/;" v +Progr_Callback_t gtdev-plugins.h /^typedef void CALLBACK (*Progr_Callback_t)(char *func,char *file,unsigned int fprogress);$/;" t +PushScr display.h /^void PushScr() {$/;" f +PutLine display.h /^void PutLine(void *src,int y) {$/;" f +RELEASE main.c 18;" d file: +RestoreAutoint autoint_fix.h /^void RestoreAutoint() {$/;" f +SACB gtdev-apphdr.h /^typedef struct SACB$/;" s +SAVE_SCREEN main.c 15;" d file: +SAppExtEntry gtdev-apphdr.h /^typedef struct SAppExtEntry$/;" s +SAppExtension gtdev-apphdr.h /^typedef struct SAppExtension$/;" s +SAppHdr gtdev-apphdr.h /^typedef struct SAppHdr$/;" s +SCROLL util.h /^} SCROLL;$/;" t typeref:struct:__anon20 +SDLG_ALL dialogs.h /^enum { SDLG_WW=0x1, SDLG_CS=0x2, SDLG_SA=0x4, SDLG_ALL=0x40, SDLG_REPL=0x80, };$/;" e enum:__anon4 +SDLG_BUF_SIZE dialogs.h 39;" d +SDLG_BUF_SIZE display.h 562;" d +SDLG_CS dialogs.h /^enum { SDLG_WW=0x1, SDLG_CS=0x2, SDLG_SA=0x4, SDLG_ALL=0x40, SDLG_REPL=0x80, };$/;" e enum:__anon4 +SDLG_LEFT_MARGIN dialogs.h 40;" d +SDLG_NUM_OPTS dialogs.h 41;" d +SDLG_REPL dialogs.h /^enum { SDLG_WW=0x1, SDLG_CS=0x2, SDLG_SA=0x4, SDLG_ALL=0x40, SDLG_REPL=0x80, };$/;" e enum:__anon4 +SDLG_SA dialogs.h /^enum { SDLG_WW=0x1, SDLG_CS=0x2, SDLG_SA=0x4, SDLG_ALL=0x40, SDLG_REPL=0x80, };$/;" e enum:__anon4 +SDLG_WW dialogs.h /^enum { SDLG_WW=0x1, SDLG_CS=0x2, SDLG_SA=0x4, SDLG_ALL=0x40, SDLG_REPL=0x80, };$/;" e enum:__anon4 +SEARCH_FUNC editui.h 349;" d +SECTION_FONT display.h 178;" d +SECTION_FONT display.h 47;" d +SEQ edit.h 522;" d +SFrame gtdev-apphdr.h /^typedef struct SFrame$/;" s +SFrameHdr gtdev-apphdr.h /^typedef struct SFrameHdr$/;" s +STRING_ATTR gtdev-apphdr.h 58;" d +STRING_FRAME gtdev-apphdr.h 35;" d +ST_flagsL main.c /^unsigned int ST_flagsL=0;$/;" v +ST_flagsL main.c 77;" d file: +ScrRectFill2 display.h /^void ScrRectFill2(SCR_RECT *scr,int attr) {$/;" f +ScrollChg util.h 6;" d +ScrollChgWrapOnlyAtEnd util.h /^void ScrollChgWrapOnlyAtEnd(SCROLL *s,int d) {$/;" f +ScrollDn util.h 8;" d +ScrollHasDnArrow util.h 10;" d +ScrollHasUpArrow util.h 9;" d +ScrollInit util.h 5;" d +ScrollUp util.h 7;" d +ScrollUpd util.h /^void ScrollUpd(SCROLL *s) {$/;" f +ScrollUpdNoWrap util.h /^void ScrollUpdNoWrap(SCROLL *s) { \/* same as ScrollUpd, but doesn't wrap *\/$/;" f +ScrollUpdNoWrapDots util.h /^void ScrollUpdNoWrapDots(SCROLL *s) { \/* same as ScrollUpdNoWrap, but leaves 1 blank on the border *\/$/;" f +SearchDlg dialogs.h /^int SearchDlg(int rep) {$/;" f +SimpleDlg editui.h /^int SimpleDlg(char *title,char *text,int attr,int wattr) {$/;" f +SmallDStr display.h /^void xregparm(2,2,1) SmallDStr(int x,int y,char *s) {$/;" f +SmallDStrC display.h /^void xregparm(3,3,1) SmallDStrC(int x,int y,char *s,int w) {$/;" f +SmallDStrCS display.h /^void xregparm(3,3,1) SmallDStrCS(int x,int y,char *s,int w) {$/;" f +SmallDStrS display.h /^void xregparm(3,3,1) SmallDStrS(int x,int y,char *s,int w) {$/;" f +TAB edit.h 21;" d +TBAR_HEIGHT edit.h 181;" d +TBarDisp edit.h /^void TBarDisp() {$/;" f +TITLEBAR main.c 9;" d file: +TI_LONG main.c /^typedef unsigned long TI_LONG;$/;" t file: +TI_SHORT main.c /^typedef unsigned short TI_SHORT;$/;" t file: +TM_DIALOG handlers.h /^ TM_MULTILINE=0x1, TM_DIALOG=0x2,$/;" e enum:__anon19 +TM_MULTILINE handlers.h /^ TM_MULTILINE=0x1, TM_DIALOG=0x2,$/;" e enum:__anon19 +UPARR display.h 317;" d +USE_TI89 main.c 32;" d file: +USE_TI92PLUS main.c 37;" d file: +USE_V200 main.c 38;" d file: +VariableDChar display.h 444;" d +VariableDCharS display.h 445;" d +VariableDStr display.h /^void xregparm(2,2,1) VariableDStr(int x,int y,char *s) {$/;" f +VariableDStr display.h 440;" d +VariableDStrC display.h /^void xregparm(3,3,1) VariableDStrC(int x,int y,char *s,int w) {$/;" f +VariableDStrC display.h 442;" d +VariableDStrCS display.h /^void xregparm(3,3,1) VariableDStrCS(int x,int y,char *s,int w) {$/;" f +VariableDStrCS display.h 443;" d +VariableDStrS display.h /^void xregparm(3,3,1) VariableDStrS(int x,int y,char *s,int w) {$/;" f +VariableDStrS display.h 441;" d +WFILE workspace.h /^} WFILE;$/;" t typeref:struct:__anon22 +WFOLD workspace.h /^} WFOLD;$/;" t typeref:struct:__anon23 +WIDTH edit.h 4;" d +WIDTH edit.h 6;" d +WITEM workspace.h /^} WITEM;$/;" t typeref:union:__anon24 +WI_FILE workspace.h /^enum { WI_FOLD=0, WI_FILE };$/;" e enum:__anon21 +WI_FOLD workspace.h /^enum { WI_FOLD=0, WI_FILE };$/;" e enum:__anon21 +WSP workspace.h /^} WSP;$/;" t typeref:struct:__anon25 +WSPT_GAME workspace.h /^enum { WSPT_SIMPLE=0, WSPT_GAME=1, WSPT_UTIL=2, WSPT_OTHER=3 };$/;" e enum:__anon26 +WSPT_OTHER workspace.h /^enum { WSPT_SIMPLE=0, WSPT_GAME=1, WSPT_UTIL=2, WSPT_OTHER=3 };$/;" e enum:__anon26 +WSPT_SIMPLE workspace.h /^enum { WSPT_SIMPLE=0, WSPT_GAME=1, WSPT_UTIL=2, WSPT_OTHER=3 };$/;" e enum:__anon26 +WSPT_UTIL workspace.h /^enum { WSPT_SIMPLE=0, WSPT_GAME=1, WSPT_UTIL=2, WSPT_OTHER=3 };$/;" e enum:__anon26 +WSP_MAX_ITEMS workspace.h 40;" d +W_ALLOW_F1 display.h /^ W_ALLOW_F1=0x10<<1, W_ALLOW_F2=0x10<<2, W_ALLOW_F3=0x10<<3, W_ALLOW_F4=0x10<<4, W_ALLOW_F5=0x10<<5,$/;" e enum:__anon6 +W_ALLOW_F2 display.h /^ W_ALLOW_F1=0x10<<1, W_ALLOW_F2=0x10<<2, W_ALLOW_F3=0x10<<3, W_ALLOW_F4=0x10<<4, W_ALLOW_F5=0x10<<5,$/;" e enum:__anon6 +W_ALLOW_F3 display.h /^ W_ALLOW_F1=0x10<<1, W_ALLOW_F2=0x10<<2, W_ALLOW_F3=0x10<<3, W_ALLOW_F4=0x10<<4, W_ALLOW_F5=0x10<<5,$/;" e enum:__anon6 +W_ALLOW_F4 display.h /^ W_ALLOW_F1=0x10<<1, W_ALLOW_F2=0x10<<2, W_ALLOW_F3=0x10<<3, W_ALLOW_F4=0x10<<4, W_ALLOW_F5=0x10<<5,$/;" e enum:__anon6 +W_ALLOW_F5 display.h /^ W_ALLOW_F1=0x10<<1, W_ALLOW_F2=0x10<<2, W_ALLOW_F3=0x10<<3, W_ALLOW_F4=0x10<<4, W_ALLOW_F5=0x10<<5,$/;" e enum:__anon6 +W_NOKEY display.h /^ W_NOKEY=0x10,$/;" e enum:__anon6 +W_NORMAL display.h /^ W_NORMAL=0,$/;" e enum:__anon6 +WaitLoop editui.h /^int WaitLoop(int *blink) {$/;" f +WspAddFile workspace.h /^int WspAddFile(char *file,char *dfold) {$/;" f +WspAddFold workspace.h /^int WspAddFold(char *fold) {$/;" f +WspAddItem workspace.h /^WITEM *WspAddItem(int i) {$/;" f +WspFindItem workspace.h /^int WspFindItem(char *wi_name,int wi_type,int i) {$/;" f +WspFindNearItem workspace.h /^int WspFindNearItem(char *wi_name,int wi_type,int i) {$/;" f +WspNew workspace.h /^void WspNew() {$/;" f +WspPromptSave workspace.h /^void WspPromptSave() {$/;" f +WspSave workspace.h /^void WspSave() {$/;" f +WspShowBrowser workspace.h /^void WspShowBrowser() {$/;" f +X main.c 33;" d file: +X main.c 39;" d file: +XPLCB_BREAK axplore.h /^enum { XPLCB_CONT=0, XPLCB_QUIT=-1, XPLCB_BREAK=1, XPLCB_OPENDIR=2 };$/;" e enum:__anon3 +XPLCB_CONT axplore.h /^enum { XPLCB_CONT=0, XPLCB_QUIT=-1, XPLCB_BREAK=1, XPLCB_OPENDIR=2 };$/;" e enum:__anon3 +XPLCB_OPENDIR axplore.h /^enum { XPLCB_CONT=0, XPLCB_QUIT=-1, XPLCB_BREAK=1, XPLCB_OPENDIR=2 };$/;" e enum:__anon3 +XPLCB_QUIT axplore.h /^enum { XPLCB_CONT=0, XPLCB_QUIT=-1, XPLCB_BREAK=1, XPLCB_OPENDIR=2 };$/;" e enum:__anon3 +XP_C axplore.h /^} XP_C;$/;" t typeref:struct:__anon2 +XP_H axplore.h 71;" d +XP_N axplore.h 70;" d +XP_S axplore.h /^} XP_S;$/;" t typeref:struct:__anon1 +XP_X1 axplore.h 68;" d +XP_X2 axplore.h 69;" d +XpDisp axplore.h /^void XpDisp(XP_C *xc,int y) {$/;" f +XpFatSub axplore.h /^long XpFatSub(XP_S *xs,char *acc,char *cfold) {$/;" f +XpLoadFat axplore.h /^XP_C *XpLoadFat(char *cfold) {$/;" f +XpLoadItems files.h /^XP_C *XpLoadItems(int filter) {$/;" f +XpLoadList axplore.h /^XP_C *XpLoadList(char **list,int n) {$/;" f +XpLoop axplore.h /^XP_S *XpLoop(XP_C *xc,int y,XPLOOP_CB callback,void *ctx) {$/;" f +XpMove axplore.h /^int XpMove(XP_C *xc,int n) {$/;" f +XpNeg axplore.h /^void XpNeg(XP_C *xc) {$/;" f +XpSprite axplore.h /^char XpSprite[8*5]={$/;" v +Y main.c 34;" d file: +Y main.c 40;" d file: +YMAX edit.h /^int YMAX=0,NLINES=0;$/;" v +YesNoDlg editui.h /^int YesNoDlg(char *title,char *text) {$/;" f +_89_92 main.c 92;" d file: +_89_92 main.c 95;" d file: +__UNAVAILABLE_CHAR__ font.h 1;" d +_main main.c /^void _main(void) {$/;" f +_ti89 main.c /^char _ti89[0],_ti92plus[0];$/;" v +_ti92plus main.c /^char _ti89[0],_ti92plus[0];$/;" v +ac_disp edit.h /^int ac_on=0,ac_disp=0;$/;" v +ac_display edit.h /^void ac_display(int has_sel) {$/;" f +ac_do edit.h /^void ac_do() {$/;" f +ac_on edit.h /^int ac_on=0,ac_disp=0;$/;" v +ac_s edit.h /^SCROLL ac_s={0,0,0,0};$/;" v +add_all_pch edit.h /^void add_all_pch() {$/;" f +add_pch edit.h /^int add_pch(char *name) {$/;" f +appData gtdev-apphdr.h /^ pFrame appData;$/;" m struct:SACB +appHeader gtdev-apphdr.h /^ AppHdr const *appHeader;$/;" m struct:SACB +attr gtdev-apphdr.h /^ } attr;$/;" m struct:SFrame typeref:union:SFrame::__anon14 +autoint_fix autoint_fix.h /^void *autoint_fix=0,*autoint_previous=0;$/;" v +autoint_fix_block autoint_fix.h /^int autoint_fix_block[(MAX_BLOCK1+MAX_BLOCK2)\/2];$/;" v +autoint_previous autoint_fix.h /^void *autoint_fix=0,*autoint_previous=0;$/;" v +boxDisp dialogs.h /^void boxDisp(EDIT_LINE *e,$/;" f +boxProcess dialogs.h /^void boxProcess(EDIT_LINE *e,int key) {$/;" f +buf editui.h /^ char *buf;$/;" m struct:__anon9 +cBKD edit.h /^int cKID=200,cBKD=35;$/;" v +cKID edit.h /^int cKID=200,cBKD=35;$/;" v +calc main.c /^int calc=0;$/;" v +cat_list editui.h /^void cat_list(SCROLL *s,char **match,int x,int w,int y) {$/;" f +cat_prep editui.h /^int cat_prep(int MM,char **match,char **mdata) {$/;" f +cat_retbuf editui.h /^char cat_retbuf[80];$/;" v +catmatch edit.h /^char **catmatch=0; int catnum=0;$/;" v +catnum edit.h /^char **catmatch=0; int catnum=0;$/;" v +certhdr gtdev-apphdr.h /^ BYTE const *certhdr;$/;" m struct:SACB +char_height display.h /^int char_height = 0;$/;" v +char_height display.h 7;" d +char_width display.h /^int char_width = 0;$/;" v +char_width display.h 5;" d +charmap edit.h /^char charmap[]=$/;" v +checkProcess dialogs.h /^int checkProcess(int v,int a,int key) {$/;" f +chk_curword edit.h /^int chk_curword(char *curword,unsigned int pos,int store_cwpos) {$/;" f +close_pch edit.h /^void close_pch(void) {$/;" f +codeOffset gtdev-apphdr.h /^ ULONG codeOffset;$/;" m struct:SAppHdr +count gtdev-apphdr.h /^ ULONG count;$/;" m struct:SFrameHdr +cpos edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +cs edit.h 369;" d +cs edit.h 377;" d +curFileExt edit.h /^char curFileName[8+1],curFileExt[4+1],curFileFullName[17+1];$/;" v +curFileFullName edit.h /^char curFileName[8+1],curFileExt[4+1],curFileFullName[17+1];$/;" v +curFileName edit.h /^char curFileName[8+1],curFileExt[4+1],curFileFullName[17+1];$/;" v +curFileNum edit.h /^int numOpenFiles=0,curFileNum=0;$/;" v +curpos edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +curword edit.h /^char *msg=0,curword[MAX_CURWORD+1]={0},parword[MAX_CURWORD+1]={0};$/;" v +cwpos edit.h /^unsigned int par1=0,par2=0,cwpos=0;$/;" v +d axplore.h /^ void *d;$/;" m struct:__anon1 +d workspace.h /^ WFOLD d;$/;" m union:__anon24 +dHandle textedit.h /^int dHandle(int key) {$/;" f +dataLen gtdev-apphdr.h /^ ULONG dataLen;$/;" m struct:SAppHdr +debug_msg editui.h /^void debug_msg(char *s) {$/;" f +deflttype workspace.h /^ int deflttype[NUM_DEFLTTYPE];$/;" m struct:__anon23 +delEditLine editui.h /^int delEditLine(EDIT_LINE *e,int n) {$/;" f +dialog display.h /^void dialog(char *title,int width,int height,int attr,WIN_RECT *w) {$/;" f +disp_box display.h /^int disp_box(int x1,int x2,int height,int attr,WIN_RECT *win) {$/;" f +display edit.h /^void display(int z) {$/;" f +down edit.h /^unsigned int down(unsigned int pos,int xd) {$/;" f +drawCheckBox editui.h /^void drawCheckBox(char *s,int v,int f,int x,int y,int inactive) {$/;" f +drawEditLine editui.h /^void drawEditLine(EDIT_LINE *e,int inactive,int blink) {$/;" f +dual_memmove4_plus4 editui.h /^void __attribute__((__regparm__(3))) dual_memmove4_plus4(long *p,long *r,int n) {$/;" f +editor_exit_requested edit.h /^int editor_exit_requested=0;$/;" v +et_isinternal gtdev-plugins.h 10;" d +even edit.h /^int even(unsigned int pos) {$/;" f +expanded workspace.h /^ int expanded;$/;" m struct:__anon23 +extension gtdev-apphdr.h /^ APP_EXT_FUNC extension;$/;" m struct:SAppExtEntry +f workspace.h /^ WFILE f;$/;" m union:__anon24 +first gtdev-apphdr.h /^ ULONG first;$/;" m struct:SFrameHdr +flags editui.h /^int flags(char *p) {$/;" f +flags gtdev-apphdr.h /^ OO_Flags flags;$/;" m struct:SFrameHdr +flags gtdev-apphdr.h /^ USHORT flags;$/;" m struct:SACB +flags gtdev-apphdr.h /^ USHORT flags;$/;" m struct:SAppHdr +flags gtdev-apphdr.h /^ unsigned short flags;$/;" m struct:SAppExtEntry +foldname workspace.h /^ char foldname[8+1];$/;" m struct:__anon25 +font display.h /^const unsigned short SECTION_FONT font[]={$/;" v +getEditLinePos editui.h 65;" d +get_keylist edit.h /^int *get_keylist() {$/;" f +get_zone edit.h /^int get_zone(unsigned int pos) {$/;" f +go_down edit.h /^unsigned int go_down() {$/;" f +h util.h /^ int sel,scr,h,n;$/;" m struct:__anon20 +handler textedit.h /^HANDLER handler=0;$/;" v +hd edit.h /^char *tptr=0; HANDLE hd=0;$/;" v +hdx editor.h 29;" d +head gtdev-apphdr.h /^ OO_Hdr head;$/;" m struct:SFrame +help gtdev-apphdr.h /^ unsigned long help;$/;" m struct:SAppExtension +hsize edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +i axplore.h /^ int i,t;$/;" m struct:__anon1 +icons display.h /^char icons[]={$/;" v +identity editui.h 369;" d +iname workspace.h /^ char iname[8+1];$/;" m struct:__anon25 +index gtdev-apphdr.h /^ unsigned short index;$/;" m struct:SAppExtension +initDataLen gtdev-apphdr.h /^ ULONG initDataLen;$/;" m struct:SAppHdr +initDataOffset gtdev-apphdr.h /^ ULONG initDataOffset;$/;" m struct:SAppHdr +init_calc main.c /^void init_calc() {$/;" f +insEditLine editui.h /^int insEditLine(EDIT_LINE *e,int n) {$/;" f +insert edit.h /^void insert(int n) {$/;" f +is_c_idch dialogs.h 104;" d +is_nl edit.h 20;" d +isidch edit.h 288;" d +isnum edit.h 291;" d +items workspace.h /^ WITEM items[0];$/;" m struct:__anon25 +kbdq main.c /^void *kbdq=0;$/;" v +key gtdev-apphdr.h /^ ULONG key;$/;" m struct:__anon13 +key89 edit.h /^int key89[]={$/;" v +key92 edit.h /^int key92[]={$/;" v +last_act edit.h /^int last_act=0;$/;" v +letter_comp editui.h 367;" d +linebegin edit.h /^unsigned int __attribute__((__regparm__(1))) linebegin(unsigned int pos) {$/;" f +loaded workspace.h /^ int loaded;$/;" m struct:__anon25 +magic gtdev-apphdr.h /^ ULONG magic;$/;" m struct:SAppHdr +match edit.h /^char *match[MAX_MATCH]={0};$/;" v +memmove4_plus4 editui.h /^void __attribute__((__regparm__(2))) memmove4_plus4(long *p,int n) {$/;" f +memquit main.c /^void memquit() {$/;" f +message_cb plugins.h /^void CALLBACK message_cb(char *message,int err_type,char *func,char *file,int line,int chr) {$/;" f +msel axplore.h /^ int sh,sel,msel;$/;" m struct:__anon2 +msg edit.h /^char *msg=0,curword[MAX_CURWORD+1]={0},parword[MAX_CURWORD+1]={0};$/;" v +msgBuf edit.h /^char msgBuf[58+1]; \/* max string length on 92\/V200 is 240\/4-2=58 *\/$/;" v +myID gtdev-apphdr.h /^ AppID myID;$/;" m struct:SACB +n util.h /^ int sel,scr,h,n;$/;" m struct:__anon20 +name gtdev-apphdr.h /^ UCHAR name[MAX_APPLET_NAME_SIZE];$/;" m struct:SAppHdr +name gtdev-apphdr.h /^ unsigned long name;$/;" m struct:SAppExtension +name workspace.h /^ FILENAME name;$/;" m struct:__anon22 +need_go_down edit.h /^int need_go_down() {$/;" f +newEditLine editui.h /^void newEditLine(EDIT_LINE *e,char *buf,int sz,int x0,int x1,int y) {$/;" f +next gtdev-apphdr.h /^ AppID next;$/;" m struct:SACB +nitems workspace.h /^ int nitems;$/;" m struct:__anon25 +nmatch edit.h /^int nmatch=0;$/;" v +nonwhite edit.h /^char * __attribute__((__regparm__(1))) nonwhite(char *p) {$/;" f +numOpenFiles edit.h /^int numOpenFiles=0,curFileNum=0;$/;" v +onopen_gotofile editor.h /^char *onopen_gotofile=NULL;$/;" v +onopen_gotoline editor.h /^int onopen_gotoline=-1;$/;" v +open workspace.h /^ int open;$/;" m struct:__anon22 +openhd workspace.h /^ HANDLE openhd;$/;" m struct:__anon22 +optlen gtdev-apphdr.h /^ ULONG optlen;$/;" m struct:SAppHdr +pFrame gtdev-apphdr.h /^typedef ULONG pFrame;$/;" t +pFrame gtdev-apphdr.h 14;" d +pad workspace.h /^ char pad[32];$/;" m union:__anon24 +pair edit.h 557;" d +pair edit.h 559;" d +pair edit.h 560;" d +pair edit.h 562;" d +pair edit.h 597;" d +pair edit.h 599;" d +pair edit.h 600;" d +pair edit.h 602;" d +pair gtdev-apphdr.h /^ OO_Attr pair[65000];$/;" m union:SFrame::__anon14 +par1 edit.h /^unsigned int par1=0,par2=0,cwpos=0;$/;" v +par2 edit.h /^unsigned int par1=0,par2=0,cwpos=0;$/;" v +parent gtdev-apphdr.h /^ pFrame parent;$/;" m struct:SFrameHdr +parword edit.h /^char *msg=0,curword[MAX_CURWORD+1]={0},parword[MAX_CURWORD+1]={0};$/;" v +pch_help edit.h /^ char *pch_help(char *p,char *p0) {$/;" f +pch_read pchutil.h /^char *pch_read(char *p,char *p0,PCHREAD_CB cb,char *cbparam) {$/;" f +pch_search edit.h /^char *pch_search(char *curword,int ac_test,int MM,char **match) { \/* match may be NULL if ac_test is 0 *\/$/;" f +pch_unpack editui.h /^ char *pch_unpack(char *p,char *p0) {$/;" f +pch_unpack2 editui.h /^ char *pch_unpack2(char *p,char *p0) {$/;" f +pchdata edit.h /^char *pchdata[MAX_OPEN_PCH];$/;" v +pchfile edit.h /^FILE *pchfile[MAX_OPEN_PCH];$/;" v +pchhead edit.h 323;" d +pchhead edit.h 324;" d +pchnum edit.h /^int pchnum = 0;$/;" v +physical_to_virtual display.h /^int physical_to_virtual(int px) {$/;" f +physical_to_virtual display.h 8;" d +prettyname workspace.h /^ char prettyname[32];$/;" m struct:__anon25 +prev gtdev-apphdr.h /^ AppID prev;$/;" m struct:SACB +progr_cb plugins.h /^void CALLBACK progr_cb(char *func,char *file,unsigned int fprogress) {$/;" f +prototype gtdev-apphdr.h /^ pFrame prototype;$/;" m struct:SFrameHdr +publicstorage gtdev-apphdr.h /^ ULONG publicstorage;$/;" m struct:SACB +q89 main.c 35;" d file: +q89 main.c 41;" d file: +repeated editui.h /^int repeated=0; \/\/ was the last key repeated?$/;" v +s axplore.h /^ XP_S *s;$/;" m struct:__anon2 +sUnpack sunpack.c /^char *sUnpack(char *in,char *out,char *dic) {$/;" f +sUnpackBuf main.c /^char sUnpackBuf[500];$/;" v +scr editui.h /^ SCROLL scr;$/;" m struct:__anon9 +scr util.h /^ int sel,scr,h,n;$/;" m struct:__anon20 +scr_sptr display.h /^LCD_BUFFER *scr_stk[8],**scr_sptr=0;$/;" v +scr_stk display.h /^LCD_BUFFER *scr_stk[8],**scr_sptr=0;$/;" v +search edit.h 454;" d +search edit.h 494;" d +search_attr dialogs.h /^int search_attr=0;$/;" v +search_attr workspace.h /^ int search_attr;$/;" m struct:__anon25 +search_coord dialogs.h /^int search_coord=0;$/;" v +sel axplore.h /^ int sh,sel,msel;$/;" m struct:__anon2 +sel util.h /^ int sel,scr,h,n;$/;" m struct:__anon20 +sel1 edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +sel2 edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +sel_del edit.h /^void sel_del() {$/;" f +selpos edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +set_font display.h /^void set_font(int font) {$/;" f +sh axplore.h /^ int sh,sel,msel;$/;" m struct:__anon2 +size edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +small_font display.h /^int small_font = -1;$/;" v +spos edit.h /^unsigned int spos=0,cpos=0,curpos=0,selpos=0,sel1=0,sel2=0,size=0,hsize=0\/*,is_nl=0*\/;$/;" v +ssort edit.h /^void ssort(char **match,int n) {$/;" f +strcmpindiff editui.h /^int strcmpindiff(char *a,char *b) {$/;" f +strtolower util.h /^void strtolower(char *s) {$/;" f +sz editui.h /^ int sz;$/;" m struct:__anon9 +t axplore.h /^ int i,t;$/;" m struct:__anon1 +tHandle textedit.h /^int tHandle(int key) {$/;" f +tab_chk edit.h /^int tab_chk(unsigned int pos) {$/;" f +tab_chk_l edit.h 23;" d +tab_chk_l edit.h 52;" d +tab_chk_r edit.h 24;" d +tab_chk_r edit.h 53;" d +temp_wsp workspace.h /^char temp_wsp[sizeof(WSP)+WSP_MAX_ITEMS*sizeof(WITEM)];$/;" v +text_enclose edit.h /^void text_enclose(char *l,char *r) {$/;" f +text_find dialogs.h /^char text_find[SDLG_BUF_SIZE],text_repl[SDLG_BUF_SIZE];$/;" v +text_repl dialogs.h /^char text_find[SDLG_BUF_SIZE],text_repl[SDLG_BUF_SIZE];$/;" v +title workspace.h /^ char title[24];$/;" m struct:__anon23 +toindiff editui.h 357;" d +tptr edit.h /^char *tptr=0; HANDLE hd=0;$/;" v +type workspace.h /^ int type; \/\/ =WI_FILE$/;" m struct:__anon22 +type workspace.h /^ int type; \/\/ =WI_FOLD$/;" m struct:__anon23 +type workspace.h /^ int type;$/;" m struct:__anon25 +type workspace.h /^ int type;$/;" m union:__anon24 +up edit.h /^unsigned int up(unsigned int pos,int xd) {$/;" f +updEditLine editui.h /^void updEditLine(EDIT_LINE *e) { \/* to be called when buffer content changes *\/$/;" f +valid edit.h 160;" d +value gtdev-apphdr.h /^ void *value[65000];$/;" m union:SFrame::__anon14 +value gtdev-apphdr.h /^ void *value;$/;" m struct:__anon13 +view_cursor edit.h /^void view_cursor() {$/;" f +virtual_char_width display.h /^int virtual_char_width = 0;$/;" v +virtual_char_width display.h 6;" d +virtual_to_physical display.h /^int virtual_to_physical(int vx) {$/;" f +virtual_to_physical display.h 9;" d +w editui.h /^ int x0,y,w;$/;" m struct:__anon9 +whitespace edit.h /^int whitespace(unsigned int pos,unsigned int maxpos) {$/;" f +win editui.h /^ WIN_RECT win;$/;" m struct:__anon9 +write_until pchutil.h /^char *write_until(char *d,char **s,char c) {$/;" f +wsp workspace.h /^WSP *wsp=0;$/;" v +wzChoice dialogs.h /^int wzChoice(char *prompt,char **choice,int choicen,int *dest) {$/;" f +wzChoiceDeflt dialogs.h /^int wzChoiceDeflt(char *prompt,char **choice,int choicen,int *dest,int v) {$/;" f +wzDone dialogs.h /^void wzDone(char *text) {$/;" f +wzErr dialogs.h 233;" d +wzList dialogs.h 232;" d +wzStart dialogs.h /^void wzStart(char *title,char *numSteps) {$/;" f +wzStep dialogs.h 154;" d +wzStepPtr dialogs.h /^char *wzStepPtr=0;$/;" v +wzSuccess dialogs.h /^int wzSuccess=0;$/;" v +wzText dialogs.h /^int wzText(char *prompt,char *dest,int n) {$/;" f +wzTextClr dialogs.h /^int wzTextClr(char *prompt,char *dest,int n) {$/;" f +wzTitle dialogs.h /^char wzTitle[40];$/;" v +x0 editui.h /^ int x0,y,w;$/;" m struct:__anon9 +xcur edit.h /^int xcur=0\/*,ycur=0*\/;$/;" v +xps_sel axplore.h 137;" d +xregparm display.h 39;" d +xregparm display.h 44;" d +y editui.h /^ int x0,y,w;$/;" m struct:__anon9 +ycur display.h /^int ycur=0;$/;" v +zeros gtdev-apphdr.h /^ BYTE zeros[24];$/;" m struct:SAppHdr diff --git a/ti68k/ide/textedit.h b/ti68k/ide/textedit.h new file mode 100644 index 0000000..272f2e7 --- /dev/null +++ b/ti68k/ide/textedit.h @@ -0,0 +1,132 @@ +// Text editing handler +typedef int (*HANDLER)(int); +HANDLER handler=0; +int EDH_proc=0; +int tHandle(int key) { + int *kp=get_keylist(); + /* UP/DOWN mode=0/2nd/Shift */ + if (key==*kp++) { if (ac_on) ScrollUp(&ac_s); else cpos=up(curpos,xcur),tab_chk_r(cpos),selpos=0; } + else if (key==*kp++) { if (ac_on)ScrollDn(&ac_s);else cpos=down(curpos,xcur),tab_chk_r(cpos),selpos=0; } + else if (key==*kp++) { + n=NLINES; cpos=curpos; while (n--) cpos=up(cpos,xcur); + tab_chk_l(cpos); selpos=0; + } else if (key==*kp++) { + n=NLINES; cpos=curpos; while (n--) cpos=down(cpos,xcur); + tab_chk_l(cpos); selpos=0; + } else if (key==*kp++) selpos=up(curpos,xcur),tab_chk_r(selpos); + else if (key==*kp++) selpos=down(curpos,xcur),tab_chk_r(selpos); + /* LEFT/RIGHT mode=0/2nd/Shift */ + else if (key==*kp++) { + if (sel1) cpos=sel1, selpos=0; + else if (curpos>1) { + cpos=curpos; + cpos--; if (tptr[cpos-1]==NEWLINE) cpos--; + selpos=0; tab_chk_l(cpos); + } + } else if (key==*kp++) { + if (sel2) cpos=sel2; + else if (cpos1 && tptr[cpos-2]!=NEWLINE) cpos--; selpos=0; + } else if (key==*kp++) { + cpos=curpos; while (tptr[cpos] && tptr[cpos]!=NEWLINE) cpos++; selpos=0; + } else if (key==*kp++) { if (curpos>1) { + selpos=curpos; selpos--; if (tptr[selpos-1]==NEWLINE) selpos--; tab_chk_l(selpos); + } } else if (key==*kp++) { if (curpos1) { + int n=tptr[cpos-2]==NEWLINE?2:1; + memmove(tptr+cpos-n,tptr+cpos,size+1+1-cpos); + size-=n; cpos-=n; + } + } + } else if ((k=0,key==*kp++) || (k=1,key==*kp++)) { /* CUT/COPY */ + if (sel1!=sel2) { + CB_replaceTEXT(tptr+sel1,sel2-sel1,0); + if (!k) sel_del(); + } + } else if (key==*kp++) { /* PASTE */ + HANDLE hd; long len; + if (CB_fetchTEXT(&hd,&len)) + sel_del(), insert((unsigned short)len), + memcpy(tptr+(cpos-(unsigned short)len),HeapDeref(hd),(unsigned short)len); // multitask-unsafe ! + } else if (key==KEY_ENTER) { + int n; unsigned int dpos=0; + if (ac_on) ac_do(); + sel_del(); + n=whitespace(cpos,cpos); + if (tptr[cpos-1]=='{') { + if (whitespace(cpos+2,-1)<=n) { + int i=n+2; + insert(2+i), tptr[cpos-i-2]=NEWLINE; + do tptr[cpos-i-1]=' '; while (i--); + dpos=cpos; + } else n+=2; + } + insert(2+n), tptr[cpos-n-2]=NEWLINE; + do tptr[cpos-n-1]=' '; while (n--); + if (dpos) cpos=dpos; + } else if (key>=14 && key<=255) { + if (!isidch(key) && ac_on) ac_do(); + sel_del(), insert(1), tptr[cpos-1]=key; + } else if (key!=KEY_ESC && !EDH_proc && (key&0xFFF0)!=0x0150 /* arrow keys [they seem to bug] */) { + int k2=0; + void EVh(EVENT *ev) { + if (ev->Type==CM_KEYPRESS) k2=ev->extra.Key.Code+1; + else if (ev->Type==CM_STRING) { + char *p=ev->extra.pasteText; int n; + sel_del(), insert(n=strlen(p)), memcpy(tptr+cpos-n,p,n); + } + ER_throwVar(1); + } + EVENT e; + while ((k=*kp++)) if (key==k) goto keydone; + e.Type=CM_KEYPRESS; + e.extra.Key.Code=key; + // e.extra.Key.Mod =key&0xF000; + EV_captureEvents((EVENT_HANDLER)EVh); + PortRestore(); + TRY + EV_defaultHandler(&e); + ONERR + EV_captureEvents(NULL); + ENDTRY + PortSet(Port,239,127); + EDH_proc=1; + return handler(k2); + } else return 0; + keydone: + return 1; +} +int dHandle(int key) { + } else if (k==KEY_ON && key!=k) { + if (key&4096) key=KEY_ESC; + Off(); +} + + } else if (key==KEY_CLEAR) { + int n; + if (ac_on) ac_do(); + sel_del(), insert(n=even(cpos)+1), tptr[cpos-n]=' ', tptr[cpos-1]=' '; + } else if (key=='(' || key=='[' || key=='{') { + int x=key=='('?0:(key=='['?1:2); + if (ac_on) ac_do(); + text_enclose(((char *[]){"(","[","{"})[x],((char *[]){")","]","}"})[x]); + } else if ((k=key&~(32|4096|8192|16384))=='X' || k=='Y' || k=='Z' || k=='T') { + k-='X'; if (k<0) k=3; k+=k; + if (key&4096) k++; + text_enclose(((char *[]){"if (","if (","for (","for (","while (","while ("})[k], + ((char *[]){")\n\t\n\b",") {\n\t\n\b}\n"})[k&1]); + } else if ((k=(key&*kp++))>='1' && k<='9') { /* kbdprgm# - custom shortcuts */ + + } else if (key==*kp++) { /* CATALOG */ + Catalog(); + } else if ((k=(key-KEY_F1+1))>=1 && k<=8) { /* Function key F# */ + /*if (k==1) TestDisp(); + else*/ if (k==3) FindDlg(); diff --git a/ti68k/ide/util.h b/ti68k/ide/util.h new file mode 100644 index 0000000..9432f36 --- /dev/null +++ b/ti68k/ide/util.h @@ -0,0 +1,48 @@ +typedef struct { + int sel,scr,h,n; +} SCROLL; + +#define ScrollInit(s) ((s)->sel=0,(s)->scr=0) +#define ScrollChg(s,n) ((s)->sel+=n) +#define ScrollUp(s) (--(s)->sel) +#define ScrollDn(s) (++(s)->sel) +#define ScrollHasUpArrow(s) (!!((s)->scr)) +#define ScrollHasDnArrow(s) ((s)->scr+(s)->h<(s)->n) +void ScrollUpd(SCROLL *s) { + int n=s->n; + while (s->sel<0) s->sel+=n; + while (s->sel>=n) s->sel-=n; + /* Now s->sel is OK, let's update s->scr */ + if (s->selscr) s->scr=s->sel; + if (s->sel>=s->scr+s->h) s->scr=s->sel-s->h+1; +} +void ScrollUpdNoWrap(SCROLL *s) { /* same as ScrollUpd, but doesn't wrap */ + int n=s->n; + if (s->sel<0) s->sel=0; + if (s->sel>=n) s->sel=n-1; + /* Now s->sel is OK, let's update s->scr */ + if (s->selscr) s->scr=s->sel; + if (s->sel>=s->scr+s->h) s->scr=s->sel-s->h+1; +} +void ScrollUpdNoWrapDots(SCROLL *s) { /* same as ScrollUpdNoWrap, but leaves 1 blank on the border */ + int n=s->n; + if (s->sel>=n) s->sel=n-1; + if (s->sel<0) s->sel=0; + /* Now s->sel is OK, let's update s->scr */ + if (s->sel-1scr) s->scr=s->sel-1; + if (s->sel+1>=s->scr+s->h) s->scr=s->sel+1-s->h+1; + while (s->scr+s->h>=n) s->scr--; + if (s->scr<0) s->scr=0; // this is what happens if s->h==s->n +} + +void ScrollChgWrapOnlyAtEnd(SCROLL *s,int d) { + /* likes ScrollChg, but prevents selection from wrapping if cursor was not at end */ + int n=s->n,sel2=s->sel+d; + if (sel2<0) { if (s->sel>0) sel2=0; else sel2=-1; } + else if (sel2>=n) { if (s->selsel=sel2; +} + +void strtolower(char *s) { + while (*s) *s=tolower(*s),s++; +} diff --git a/ti68k/ide/workspace.h b/ti68k/ide/workspace.h new file mode 100644 index 0000000..f7a36c6 --- /dev/null +++ b/ti68k/ide/workspace.h @@ -0,0 +1,179 @@ +// Workspace management routines + +typedef char FILENAME[8+1+8+1]; +enum { WI_FOLD=0, WI_FILE }; +typedef struct { + int type; // =WI_FILE + FILENAME name; + int open; + HANDLE openhd; +} WFILE; +#define NUM_DEFLTTYPE 2 +typedef struct { + int type; // =WI_FOLD + char title[24]; + int deflttype[NUM_DEFLTTYPE]; + int expanded; +} WFOLD; +typedef union { + int type; + WFILE f; + WFOLD d; + char pad[32]; +} WITEM; +typedef struct { + // General info + char prettyname[32]; + char iname[8+1]; + char foldname[8+1]; + int type; + int loaded; + // Settings + int search_attr; + + // Content + int nitems; + WITEM items[0]; +} WSP; +enum { WSPT_SIMPLE=0, WSPT_GAME=1, WSPT_UTIL=2, WSPT_OTHER=3 }; + +#define WSP_MAX_ITEMS 32 +WSP *wsp=0; +char temp_wsp[sizeof(WSP)+WSP_MAX_ITEMS*sizeof(WITEM)]; + +#include "Files.h" + +void WspPromptSave(); +int WspAddFold(char *fold); +void WspNew() { + WSP this_w,*w=&this_w; + WspPromptSave(); + memset(w,0,sizeof(WSP)); + wzStart("New project","3"); + while (wzTextClr("Project name:",w->prettyname,31)) +// while (wzTextClr("Project internal name:",w->iname,8)) + while (wzTextClr("Project folder:",w->foldname,8)) { + if (!ValidateSymName(w->foldname)) wzErr("Please enter a valid folder name"); + strtolower(w->foldname); + while (wzChoiceDeflt("Project type:", + wzList("Simple program","Game","Utility","Other"),&w->type,WSPT_SIMPLE)) { + wzDone("Your project is now created. " + "The project browser (accessible through 2ND-[VAR-LINK]) will now be opened for you."); + strcpy(w->iname,"project"); + w->loaded=0; + *(WSP *)temp_wsp=*w; + wsp=(WSP *)temp_wsp; + WspAddFold("Default"); + return; + } + } +} +void WspShowBrowser(); +void WspSave() { + WSP *w=wsp; + char tn[20]; + strcpy(tn,w->foldname); + strcat(tn,"\\"); + strcat(tn,w->iname); + SYM_STR sym=SYMSTR(tn); + EM_moveSymFromExtMem(tn,HS_NULL); + rename(tn,"_wsptemp"); + SYM_STR foldss=SYMSTR(w->foldname); + if (!SymFindHome(foldss).folder) FolderAdd(foldss); + FILE *fp=fopen(tn,"wb"); + fwrite(w,sizeof(WSP)+w->nitems*sizeof(WITEM),1,fp); + fwrite((char[]){0,'W','S','P',0,OTH_TAG},1,6,fp); + if (ferror(fp)) { + fclose(fp); + unlink(tn); + rename("_wsptemp",tn); + EM_moveSymToExtMem(tn,HS_NULL); + SimpleDlg("Save project","Error : the project could not be saved.",B_CENTER,W_NORMAL|ICO_WARN); + return; + } + fclose(fp); + unlink("_wsptemp"); + if (!EM_moveSymToExtMem(tn,HS_NULL)) + SimpleDlg("Save project", + "Warning : the project could not be archived. Please go to the [VAR-LINK] " + "window, delete the files you don't need, and archive it.",B_CENTER,W_NORMAL|ICO_WARN); + WspShowBrowser(); +} +void WspPromptSave() { + if (wsp) { + if (YesNoDlg("GT-Dev","Save the current project?")) + WspSave(); + } +} + +int WspFindNearItem(char *wi_name,int wi_type,int i) { + int n=wsp->nitems-i; + WITEM *wip=wsp->items+i; + while (n--) { + if (wip->typetype==wi_type && strcmp(wip->f.name,wi_name)>=0) return i; + i++; wip++; + } + return i; +} +int WspFindItem(char *wi_name,int wi_type,int i) { + int j=WspFindNearItem(wi_name,wi_type,i); + if (jnitems && wsp->items[j].type==wi_type && !strcmp(wsp->items[j].f.name,wi_name)) + return j; + return -1; +} +WITEM *WspAddItem(int i) { + if (wsp->nitems>=WSP_MAX_ITEMS) return NULL; + WITEM *wi=wsp->items+i; + memmove(wi+1,wi,(wsp->nitems-i)*sizeof(WITEM)); + wsp->nitems++; + memset(wi,0,sizeof(WITEM)); + return wi; +} +int WspAddFile(char *file,char *dfold) { + int i=WspFindItem(dfold,WI_FOLD,0); + if (i<0) return 0; + WFILE *wf=&(WspAddItem(WspFindNearItem(file,WI_FILE,i+1))->f); + if (!wf) return 0; + wf->type=WI_FILE; + strcpy(wf->name,file); + // everything else is set to 0 :) + return 1; +} +int WspAddFold(char *fold) { +// asm("0:bra 0b"); + WFOLD *wd=&(WspAddItem(WspFindNearItem(fold,WI_FOLD,0))->d); + if (!wd) return 0; + wd->type=WI_FOLD; + strcpy(wd->title,fold); + // everything else is set to 0 :) + return 1; +} + +DEFINE_XPLOOP_CB(callback) { + if (!key) { + char *Menu[5]={"Help","New"DOTS,"Import\xA0","Rename","Setup"}; + if (xc->s[xc->sel].i==1) Menu[4]=NULL; + MenuContents=Menu; + return XPLCB_CONT; + } else if (key==KEY_F1) { + return XPLCB_BREAK; + } + return XPLCB_CONT; +} +void WspShowBrowser() { + int h=8; + WIN_RECT win; + XP_C *xc=XpLoadItems(0); + PushScr(); + dialog("Project browser",120,h+XP_H*XP_N,B_CENTER|B_ROUNDED,&win); + DStr(win.x0>>2,win.y0,"Project view :"); + xc->sel=0; + XP_S *xs; + if ((xs=XpLoop(xc,win.y0+h,callback,NULL))) { + + } + PopScr(); + free(xc); + MenuContents=NULL; +} diff --git a/ti68k/mkinfo-89-flashapp b/ti68k/mkinfo-89-flashapp new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-89-h b/ti68k/mkinfo-89-h new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-89-ide b/ti68k/mkinfo-89-ide new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-89-pch b/ti68k/mkinfo-89-pch new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-92p-flashapp b/ti68k/mkinfo-92p-flashapp new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-92p-h b/ti68k/mkinfo-92p-h new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-92p-ide b/ti68k/mkinfo-92p-ide new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-92p-pch b/ti68k/mkinfo-92p-pch new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-v200-flashapp b/ti68k/mkinfo-v200-flashapp new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-v200-h b/ti68k/mkinfo-v200-h new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-v200-ide b/ti68k/mkinfo-v200-ide new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/mkinfo-v200-pch b/ti68k/mkinfo-v200-pch new file mode 100644 index 0000000..e69de29 diff --git a/ti68k/srcdata/flashapp/gtc-89.89k b/ti68k/srcdata/flashapp/gtc-89.89k new file mode 100644 index 0000000000000000000000000000000000000000..b3d9a9e6a34b0fe51d8a54b2e323ca2fd998d3d6 GIT binary patch literal 109161 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≫z=suam-ei!#SVnTt$0{3@4;*e1<6B}H^_Zp1!; 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 literal 0 HcmV?d00001 diff --git a/ti68k/srcdata/flashapp/gtc-92p.9xk b/ti68k/srcdata/flashapp/gtc-92p.9xk new file mode 100644 index 0000000000000000000000000000000000000000..fca265c817ffbc614345779834e158a798fb2b30 GIT binary patch literal 109161 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 literal 0 HcmV?d00001 diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..86944c4 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,8 @@ +all: all-obj2ti all-pchmaker all-dat89y all-txt89t +all-%: + $(MAKE) -C $(patsubst all-%,%,$@) all +clean distclean scratchclean: + $(MAKE) -C obj2ti $@ + $(MAKE) -C pchmaker $@ + $(MAKE) -C dat89y $@ + $(MAKE) -C txt89t $@ diff --git a/tools/dat89y/Makefile b/tools/dat89y/Makefile new file mode 100644 index 0000000..42f1c31 --- /dev/null +++ b/tools/dat89y/Makefile @@ -0,0 +1,14 @@ +include ../../common.mk +CFLAGS = $(DEFAULT_CFLAGS) + +SRC = dat89y.c bin2calc.c + +all: dat89y + +dat89y: $(SRC) + $(CC) $(CFLAGS) $(SRC) -o $@ + +include ../../platform.mk +clean: +distclean scratchclean: + $(RM) dat89y$(BIN_SUFFIX) diff --git a/tools/dat89y/bin2calc.c b/tools/dat89y/bin2calc.c new file mode 100644 index 0000000..d3b56e1 --- /dev/null +++ b/tools/dat89y/bin2calc.c @@ -0,0 +1,85 @@ +#include +#include +#include + +// This structure comes from ttools. +typedef struct { + char signature[8]; // "**TI92P*" or "**TI89**" + unsigned char fill1[2]; // 01 00 + char folder[8]; // folder name + char desc[40]; // ---- not used ---- + unsigned char fill2[6]; // 01 00 52 00 00 00 + char name[8]; // varname + unsigned char type[4]; // 0C 00 00 00 + unsigned char size[4]; // complete file size (including checksum) + unsigned char fill3[6]; // A5 5A 00 00 00 00 + unsigned char datasize[2]; // data size +} TI_FILE_HDR; + + +static void put_little_endian(unsigned char *dest, unsigned long val, int len) { + while (len--) { + *dest++ = (unsigned char)(val&0xFF); + val >>= 8; + } +} +static void put_big_endian(unsigned char *dest, unsigned long val, int len) { + dest += len; + while (len--) { + *--dest = (unsigned char)(val&0xFF); + val >>= 8; + } +} + +char *create_ti_file(int calc,int tigl_type,char *name,char *folder,char *content,unsigned long content_size,unsigned long *ti_file_size) { + TI_FILE_HDR h; + memset(&h, 0, sizeof h); + memcpy(h.signature, "********", 8); +#define sig(x) memcpy(h.signature+2,x,sizeof(x)-1) + switch (calc) { + case 0: + sig("TI89"); + break; + case 1: + sig("TI92P"); + break; + case 2: + sig("TI92P"); + break; + default: + fatal("unknown calc type"); + } +#undef sig + h.fill1[0] = 1; + strncpy(h.folder, folder?folder:"main", 8); + h.fill2[0] = 1; h.fill2[2] = 0x52; + strncpy(h.name, name, 8); + h.type[0] = tigl_type; h.type[2] = 3; + h.fill3[0] = 0xA5; h.fill3[1] = 0x5A; + { + unsigned long oncalc_size = 88+content_size+2; + put_little_endian(h.size, oncalc_size, 4); + } + put_big_endian(h.datasize, content_size, 2); + + if (content_size>=65520) + fatal("TIOS variables can't be more than 65520 bytes long."); + + { + char *ret = malloc(sizeof(h)+content_size+2); + if (!ret) + fatal("Memory"); + if (ti_file_size) + *ti_file_size = sizeof(h)+content_size+2; + memcpy(ret, &h, sizeof(h)); + memcpy(ret+sizeof(h), content, content_size); + { + unsigned int crc = h.datasize[0]+h.datasize[1]; + unsigned long n = content_size; + while (n--) + crc += 0xff & (unsigned char)*content++; + put_little_endian(ret+sizeof(h)+content_size, crc, 2); + } + return ret; + } +} diff --git a/tools/dat89y/dat89y.c b/tools/dat89y/dat89y.c new file mode 100644 index 0000000..cf3bd24 --- /dev/null +++ b/tools/dat89y/dat89y.c @@ -0,0 +1,104 @@ +#include +#include +#include + +void fatal(char *s) { + fprintf(stderr,"error: %s\n"); + exit(123); +} +char *create_ti_file(int calc,int tigl_type,char *name,char *folder,char *content,unsigned long content_size,unsigned long *ti_file_size); + +char *rightest_of(char *s,char c) { + char *t=strrchr(s,c); + if (t) return t+1; + return s; +} +char *leftest_end_of(char *s,char c) { + char *t=strchr(s,c); + if (t) return t; + return s+strlen(s); +} + +int main(int argc,char **argv) { + char *folder=NULL,*extension=NULL; + char **p=argv+1; + int n=argc-1; + while (n && **p=='-') { + if (!strcmp(*p,"-f")) { + folder=p[1]; + n-=2,p+=2; + continue; + } + if (!strcmp(*p,"-e")) { + extension=p[1]; + n-=2,p+=2; + continue; + } + fprintf(stderr,"unknown option\n"); + return 2; + } + if (!n) { + fprintf(stderr,"usage: dat89y [-f ] [-e ] ... \n"); + return 1; + } + if (!extension) + extension = "OTH"; + while (n--) { + char *filename=*p++; + char *basename=rightest_of(rightest_of(filename,'\\'),'/'); + char *rootname_end=leftest_end_of(basename,'.'); + char *rootname=malloc(rootname_end-basename+4+1); + int i; + memcpy(rootname,basename,rootname_end-basename); + rootname[rootname_end-basename]=0; + for (i=0;i=0) + len++; + fseek(fp,0,SEEK_SET); + dp=dat=malloc(len); + while (1) { + int v=getc(fp); + if (v<0) + break; + *dp++=(c=v); + } + *dp++=0; + { + int i; + for (i=0;extension[i];i++) + *dp++=extension[i]; + } + *dp++=0; + *dp=0xF8; + fclose(fp); + outdat=create_ti_file(0,0x0C,rootname,folder,dat,len,&outlen); + free(dat); + memcpy(rootname,basename,strlen(rootname)); + strcat(rootname,".89y"); + fp=fopen(rootname,"wb"); + if (!fp) { + fprintf(stderr,"can't write file!\n"); + return 3; + } + fwrite(outdat,1,outlen,fp); + fclose(fp); + free(outdat); + } + free(rootname); + } + return 0; +} diff --git a/tools/obj2ti/Makefile b/tools/obj2ti/Makefile new file mode 100644 index 0000000..7430236 --- /dev/null +++ b/tools/obj2ti/Makefile @@ -0,0 +1,12 @@ +include ../../common.mk +CXXFLAGS = $(DEFAULT_CFLAGS) + +all: obj2ti + +obj2ti: obj2ti.cpp + $(CXX) $(CXXFLAGS) $< -o $@ + +include ../../platform.mk +clean: +distclean scratchclean: + $(RM) obj2ti$(BIN_SUFFIX) diff --git a/tools/obj2ti/m68kdefs.h b/tools/obj2ti/m68kdefs.h new file mode 100644 index 0000000..59d709a --- /dev/null +++ b/tools/obj2ti/m68kdefs.h @@ -0,0 +1,43 @@ +typedef struct { + char f_magic[2]; + char f_nscns[2]; // # of sections + char f_timdat[4]; // timestamp + char f_symptr[4]; // ptr to symtab + char f_nsyms[4]; // # of symtab entries + char f_opthdr[2]; // optional header size + char f_flags[2]; +} FILHDR; + +typedef struct { + char s_name[8]; + char s_paddr[4]; + char s_vaddr[4]; + char s_size[4]; + char s_scnptr[4]; + char s_relptr[4]; + char s_lnnoptr[4]; + char s_nreloc[2]; + char s_nlnno[2]; + char s_flags[4]; +} SCNHDR; + +typedef struct { + union { + char e_name[8]; + struct { + char e_zeroes[4]; + char e_offset[4]; + } e; + } e; + char e_value[4]; + char e_scnum[2]; + char e_type[2]; + char e_sclass[1]; + char e_numaux[1]; +} SYMENT; + +typedef struct { + char r_vaddr[4]; + char r_symndx[4]; + char r_type[2]; +} RELOC; diff --git a/tools/obj2ti/obj2ti.cpp b/tools/obj2ti/obj2ti.cpp new file mode 100644 index 0000000..6516c57 --- /dev/null +++ b/tools/obj2ti/obj2ti.cpp @@ -0,0 +1,1244 @@ +// Written by Julien Muchembled. +// Fixed by Romain Lievin for Linux. +// Further modifications by Sebastian Reichelt, Kevin Kofler and Paul Froissart. +// Copyright (c) 2001-2002. All rights reserved. + +// default: don't include AmigaOS support +//#define SUPPORT_AMIGA +// This needs to be defined BEFORE including obj2ti.h, since it is used in +// that header. + +#include "obj2ti.h" + +// default: don't print out extra debugging information +//#define TEXT_DEBUG + +#ifdef TEXT_DEBUG +# define DEBUG_PRINT(str...) (printf (str)) +#else +# define DEBUG_PRINT(str...) +#endif + +// default: catch symbols with unknown class +#define CHECK_SYMBOLS + +#define MAX_VAR_SIZE 65517 + +__inline unsigned short br2 (void *pp) +{ + unsigned char *p = (unsigned char *) pp; + return ((unsigned short) p[0] << 8) + (unsigned short) p[1]; +} +__inline unsigned long br4 (void *pp) +{ + unsigned char *p = (unsigned char *) pp; + return ((unsigned long) p[0] << 24) + ((unsigned long) p[1] << 16) + + ((unsigned long) p[2] << 8) + (unsigned long) p[3]; +} +__inline void bw2 (void *pp, unsigned short w) +{ + unsigned char *p = (unsigned char *) pp; + *p++ = (unsigned char)(w>>8); + *p = (unsigned char) w; +} +__inline void bw4 (void *pp, unsigned long dw) +{ + unsigned char *p = (unsigned char *) pp; + *p++ = (unsigned char)(dw>>24); + *p++ = (unsigned char)(dw>>16); + *p++ = (unsigned char)(dw>>8); + *p = (unsigned char) dw; +} +__inline void ba4 (void *p, unsigned long dw) +{ bw4 (p, br4 (p) + dw); } + +__inline unsigned short lr2 (void *pp) +{ + unsigned char *p = (unsigned char *) pp; + return (unsigned short) p[0] + ((unsigned short) p[1] << 8); +} +__inline unsigned long lr4 (void *pp) +{ + unsigned char *p = (unsigned char *) pp; + return (unsigned long) p[0] + ((unsigned long) p[1] << 8) + + ((unsigned long) p[2] << 16) + ((unsigned long) p[3] << 24); +} +__inline void lw2 (void *pp, unsigned short w) +{ + unsigned char *p = (unsigned char *) pp; + *p++ = (unsigned char) w; + *p = (unsigned char)(w>>8); +} +__inline void lw4 (void *pp, unsigned long dw) +{ + unsigned char *p = (unsigned char *) pp; + *p++ = (unsigned char) dw; + *p++ = (unsigned char)(dw>>=8); + *p++ = (unsigned char)(dw>>=8); + *p = (unsigned char)(dw>>8); +} +__inline void la4 (void *p, unsigned long dw) +{ lw4 (p, lr4 (p) + dw); } + +void Object::AllocExt (int CurHunk, Import **Imp16, Import **Imp32, Export **Exports) +{ + if (Hunk[CurHunk].nImp16) + *Imp16 = Hunk[CurHunk].Imp16 = new Import[Hunk[CurHunk].nImp16]; + if (Hunk[CurHunk].nImp32) + *Imp32 = Hunk[CurHunk].Imp32 = new Import[Hunk[CurHunk].nImp32]; + if (Hunk[CurHunk].nExports) + *Exports = Hunk[CurHunk].Exports = new Export[Hunk[CurHunk].nExports]; +} + +#ifdef SUPPORT_AMIGA +ObjErr Object::ReadAmiga () +{ + int CurHunk=-1; unsigned long *am = o32, size, *Ext[3]={NULL,NULL,NULL}; + + bBadExport = true; + + for (size=Size>>2; size>0; size--) { + DWORD n, HunkType = br4(am++); + n = br4 (am); + switch (HunkType) { + default: return OBJERR_HunkType; + case HunkUnit: + case HunkName: + case HunkDbg: + size -= ++n; am += n; + case HunkEnd: break; + case HunkCode: + if (CodeHunk >= 0) return OBJERR_NbScns; + else { + CodeHunk = ++CurHunk; + Hunk[CurHunk].size = n << 2; + Hunk[CurHunk].o32 = ++am; + am += n; size -= n+1; + } break; + case HunkData: + if (DataHunk >= 0) return OBJERR_NbScns; + else { + DataHunk = ++CurHunk; + Hunk[CurHunk].size = n << 2; + Hunk[CurHunk].o32 = ++am; + am += n; size -= n+1; + } break; + case HunkBSS: + if (BSSHunk >= 0) return OBJERR_NbScns; + else Hunk[BSSHunk = ++CurHunk].size = n << 2, am++, size--; + break; + case HunkR16: + fprintf (stderr, "Warning: 16-bit relocations are unsupported.\n"); + for (; size>0 && n; n=br4 (am)) + n += 2, am += n, size -= n; + am++; size--; break; + case HunkR32: + if (CurHunk < 0) return OBJERR_R32Hunk; + else { + for (; size>0 && n; n=br4 (am)) { + DWORD k = br4 (++am); + if (k < 3 && !Hunk[CurHunk].R32[k]) { + unsigned long *R32; + Hunk[CurHunk].nR32[k] = n; + Hunk[CurHunk].R32[k] = R32 = new unsigned long [n]; + for (am++; n--; size--) *R32++ = br4 (am++); + size -= 2; + } else return OBJERR_R32Hunk; + } am++; size--; + } break; + case HunkExt: + if (CurHunk < 0 || Ext[CurHunk]) return OBJERR_ExtHunk; + else { + unsigned char type; unsigned long nExtRefs=0, nImports=0; + Ext[CurHunk] = am; + do { + n = (br4 (am) & 0xFFFFFF) + 1; + switch (type = *(unsigned char *)am++) { + default: return OBJERR_ExtType; + case TypeEnd: break; + case TypeImport32: + Hunk[CurHunk].nImp32++; + case TypeImport16: + case TypeImport16Alt: + am += n; size -= n; + n = br4 (am-1); + nImports++; + case TypeExport: + am += n; size -= n; nExtRefs++; + } } while (size-- > 0 && type != TypeEnd); + if (!nExtRefs) Ext[CurHunk] = NULL; + else { + Hunk[CurHunk].nExports = nExtRefs - nImports; + Hunk[CurHunk].nImp16 = nImports - Hunk[CurHunk].nImp32; + } } } } + + if (size) return OBJERR_Size; + if (CurHunk < 0) return OBJERR_NbScns; + + nscns = CurHunk+1; + for (CurHunk=0; (unsigned int)CurHunkname = (char *)am; + am += n; n = br4 (am++); + Imp32->nrlcs = n; + Imp32->rlc = rlc = new unsigned long [n]; + while (n--) *rlc++ = br4 (am++); + Imp32++; + break; + case TypeImport16: + case TypeImport16Alt: + Imp16->name = (char *)am; + am += n; n = br4 (am++); + Imp16->nrlcs = n; + Imp16->rlc = rlc = new unsigned long [n]; + while (n--) *rlc++ = br4 (am++); + Imp16++; + break; + case TypeExport: + Exports->name = (char *)am; am += n; + //Exports->size = 0; + Exports->value = br4 (am++); + Exports++; + } } } + return OBJERR_OK; +} +#endif + +char *Object::COFF_ReadName (SYMENT *sym, char *Str) +{ + return br4 (sym->e.e.e_zeroes) ? + sym->e.e_name : + &Str[br4 (sym->e.e.e_offset)]; +} + +ObjErr Object::ReadCOFF () +{ + int CurHunk=BSSHunk=0; SCNHDR *scn = (SCNHDR *)&o8[sizeof(FILHDR)]; + RELOC *Relocs[2]; unsigned short nrlcs[2]; + unsigned long i, nSyms, s_vaddr[3]; + nscns = br2 (filhdr->f_nscns); + if (nscns < 3) return OBJERR_NbScns; + if (nscns > 3) { + fprintf (stderr, "Warning: More than 3 COFF sections. Excess sections ignored.\n"); + nscns = 3; + } + if (br2 (filhdr->f_opthdr)) return OBJERR_OptHdr; + s_vaddr[0] = 0; + + for (i=0; i= 0) return OBJERR_NbScns; + else { + Relocs[CurHunk] = (RELOC *)&o8[br4 (scn[i].s_relptr)]; + nrlcs[CurHunk] = br2 (scn[i].s_nreloc); + Hunk[CodeHunk = ++CurHunk].o8 = &o8[br4 (scn[i].s_scnptr)]; + Hunk[CurHunk].size = br4 (scn[i].s_size); + s_vaddr[CurHunk] = br4 (scn[i].s_vaddr); + } + break; + case STYP_BSS: + // This program can only work properly if the BSS section is the last + // one. + if (CurHunk != (int) nscns - 1) return OBJERR_NbScns; + else { + // Objcopy produces real BSS sections, while the GNU assembler + // simply leaves an empty section. + // Both versions will work here, since the relocs are different + // (section 0 (none) vs. section 3). + Hunk[0].size = br4 (scn[i].s_size); + // This is just a stupid number which has to be subtracted from all + // relocs. + s_vaddr[0] = br4 (scn[i].s_vaddr); + } + break; + case STYP_DATA: + if (DataHunk >= 0) return OBJERR_NbScns; + else { + Relocs[CurHunk] = (RELOC *)&o8[br4 (scn[i].s_relptr)]; + nrlcs[CurHunk] = br2 (scn[i].s_nreloc); + Hunk[DataHunk = ++CurHunk].o8 = &o8[br4 (scn[i].s_scnptr)]; + Hunk[CurHunk].size = br4 (scn[i].s_size); + s_vaddr[CurHunk] = br4 (scn[i].s_vaddr); + } + break; + } + + SYMENT *sym, *Sym = (SYMENT *)&o8[br4 (filhdr->f_symptr)]; + char *Str = (char *)&Sym[nSyms = br4 (filhdr->f_nsyms)]; + struct SYMNFO { + unsigned char ok; + unsigned char R32; + unsigned char IsBSSSymbol; + unsigned short hunk; + struct { + unsigned short n16; + unsigned short n32; + } Hunk[2]; + } *SymNfo = (SYMNFO *)_alloca (nSyms*sizeof(SYMNFO)); + unsigned long *R32[2][3]; + memset (&R32, 0, sizeof (R32)); memset (SymNfo, 0, nSyms*sizeof(SYMNFO)); + +/************************************\ +| Basic symbol and relocation info | +\************************************/ + + // Read in the symbol table and build the SymNfo table with additional + // information. + // FIXME: Imported symbols shouldn't be considered as exports as well. + for (sym=Sym,i=0; ie_sclass)), (long) (short) (br2 (sym->e_scnum)), (long) (br4 (sym->e_value))); +#ifdef CHECK_SYMBOLS + switch (br2 (sym->e_sclass)) { + // All non-standard symbols are not 'ok'. + case 0x200: + case 0x201: + case 0x300: + case 0x301: +#endif + { unsigned int hunk = br2 (sym->e_scnum); + if (hunk == nscns) { + // It is a symbol in the BSS section, as objcopy produces them. + // This program assumes that the BSS section is the last one. + // This could be greatly simplified if we assume that there is + // always just one single symbol (called '.bss') at the start of + // the BSS section. + SymNfo[i].IsBSSSymbol = 1; + SymNfo[i].R32 = 1; + ba4 (sym->e_value, (DWORD)-(long)s_vaddr[0]); + } + if (hunk >= nscns) hunk = 0; + Hunk[SymNfo[i].hunk = hunk].nExports++; + SymNfo[i].ok = 1; + } +#ifdef CHECK_SYMBOLS + } +#endif + } + + // Here the number of imports and relocations is read in. No relocation is + // actually done. + for (CurHunk=1; (unsigned int)CurHunkr_symndx); + sym = &Sym[i]; + if (SymNfo[i].ok) { + unsigned long value = br4 (sym->e_value); + DEBUG_PRINT ("Reloc %ld: Type 0x%lx; Section %ld; Address 0x%lx\n", (long) (nrlcs[CurHunk-1] - j + 1), (long) (br2 (rlc->r_type)), (long) CurHunk, (long) (long) (br4 (rlc->r_vaddr))); + DEBUG_PRINT (" Symbol %ld (%s)\n", (long) i, COFF_ReadName (sym, Str)); + switch (br2 (rlc->r_type)) { + default: + return OBJERR_RlcType; + case 0x10: + case 0x13: + DEBUG_PRINT (" 16-bit reloc\n"); + if (!value && !SymNfo[i].hunk) { + DEBUG_PRINT (" Normal reloc: Section %ld; Address 0x%lx\n", (long) SymNfo[i].hunk, (long) (br4 (sym->e_value))); + if (!SymNfo[i].Hunk[CurHunk-1].n16++) Hunk[CurHunk].nImp16++; + } + break; + case 0x11: + case 0x14: + // Warning: BSSHunk is 0. + // And 0 is also used for imported symbols, which don't have a + // section they reside in. + // Luckily however, we can decide by looking at the value: + // If it's 0, it's an import, like a ROM_CALL or RAM_CALL. + // Otherwise, we have a BSS entry. The value then marks the size + // of the entry, in bytes. + // That means we simply replace the value by an offset into the + // BSS section (plus s_vaddr, because COFF requires it). Since + // this offset can be 0 for the first symbol in the BSS section, + // we sign a special flag. + if (SymNfo[i].hunk==0) { + DEBUG_PRINT (" Symbol has section 0\n"); + DEBUG_PRINT (" Value: %ld (marked as BSS: %ld)\n", (long) value, (long) SymNfo[i].IsBSSSymbol); + if (value || SymNfo[i].IsBSSSymbol) { + DEBUG_PRINT (" Inserting reloc into BSS section (0)\n"); + Hunk[CurHunk].nR32[0]++; + if (!SymNfo[i].R32) { + unsigned long blocksize = value; + SymNfo[i].R32 = 1; + SymNfo[i].IsBSSSymbol = 1; + bw4 (sym->e_value, value = s_vaddr[0] + Hunk[0].size); + Hunk[0].size += blocksize; + DEBUG_PRINT (" New BSS size: %ld\n", (long) Hunk[0].size); + DEBUG_PRINT (" New value for symbol: %ld\n", (long) value); + } + } else { + DEBUG_PRINT (" Adding import\n"); + if (!SymNfo[i].Hunk[CurHunk-1].n32++) Hunk[CurHunk].nImp32++; + } + } else { + DEBUG_PRINT (" Normal reloc: Section %ld; Address 0x%lx\n", (long) SymNfo[i].hunk, (long) (br4 (sym->e_value))); + Hunk[CurHunk].nR32[SymNfo[i].hunk]++; + SymNfo[i].R32 = 1; + } } + } else { + fprintf (stderr, "Warning: Removing reloc to unsupported symbol '%s'.\n", COFF_ReadName (sym, Str)); + } } } + +/*****************************************************\ +| Allocation of export, import, and relocation tables | +\*****************************************************/ + + // All tables are built up using the results from the counting above. + Export *Exports[3]={NULL,NULL,NULL}; + unsigned long **Imp16rlc[3], **Imp32rlc[3]; + for (i=0; iname = COFF_ReadName (sym, Str); + Imp16->nrlcs = SymNfo[j].Hunk[i-1].n16; + Imp16->rlc = *pImp16rlc++ = new unsigned long [Imp16->nrlcs]; + Imp16++; SymNfo[j].Hunk[i-1].n16 = ++n16; + } + if (SymNfo[j].Hunk[i-1].n32) { + Imp32->name = COFF_ReadName (sym, Str); + Imp32->nrlcs = SymNfo[j].Hunk[i-1].n32; + Imp32->rlc = *pImp32rlc++ = new unsigned long [Imp32->nrlcs]; + Imp32++; SymNfo[j].Hunk[i-1].n32 = ++n32; + } } + // Allocate the relocation tables. + for (j=0; jname = COFF_ReadName (sym, Str); + Exports[SymNfo[i].hunk]->value = br4 (sym->e_value); + Exports[SymNfo[i].hunk]++; + } + + // Initialize import and relocation tables, and relocate. + for (CurHunk=1; (unsigned int)CurHunkr_symndx); + if (SymNfo[i].ok) { + int k; unsigned long ofs; + ofs = br4 (rlc->r_vaddr) - s_vaddr[CurHunk]; + switch (br2 (rlc->r_type)) { + case 0x10: + case 0x13: + if ((k = SymNfo[i].Hunk[CurHunk-1].n16)) + *Imp16rlc[CurHunk][k-1]++ = ofs; + break; + case 0x11: + case 0x14: + if (SymNfo[i].R32) { + *R32[CurHunk-1][SymNfo[i].hunk]++ = ofs; + DEBUG_PRINT ("Relocating 32 bits at offset 0x%lx in section %ld\n", (long) ofs, (long) CurHunk); + DEBUG_PRINT (" Old value: 0x%lx\n", (long) br4 (&Hunk[CurHunk].o8[ofs])); + ba4 (&Hunk[CurHunk].o8[ofs], (SymNfo[i].IsBSSSymbol ? br4 (Sym[i].e_value) : 0) + ((DWORD)-(long)s_vaddr[SymNfo[i].hunk])); + DEBUG_PRINT (" New value: 0x%lx\n", (long) br4 (&Hunk[CurHunk].o8[ofs])); + } else if ((k = SymNfo[i].Hunk[CurHunk-1].n32)) + *Imp32rlc[CurHunk][k-1]++ = ofs; + } } } + Delete (Imp16rlc[CurHunk]); + Delete (Imp32rlc[CurHunk]); + } + + return OBJERR_OK; +} + +ObjErr Object::Read (char *FileName) +{ + long size = 0; + FILE *f = fopen (FileName, "rb"); + if (!f) return OBJERR_Open; + fseek (f, 0, SEEK_END); + Size = ftell (f); rewind (f); + if ((o0 = malloc (Size))) + size = fread (o0, 1, Size, f); + fclose (f); + if (!o0) return OBJERR_Mem; + if (size != Size) return OBJERR_Read; + + switch (br2 (o0)) { +#ifdef SUPPORT_AMIGA + case 0: + ObjFmt = OBJFMT_Amiga; + return ReadAmiga (); +#endif + case 0x150: + ObjFmt = OBJFMT_COFF; + return ReadCOFF (); + } + return OBJERR_Unknown; +} + +void Object::MergeImp ( + unsigned long nImp1, Import * Imp1, + unsigned long &nImp2, Import * &Imp2, + unsigned long size) +{ + unsigned long n; Import *imp2 = Imp2; + for (n=0; nrlc; + for (k=imp2->nrlcs; k--; rlc++) *rlc += size; + Import *imp1 = Imp1; + for (k=nImp1; k--; imp1++) + if (!strcmp (imp1->name, imp2->name)) { + unsigned long i, j; + i = imp1->nrlcs; j = imp2->nrlcs; + rlc = new unsigned long [i+j]; + memcpy (rlc, imp1->rlc, i * sizeof (long)); + memcpy (&rlc[i], imp2->rlc, j * sizeof (long)); + Delete (imp1->rlc); Delete (imp2->rlc); + imp1->rlc = rlc; imp1->nrlcs += j; + if (!--nImp2) Delete (Imp2); + else { + memmove (imp2, imp2+1, (nImp2-n--) * sizeof (Import)); + imp2--; + } break; + } } +} + +void Object::Merge2 ( + unsigned long &n1, void * &p1, + unsigned long &n2, void * &p2, + unsigned long SizeOf) +{ + if (n2) { + unsigned char *p = new unsigned char [(n1+n2)*SizeOf]; + memcpy (p, p1, n1 * SizeOf); + memcpy (&p[n1*SizeOf], p2, n2 * SizeOf); + DeleteCast (unsigned char **, p1); + DeleteCast (unsigned char **, p2); + n1 += n2; n2 = 0; + p1 = p; + } +} + +void Object::Merge (int &First, int &Second) +{ + int first, second; + if ((unsigned int)(second=Second) < nscns) { + if ((unsigned int)(first=First) < nscns) { + int hunk; unsigned long size = Hunk[first].size; + + for (hunk=0; hunk<(int)nscns; hunk++) if (hunk != second) { + unsigned long i, *R32 = Hunk[second].R32[hunk]; + for (i=Hunk[second].nR32[hunk]; i--; R32++) *R32 += size; + } + MergeImp ( + Hunk[first].nImp16, Hunk[first].Imp16, + Hunk[second].nImp16, Hunk[second].Imp16, + size); + MergeImp ( + Hunk[first].nImp32, Hunk[first].Imp32, + Hunk[second].nImp32, Hunk[second].Imp32, + size); + { + unsigned long i; Export *exp = Hunk[second].Exports; + for (i=Hunk[second].nExports; i--; exp++) exp->value += size; + } + + for (hunk=0; hunk<(int)nscns; hunk++) { + unsigned long i, j, *R32_1, *R32_2; + i = Hunk[hunk].nR32[first]; j = Hunk[hunk].nR32[second]; + Hunk[hunk].nR32[first] += j; Hunk[hunk].nR32[second] = 0; + R32_1 = new unsigned long [i+j]; + memcpy (R32_1, Hunk[hunk].R32[first], i*sizeof(long)); + Delete (Hunk[hunk].R32[first]); + Hunk[hunk].R32[first] = R32_1; R32_1 += i; + R32_2 = Hunk[hunk].R32[second]; + for (; j--; R32_1++) { + ba4 (&Hunk[hunk].o8[*R32_1 = *R32_2++], size); + if (hunk == second) *R32_1 += size; + } + Delete (Hunk[hunk].R32[second]); + } + + for (hunk=0; hunk<(int)nscns; hunk++) if (hunk != second) { + unsigned long i, j, *R32; + i = Hunk[first].nR32[hunk]; j = Hunk[second].nR32[hunk]; + Hunk[first].nR32[hunk] += j; Hunk[second].nR32[hunk] = 0; + R32 = new unsigned long [i+j]; + memcpy (R32, Hunk[first].R32[hunk], i*sizeof(long)); + memcpy (&R32[i], Hunk[second].R32[hunk], j*sizeof(long)); + Delete (Hunk[first].R32[hunk]); + Delete (Hunk[second].R32[hunk]); + Hunk[first].R32[hunk] = R32; + } + + Merge2 (Hunk[first].nImp16, (void * &) Hunk[first].Imp16, Hunk[second].nImp16, (void * &) Hunk[second].Imp16, sizeof (Import)); + Merge2 (Hunk[first].nImp32, (void * &) Hunk[first].Imp32, Hunk[second].nImp32, (void * &) Hunk[second].Imp32, sizeof (Import)); + Merge2 (Hunk[first].nExports, (void * &) Hunk[first].Exports, Hunk[second].nExports, (void * &) Hunk[second].Exports, sizeof (Export)); + + unsigned size2 = Hunk[second].size; + Hunk[first].size += size2; Hunk[second].size = 0; + unsigned char *o8 = new unsigned char [size + size2]; + memcpy (o8, Hunk[first].o0, size); + memcpy (&o8[size], Hunk[second].o0, size2); + if (Hunk[second].DelDat) + DeleteCast (unsigned char **, Hunk[second].o0); + if (Hunk[first].DelDat) + DeleteCast (unsigned char **, Hunk[first].o0); + else Hunk[first].DelDat = true; + Hunk[first].o8 = o8; + } else First = second, Second = first; + } +} + +#define CONFLICT "%s is incompatible with %s" +TI68kErr TI68k::Conflict (TI68kType Type2) +{ + if (szErr) { + Delete (szErr[TI68kERR_Conflict-1]); + char *msg = szErr[TI68kERR_Conflict-1] = new char [ + sizeof(CONFLICT) - 4 + + strlen(szTI68kType[Type2-1]) + + strlen(szTI68kType[Type-1])]; + sprintf (msg, CONFLICT, szTI68kType[Type2-1], szTI68kType[Type-1]); + } return TI68kERR_Conflict; +} + +void TI68k::UndefRef (Import *imp) +{ + fprintf (stderr, "Error: %lu undefined reference(s) to '%s'.\n", imp->nrlcs, imp->name); +} + +enum { RAM32, eRAM32, RAM16, eRAM16, ROM, LIBS }; +TI68kErr TI68k::MakeDoorsOS () +{ + bool bErr=false; Import *imp; + int i, *lens, n16, n32, *ndx, nExtra16=0, nLibs=LIBS, nRAM16=0; + n16 = (signed)Hunk[CodeHunk].nImp16; + n32 = (signed)Hunk[CodeHunk].nImp32; + lens = (int *)_alloca (n32 * sizeof (int)); + ndx = (int *)_alloca (n32 * sizeof (int)); + for (imp=Hunk[CodeHunk].Imp32,i=0; iname[1], '@'); + if ((!p) && ((*imp->name)!='_') && strncmp(imp->name,"L__",3)) { + p = strstr (&imp->name[1], "__"); + } + if (p) { + lens[i] = p - imp->name; + if (lens[i] > 8 && strncmp (imp->name, "_extraramaddr@", 14)) + lens[i] = 0; + } else if (!strncmp (imp->name, "_RAM_CALL_", 10) + || !strncmp (imp->name, "_ROM_CALL_", 10)) + lens[i] = 9; + else if (!strncmp (imp->name, "_extraramaddr_", 14)) + lens[i] = 13; + else lens[i] = 0; + if (!lens[i]) UndefRef (imp), bErr = true; + else { + int j; Import *imp2 = Hunk[CodeHunk].Imp32; + for (j=0; jname, imp->name, lens[i])) + lens[i] = -lens[i], ndx[i] = ndx[j], j = i; + if (j == i) { + if (lens[i] <= 8) ndx[i] = nLibs++; + else switch (imp->name[2]) { + case 'A': ndx[i] = RAM32; break; + case 'O': ndx[i] = ROM; break; + default: ndx[i] = eRAM32; + } } } } + + for (imp = Hunk[CodeHunk].Imp16,i=0; iname, "_extraramaddr", 13)) nExtra16++; + else if (!strncmp (imp->name, "_RAM_CALL_", 10)) nRAM16++; + else UndefRef (imp), bErr = true; + } + + if (bErr) return TI68kERR_DoorsOSUndef; + + struct LibRef { + unsigned short ord, nrlcs; + unsigned long *rlc; + } **Refs = (LibRef **)_alloca (nLibs * sizeof (LibRef *)); + struct Lib { + char name[9]; + unsigned char minVersion /*__attribute__ ((packed))*/; + union { + unsigned short nRefs; + unsigned short nExps; + }; + union { + LibRef *Refs; + unsigned short *Exps; + }; + } Exp, *Libs = (Lib *)_alloca (nLibs * sizeof (Lib)); + memset (Libs, 0, nLibs * sizeof (Lib)); + Libs[RAM16].nRefs = nRAM16; Libs[eRAM16].nRefs = nExtra16; + + struct { + unsigned short code, comment, main, exit, extra; + } Ofs = { 0, 0, 0, 0, 0}; + unsigned short HeaderSize = 40 + (nLibs-LIBS) * 12 + 2 * + (unsigned short)(Hunk[CodeHunk].nR32[CodeHunk] + Hunk[CodeHunk].nR32[BSSHunk]); + if (!(Hunk[BSSHunk].size)) HeaderSize-=6; + + for (imp=Hunk[CodeHunk].Imp32,i=0; i 0 && ndx[i] >= LIBS) + strncpy (Libs[ndx[i]].name, imp->name, lens[i]); + Libs[ndx[i]].nRefs++; + } + if (Libs[ROM].nRefs) HeaderSize += 2; + if (Libs[RAM32].nRefs || Libs[eRAM32].nRefs + || Libs[RAM16].nRefs || Libs[eRAM16].nRefs) + HeaderSize += 2; + for (i=0; iord = (unsigned short) + strtoul (&imp->name[abs(lens[i])+(((imp->name[abs(lens[i])]=='_')&&(imp->name[abs(lens[i])+1]=='_'))?2:1)], &p, 16); + HeaderSize += ((*refs)->nrlcs = (unsigned short) imp->nrlcs) * 2; + (*refs)->rlc = imp->rlc; (*refs)++; + } + + nRAM16 = nExtra16 = 0; + for (imp = Hunk[CodeHunk].Imp16,i=0; iname, "_RAM_CALL_", 10)) + len = 10, refs = &Libs[RAM16].Refs[nRAM16++]; + else len = 14, refs = &Libs[eRAM16].Refs[nExtra16++]; + refs->ord = (unsigned short)strtoul (&imp->name[len], &p, 16); + if (*p) UndefRef (imp), bErr = true; + HeaderSize += (refs->nrlcs = (unsigned short) imp->nrlcs) * 2; + refs->rlc = imp->rlc; + } + + if (bErr) return TI68kERR_DoorsOSUndef; + + Export *exp = Hunk[CodeHunk].Exports; Exp.nRefs = 0; + for (i=(int)Hunk[CodeHunk].nExports; i--; exp++) { + if (!strcmp (exp->name, "_comment")) + Ofs.comment = (unsigned short)exp->value; + else if (!strcmp (exp->name, "_main")) + Ofs.main = (unsigned short)exp->value; + else if (!strcmp (exp->name, "_exit")) + Ofs.exit = (unsigned short)exp->value; + else if (!strcmp (exp->name, "_extraram")) + Ofs.extra = (unsigned short)exp->value; + else { + char *p = strrchr (&exp->name[1], '@'); + if ((!p) && ((*exp->name)!='_') && strncmp(exp->name,"L__",3)) { + p = strstr (&exp->name[1], "__"); + } + if (p) { + if (!strncmp(p+((*p=='_')?2:1),"version",7)) { + int len = p - exp->name; + if (len > 8) return TI68kERR_BadExport; + unsigned long j = strtoul (p+((*p=='_')?9:8), &p, 16); + if ((*p) || (j > 255ul)) return TI68kERR_BadExport; else { + for (int ii=0; iiname,len)) Libs[ii].minVersion=j; + } + }} else { + int len = p - exp->name; + if (len > 8) return TI68kERR_BadExport; + if (!Exp.nRefs) { + strncpy (Exp.name, exp->name, len); + Exp.name[len] = 0; + } else if (strncmp (Exp.name, exp->name, len)) + return TI68kERR_BadExport; + Exp.nRefs++; + } + } } } + + if (Exp.nRefs) { + HeaderSize += 4 + 2 * Exp.nRefs; + Exp.Refs = (LibRef *)_alloca (Exp.nRefs * sizeof (short)); + memset (Exp.Refs, -1, Exp.nRefs * sizeof (short)); + + exp = Hunk[CodeHunk].Exports; + for (i=(int)Hunk[CodeHunk].nExports; i--; exp++) { + char *p = strrchr (&exp->name[1], '@'); + if ((!p) && ((*exp->name)!='_') && strncmp(exp->name,"L__",3)) { + p = strstr (&exp->name[1], "__"); + if (p) p++; + } + if (p++) { + if (strncmp(p,"version",7)) { + unsigned long j = strtoul (p, &p, 16); + if (*p || j >= Exp.nExps || (short)Exp.Exps[j] != -1) + return TI68kERR_BadExport; + Exp.Exps[j] = (unsigned short)exp->value; + } + } } } + + union { + void *o0; + unsigned char *o8; + unsigned short *o16; + unsigned long *o32; + }; + + Ofs.code = HeaderSize + (Type == TI68k_68kP ? sizeof (PrgmStub) : sizeof (LibStub)); + o8 = dat = new unsigned char [size = Ofs.code + Hunk[CodeHunk].size + 3]; + + bw2 (o16++, 0x6100); + bw2 (o16++, HeaderSize-2); + bw4 (o32++, ('6'<<24)+('8'<<16)+('k'<<8)+(Type==TI68k_68kP?'P':'L')); + *o16++ = 0; + bw2 (o16++, Ofs.comment ? Ofs.comment + Ofs.code : 0); + bw2 (o16++, Type == TI68k_68kP ? Ofs.main + Ofs.code : 0); + bw2 (o16++, Ofs.exit ? Ofs.exit + Ofs.code : 0); + bw2 (o16++, Flags); + *o16++ = 0; *o32++ = 0; + bw2 (o16++, Ofs.extra ? Ofs.extra + Ofs.code : 0); + + bw2 (o16++, nLibs-LIBS); + for (i=LIBS; iord); + unsigned long *rlc = Refs->rlc; + unsigned short k=Refs++->nrlcs; + while (k--) bw2 (o16++, Ofs.code + (unsigned short)*rlc++); + *o16++ = 0; + } while (j--); + } + + if (!Libs[ROM].nRefs) *o16++ = 0; + else { + bw2 (o16++, (unsigned short)-1); + int j = Libs[ROM].nRefs; bw2 (o16++, --j); + LibRef *Refs = Libs[ROM].Refs; + do { + bw2 (o16++, Refs->ord); + unsigned long *rlc = Refs->rlc; + unsigned short k=Refs++->nrlcs; + while (k--) bw2 (o16++, Ofs.code + (unsigned short)*rlc++); + *o16++ = 0; + } while (j--); + } + + i = Libs[RAM32].nRefs + Libs[eRAM32].nRefs + + Libs[RAM16].nRefs + Libs[eRAM16].nRefs; + if (!i--) *o16++ = 0; + else { + bw2 (o16++, (unsigned short)-1); bw2 (o16++, i); + for (i=RAM32; i<=eRAM16; i++) { + int j; LibRef *Refs = Libs[i].Refs; + for (j=Libs[i].nRefs; j; j--) { + bw2 (o16++, Refs->ord + (unsigned short)(i<<14)); + unsigned long *rlc = Refs->rlc; + unsigned short k=Refs++->nrlcs; + while (k--) bw2 (o16++, Ofs.code + (unsigned short)*rlc++); + *o16++ = 0; + } } } + + unsigned long *R32 = Hunk[CodeHunk].R32[CodeHunk]; + for (i=(int)Hunk[CodeHunk].nR32[CodeHunk]; i; i--) + bw2 (o16++, Ofs.code + (unsigned short)*R32++); + *o16++ = 0; + + if (Hunk[BSSHunk].size) { + bw2 (&dat[0x14], (unsigned short)(o8-dat)); + bw4 (o32++, Hunk[BSSHunk].size); + R32 = Hunk[CodeHunk].R32[BSSHunk]; + for (i=(int)Hunk[CodeHunk].nR32[BSSHunk]; i; i--) + bw2 (o16++, Ofs.code + (unsigned short)*R32++); + *o16++ = 0; + } else bw2 (&dat[0x14], (unsigned short)0); + + if (Exp.nRefs) { + bw2 (&dat[0x16], (unsigned short)(o8-dat)); + bw2 (o16++, Exp.nRefs); + for (i=0; i= 0) if (Hunk[BSSHunk].size) { + Hunk[BSSHunk].o8 = new unsigned char [Hunk[BSSHunk].size]; + Hunk[BSSHunk].DelDat = true; + memset (Hunk[BSSHunk].o8, 0, Hunk[BSSHunk].size); + Merge (CodeHunk, BSSHunk); + } + if (!NostubImp (Hunk[CodeHunk].nImp16, Hunk[CodeHunk].Imp16) + && !NostubImp (Hunk[CodeHunk].nImp32, Hunk[CodeHunk].Imp32)) { + unsigned long n = Hunk[CodeHunk].nR32[CodeHunk]; + unsigned long *R32 = Hunk[CodeHunk].R32[CodeHunk]; + size = Hunk[CodeHunk].size + 4 * n + 3; + dat = new unsigned char [size]; + memcpy (dat, Hunk[CodeHunk].o0, Hunk[CodeHunk].size); + unsigned short *o16 = (unsigned short *)&dat[size-1]; + *(unsigned char *)o16-- = 0xF3; + for (; n--; R32++) { + bw2 (o16--, (unsigned short)*R32); + bw2 (o16--, (unsigned short)br4 (&dat[*R32])); + } *o16 = 0; + return TI68kERR_OK; + } else return TI68kERR_NostubUndef; +} + +bool TI68k::ExtImp (unsigned long n, Import *imp) +{ + if (!n) return false; + for (; n--; imp++) UndefRef (imp); + return true; +} + +char *OutputName2=0; +bool InList(char *str, char *list) { + if (!*list) return true; + while (*list) + if (!strcmp(str,list)) return true; + else while (*list++); + return false; +} + +void maj_conv(char *s) { + char c; + while ((c=*s++)) + if (c>='A' && c<='Z') + memmove(s+1,s,strlen(s)+1), *s='-'; +} + +TI68kErr TI68k::MakeExt () +{ + /* TODO (?) : BSS aren't supported */ + if (BSSHunk >= 0) if (Hunk[BSSHunk].size) { + Hunk[BSSHunk].o8 = new unsigned char [Hunk[BSSHunk].size]; + Hunk[BSSHunk].DelDat = true; + memset (Hunk[BSSHunk].o8, 0, Hunk[BSSHunk].size); + Merge (CodeHunk, BSSHunk); + } + char *ExportList; + FILE *ex_fp=fopen("export.dat","rb"); + if (!ex_fp) ExportList=""; + else ExportList = new char [300000], fread(ExportList,300000,1,ex_fp), fclose(ex_fp); + FILE *def_fp=fopen("deflt.txt","a+"); + unsigned long nExp = 0, szExpN = 0; + int n=Hunk[CodeHunk].nExports; Export *exp = Hunk[CodeHunk].Exports; + unsigned long *expOffs = new unsigned long [n]; char **expName = new char * [n]; + for (; n--; exp++) { + if (InList(exp->name, ExportList)) { + char buf[200]; + sprintf(buf,"%s.ref",exp->name); + maj_conv(buf); + FILE *fp=fopen(buf,"w"); + if (!fp) { printf("Couldn't open '%s' !\n",buf); return TI68kERR_Unknown; } + sprintf(buf,"%s.ext",OutputName2); + fputs(buf,fp); + fclose(fp); + if (def_fp) fprintf(def_fp,"#var %s\n",exp->name); + expOffs[nExp] = exp->value, expName[nExp] = exp->name, + szExpN += strlen(exp->name)+1, nExp++; + } + } + if (def_fp) fclose(def_fp); + unsigned long nRef0 = 0, nRef = 0, nImp = 0, szImpN = 0; int i; + int n32=Hunk[CodeHunk].nImp32, n16=Hunk[CodeHunk].nImp16; + Import *imp32 = Hunk[CodeHunk].Imp32, *imp16 = Hunk[CodeHunk].Imp16, *imp; + for (n=n16,imp=imp16; n--; imp++) + nRef0+=imp->nrlcs+1; + for (n=n32,imp=imp32; n--; imp++) + nRef0+=imp->nrlcs+1; + unsigned long *impOffs = new unsigned long [nRef0]; + char **impName = new char * [n16+n32]; + for (n=n16,imp=imp16; n--; imp++) { + for (i=imp->nrlcs;i--;) + impOffs[nRef] = imp->rlc[i]-2, nRef++; + impOffs[nRef] = -2ul, nRef++; + impName[nImp] = imp->name, szImpN += strlen(imp->name)+1, nImp++; + } + for (n=n32,imp=imp32; n--; imp++) { + for (i=imp->nrlcs;i--;) + impOffs[nRef] = imp->rlc[i], nRef++; + impOffs[nRef] = -2ul, nRef++; + impName[nImp] = imp->name, szImpN += strlen(imp->name)+1, nImp++; + } + unsigned long nInt = Hunk[CodeHunk].nR32[CodeHunk]; + unsigned long *R32 = Hunk[CodeHunk].R32[CodeHunk]; + size = (2+Hunk[CodeHunk].size) + (2*nInt+2) + (2*nExp+2+szExpN) + (szExpN&1) + (2*nRef+2+szImpN) + (szImpN&1) + (2); + dat = new unsigned char [size]; + memset (dat, 0, size); + unsigned char *p8 = dat; +#define w16(x) (bw2(p8,(unsigned short)(x)), p8+=2) + w16(2+Hunk[CodeHunk].size); + memcpy (p8, Hunk[CodeHunk].o0, Hunk[CodeHunk].size), p8+=Hunk[CodeHunk].size; + /* Relocation section */ + for (n=nInt; n--; R32++) { + w16(2+(unsigned short)*R32); + } + w16(0); + /* Export section */ + for (n=nExp;n--;) + w16(2+expOffs[n]); + w16(0); + for (n=nExp;n--;) + strcpy((char *)p8, expName[n]), p8+=strlen(expName[n])+1; + if (szExpN&1) *p8++=0; + /* Import section */ + for (i=0;i<(int)nRef;i++) + w16(2+impOffs[i]); + w16(0); + for (i=0;i<(int)nImp;i++) + strcpy((char *)p8, impName[i]), p8+=strlen(impName[i])+1; + if (szImpN&1) *p8++=0; + /* BSS section */ + w16(0); +#ifndef NDEBUG + if (p8!=&dat[size]) { printf("Size mismatch!\n"); return TI68kERR_Unknown; } +#endif + return TI68kERR_OK; +} + +TI68kErr TI68k::Make () +{ + int hunk; + + for (hunk=0; hunk<3; hunk++) { + unsigned long i; Export *exp = Hunk[hunk].Exports; + for (i=Hunk[hunk].nExports; i; exp++,i--) { + if (!strcmp (exp->name, szTI68kType[TI68k_68kL-1])) { + if (Type == TI68k_none) Type = TI68k_68kL; + else return Conflict (TI68k_68kL); + } + else if (!strcmp (exp->name, szTI68kType[TI68k_68kP-1])) { + if (Type == TI68k_none) Type = TI68k_68kP; + else if (Type != TI68k_nostub) + return Conflict (TI68k_68kP); + } + else if (!strcmp (exp->name, szTI68kType[TI68k_ext-1])) { + if (Type == TI68k_none) Type = TI68k_ext; + else + return Conflict (TI68k_ext); + } + else if (!strcmp (exp->name, szTI68kType[TI68k_nostub-1])) { + if (Type == TI68k_none || Type == TI68k_68kP) + Type = TI68k_nostub; + else if (Type != TI68k_nostub_dll) + return Conflict (TI68k_nostub); + } + else if (!strcmp (exp->name, szTI68kType[TI68k_nostub_dll-1])) { + if (Type == TI68k_none || Type == TI68k_68kP || Type == TI68k_nostub) + Type = TI68k_nostub_dll; + else return Conflict (TI68k_nostub_dll); + } + else if (!strcmp (exp->name, szTI68kType[TI68k_prosit-1])) + return TI68kERR_prosit; + else if (!strcmp (exp->name, "_ti89")) + Output89 = 1; + else if (!strcmp(exp->name, "_ti92plus")) + Output92p = 1; + else if (!strncmp(exp->name, "_flag_", 6)) + Flags |= 1 << strtoul (&exp->name[6], NULL, 10); + else if (!strncmp(exp->name, "_version", 6)) + LibVersion = strtoul (&exp->name[8], NULL, 16); + else if (bBadExport + && strcmp (exp->name, "_comment") + && strcmp (exp->name, "_exit") + && strcmp (exp->name, "_extraram")) { + char *p = strrchr (&exp->name[1], '@'); + if (p) if (p[1]) { + strtoul (&p[1], &p, 16); + if (*p) p = NULL; + } + if (!p) return TI68kERR_BadExport; + } } } + + if (!Output89 && !Output92p && Type!=TI68k_ext) return TI68kERR_NoOutput; + + Merge (CodeHunk, DataHunk); + switch (Type) { + case TI68k_ext: + return MakeExt (); + case TI68k_nostub: + case TI68k_nostub_dll: + return MakeNostub (); + default: + return MakeDoorsOS (); + } + return TI68kERR_Unknown; +} + +TI68kErr TI68k::DoSave (char *FileName, char *ext, char *Header, unsigned long HeaderSize, unsigned short chksum) +{ + if (strlen (FileName) + strlen (ext) < _MAX_PATH) { + unsigned char buf[2]; char FullName[_MAX_PATH]; FILE *f; + f = fopen (strcat (strcpy (FullName, FileName), ext), "wb"); + if (HeaderSize) fwrite (Header, 1, HeaderSize, f); + bw2 (buf, (unsigned short)size); + fwrite (buf, 1, 2, f); + fwrite (dat, 1, size, f); + if (HeaderSize) lw2 (buf, chksum), fwrite (buf, 1, 2, f); + fclose (f); + } + return TI68kERR_OK; +} + +TI68kErr TI68k::Save (char *FileName, bool outputbin, bool quiet) +{ + static char Header[]= + "**TI92P*\001\0main\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\001\0R\0\0\0\0\0\0\0\0\0\0\0!\0\0\0\0\0\0\0Z\0\0\0"; +#define HeaderSize (sizeof (Header)) + + char AMSname[9], *p; unsigned short chksum; + if (GetExeSize () > MAX_VAR_SIZE) + return TI68kERR_TooLarge; + AMSname[8] = 0; p = strrchr (FileName, '\\'); + _strlwr (strncpy (AMSname, p ? p + 1 : FileName, 8)); + strncpy (&Header[0x40], AMSname, 8); + lw4 (&Header[0x4C], size + HeaderSize + 4); + + if (outputbin || Type == TI68k_nostub_dll || Type == TI68k_ext) { + if (Type == TI68k_nostub_dll && !outputbin) + DoSave (FileName, ".ndl", NULL, 0, 0); + else if (Type == TI68k_ext && !outputbin) + DoSave (FileName, ".ext", NULL, 0, 0); + else + DoSave (FileName, ".bin", NULL, 0, 0); + if (!quiet) { + if (Output89) printf ("Linked for TI-89\n"); + if (Output92p) printf ("Linked for TI-92 Plus\n"); + } + } else { + chksum = LOBYTE (size) + HIBYTE (size); + unsigned long i; + for (i=0; i\n" + "Modified by: Romain Lievin \n" + " Sebastian Reichelt \n" + " Kevin Kofler \n" + " and Paul Froissart\n" + ); + + if (help) puts ( + "Usage: obj2ti [options] file\n" + "Options:\n" + " -h --help\tDisplay this information\n" + " -o --output\tFollowed by project name\n" + " -O --outputbin\tOutput a binary file, not a calc file\n" + " -q --quiet\tLink without displaying extra verbose information\n" + " -v --version\tDisplay program version number\n" + " -x --ext\tOutput a .ext object suitable for GTC\n" + ); + else if (ObjFile) { + TI68k *ti = new TI68k (szErr, Type); + err = ti->Read (ObjFile); + if (!err) { + char *ext = strrchr (OutputName2 = ObjFile, '.'); + if (ext && (!strcmp(ext,".o") || !strcmp(ext,".O"))) + *ext = 0; + err = ti->Make (); + if (!err) { + if (!OutputName) { + char *ext = strrchr (OutputName = ObjFile, '.'); + if (ext) if (!_stricmp (ext, ".o")) *ext = 0; + } err = ti->Save (OutputName, outputbin, quiet); + if (!err && !quiet) printf ("Linked %s - Size: %lu bytes\n", OutputName, ti->GetExeSize ()); + } } + if (err) { + if (err == TI68kERR_TooLarge) + fprintf (stderr, "Error: Size of %lu bytes exceeds maximum by %lu.\n", ti->GetExeSize (), ti->GetExeSize () - MAX_VAR_SIZE); + else if (szErr[err-1]) + fprintf (stderr, "%s.\n", szErr[err-1]); + } + delete ti; + } + return err; +} diff --git a/tools/obj2ti/obj2ti.h b/tools/obj2ti/obj2ti.h new file mode 100644 index 0000000..d70dd00 --- /dev/null +++ b/tools/obj2ti/obj2ti.h @@ -0,0 +1,262 @@ +// Written by Julien Muchembled. +// Fixed by Romain Lievin for Linux. +// Copyright (c) 2001. All rights reserved. + +#if defined(WIN32) || defined(__WIN32__) +# include +#endif + +#include +#include +#include "str.h" + +#include + +#define _alloca __builtin_alloca + + +#if !defined(WIN32) && !defined(__WIN32__) +# define _MAX_PATH 1024 //PATH_MAX //unistd.h +# define LOBYTE(w) (unsigned char)(w) +# define HIBYTE(w) (unsigned char)((w) >> 8) +typedef unsigned long DWORD; +#endif + +#include "stubs.h" +#include "m68kdefs.h" + +#ifndef STYP_TEXT +#define STYP_TEXT 0x20 +#endif +#ifndef STYP_DATA +#define STYP_DATA 0x40 +#endif +#ifndef STYP_BSS +#define STYP_BSS 0x80 +#endif + +// Taken from the source of a68k. +#define HunkUnit 999 +#define HunkName 1000 +#define HunkCode 1001 +#define HunkData 1002 +#define HunkBSS 1003 +#define HunkR32 1004 +#define HunkR16 1005 +#define HunkR8 1006 +#define HunkExt 1007 +#define HunkSym 1008 +#define HunkDbg 1009 +#define HunkEnd 1010 + +#define TypeEnd 0 +#define TypeExport 1 +#define TypeImport32 0x81 +#define TypeImport16 0x83 +#define TypeImport8 0x84 +#define TypeImport16Alt 0x8A + +enum ObjErr { + OBJERR_OK, + OBJERR_Open, + OBJERR_Read, + OBJERR_Mem, + OBJERR_Unknown, + OBJERR_NbScns, + OBJERR_Size, + OBJERR_HunkType, + OBJERR_R32Hunk, + OBJERR_ExtHunk, + OBJERR_ExtType, + OBJERR_OptHdr, + OBJERR_ScnType, + OBJERR_RlcType, + OBJERR_nbErrTypes +}; + +enum TI68kErr { + TI68kERR_OK, + TI68kERR_NoOutput=OBJERR_nbErrTypes, + TI68kERR_Unknown, + TI68kERR_BadExport, + TI68kERR_Conflict, + TI68kERR_DoorsOSUndef, + TI68kERR_NostubUndef, + TI68kERR_prosit, + TI68kERR_TooLarge, + TI68kERR_nbErrTypes +}; + +char *szErr[TI68kERR_nbErrTypes-1]={ + "Error in opening object file", + "Error in reading object file", + "Not enough memory", + "Unknown format", + "Bad number of sections", + "Unexpected end of file", + "Unsupported hunk type", + "Unexpected or bad Reloc32 hunk", + "Unexpected Ext. hunk", + "Unsupported Ext. type", + "Optional header is unsupported", + "Unsupported section type", + "Unsupported relocation type", + "No target (_ti89, _ti92plus, ...) is defined", + "Program format is unsupported or not specified", + "Exported label is not valid", + NULL, NULL, NULL, + "Prosit format is unsupported" + "Variable too large" +}; + +enum TI68kType { + TI68k_none, + TI68k_68kP, + TI68k_68kL, + TI68k_nostub, + TI68k_nostub_dll, + TI68k_prosit, + TI68k_ext, +}; + +char *szTI68kType[]={ + "_main", + "_library", + "_nostub", + "_nostub_dll", + "_prosit", + "_extfile" +}; + +#define Delete(mem) do{if (mem) {delete mem; mem = NULL;}}while(0) +#define DeleteCast(type,mem) do{if ((type)mem) {delete (type)mem; mem = NULL;}}while(0) + +typedef struct { + char *name; + unsigned long nrlcs, *rlc; +} Import; +typedef struct { + char *name; + unsigned long value; +} Export; + +class Object +{ +private: + long Size; + union { + void *o0; + unsigned char *o8; + unsigned long *o32; + FILHDR *filhdr; + }; + enum { + OBJFMT_None, + OBJFMT_Amiga, + OBJFMT_COFF + } ObjFmt; + +protected: + bool bBadExport; + struct { + unsigned long size, *R32[3], nR32[3], nImp16, nImp32, nExports; + union { + void *o0; + unsigned char *o8; + unsigned long *o32; + }; + Import *Imp16, *Imp32; + Export *Exports; + bool DelDat; + } Hunk[3]; + int CodeHunk, DataHunk, BSSHunk; + unsigned int nscns; + +public: + Object () { + Size = 0; o0 = NULL; ObjFmt = OBJFMT_None; + memset (Hunk, 0, sizeof (Hunk)); nscns = 0; + CodeHunk = DataHunk = BSSHunk = -1; + bBadExport = false; + } + virtual ~Object () { + int i; for (i=0; i<3; i++) { + unsigned long j; + if (Hunk[i].DelDat) Delete (Hunk[i].o8); + for (j=0; j<3; j++) Delete (Hunk[i].R32[j]); + for (j=0; jType = Type; + Flags = 0; + size = 0; dat = NULL; + } + virtual ~TI68k () { + Delete (dat); + if (szErr) Delete (szErr[TI68kERR_Conflict-1]); + } + + TI68kErr Make (); + TI68kErr Save (char *, bool, bool); + unsigned long GetExeSize (void) { return size+2; } +}; diff --git a/tools/obj2ti/str.h b/tools/obj2ti/str.h new file mode 100644 index 0000000..11a7efc --- /dev/null +++ b/tools/obj2ti/str.h @@ -0,0 +1,36 @@ +// Written by Julien Muchembled. +// Fixed by Romain Lievin for Linux. +// Copyright (c) 2001. All rights reserved. + +#include + +#if !defined(WIN32) && !defined(__WIN32__) +# if defined(__UNIX__) || defined(__LINUX__) +# define _stricmp(s1, s2) (strcasecmp ((s1), (s2))) +# else +int _stricmp (const char *dst, const char *src) +{ + int f,l; + + do { + f = (unsigned char)*dst++; + if (f >= 'A' && f <= 'Z') f -= 'A' - 'a'; + l = (unsigned char)*src++; + if (l >= 'A' && l <= 'Z') l -= 'A' - 'a'; + } while (f && (f == l)); + return f - l; +} +# endif +#endif + +#if !defined(WIN32) && !defined(__WIN32__) +char *_strlwr (char *string) +{ + unsigned char *dst = NULL; char * cp; + + for (cp=string; *cp; ++cp) + if ('A' <= *cp && *cp <= 'Z') + *cp += 'a' - 'A'; + return string; +} +#endif diff --git a/tools/obj2ti/stubs.h b/tools/obj2ti/stubs.h new file mode 100644 index 0000000..be2bb43 --- /dev/null +++ b/tools/obj2ti/stubs.h @@ -0,0 +1,15 @@ +// Written by Julien Muchembled. +// Fixed by Romain Lievin for Linux. +// Copyright (c) 2001. All rights reserved. + +unsigned char PrgmStub[]={ + 0x4A,0x78,0x00,0x30,0x67,0x14,0x20,0x78,0x00,0x34,0x4E,0xD0,0x20,0x78,0x00,0xC8, + 0x20,0x68,0x03,0x98,0x4E,0x90,0x50,0x4F,0x4E,0x75,0x61,0xF0,0x4B,0x65,0x72,0x6E, + 0x65,0x6C,0x20,0x6E,0x65,0x65,0x64,0x65,0x64,0x2E,0x00,0x00 +}; + +unsigned char LibStub[]={ + 0x61,0x1E,0x4C,0x69,0x62,0x72,0x61,0x72,0x69,0x65,0x73,0x20,0x61,0x72,0x65,0x20, + 0x6E,0x6F,0x74,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x61,0x62,0x6C,0x65,0x2E,0x00, + 0x20,0x78,0x00,0xC8,0x20,0x68,0x03,0x98,0x4E,0x90,0x50,0x4F,0x4E,0x75 +}; diff --git a/tools/pchmaker/Makefile b/tools/pchmaker/Makefile new file mode 100644 index 0000000..f18484c --- /dev/null +++ b/tools/pchmaker/Makefile @@ -0,0 +1,12 @@ +include ../../common-gtc.mk + +SRC = pchmaker.c spack.c + +all: pchmaker +pchmaker: $(SRC) $(GTC_HEADERS) + $(CC) $(CFLAGS) $(SRC) -o $@ + +include ../../platform.mk +clean: +distclean scratchclean: + $(RM) pchmaker$(BIN_SUFFIX) diff --git a/tools/pchmaker/pchmaker.c b/tools/pchmaker/pchmaker.c new file mode 100644 index 0000000..9f230de --- /dev/null +++ b/tools/pchmaker/pchmaker.c @@ -0,0 +1,556 @@ +/* + * GTools C compiler + * ================= + * source file : + * Pre-Compiled Header maker code + */ + +/* NOTE : this source file is completely awful, but PchMaker was originally + * designed to be used only internally */ + +#include "define.h" +#include "pch.h" +#define SHARED /* we'll generate extra info so shared headers are possible */ + +FILE *src=0,*pch=0; +char *in=0; +#ifdef SHARED +#include +char *defname=0; +int n_ignored=0; char **ignored[20]; +#endif + +void fail(char *s) { +#ifdef PC + printf(s); + printf("\n"); +#else + clrscr(); + printf(s); + ngetchx(); +#endif +} + +void skipspace() { + char c; + while ((c=*in)==' ' || c=='\n' || c=='\t') in++; +} + +#ifdef PC +#define N_MAX 4096 +#else +#define N_MAX 1024 +#endif +char *tab[N_MAX]; +int N=0,var_size=0; +int extSz[N_MAX]; +int extCumSz[N_MAX]; +void *extDat[N_MAX]; +int nExt=0; + +/*#ifdef PC*/ +void wri(char *p,int v) { + *p++=(char)(v>>8); + *p=(char)v; +} +void addwri(char *p,int v) { + (*p++)+=(char)(v>>8); + (*p) +=(char)v; +} +int rd(unsigned char *p) { + return (((int)*p)<<8)+p[1]; +} +/*#else +#define wri(p,v) *(short *)(p)=v +#define rd(p) (*(short *)(p)) +#endif*/ + +#ifdef PC +void maj_conv(char *s) { + char c; + while ((c=*s++)) + if (c>='A' && c<='Z') + memmove(s+1,s,strlen(s)+1), *s='-'; +} +#endif + +char *defPack(char *s); +char *sPack(char *s,char *name,char *defn); +#ifdef PC +int memname,memdefn,meminit,memispk; +#endif +int argslen(char *s) { + char *p=s; + while (*p) { /* skip each argument */ + while (*p++); + } + return (int)((long)p)-(int)((long)s); +} +#ifdef PC +#define LOGGING +#endif +extern char *sPk_table; +#ifdef PC +static char __sPk_tab[3000]; +#ifdef PC +int sPk_usetab[128]={0}; +#endif +#define __sPk_end (&__sPk_tab[3000]) +void read_spack_table(int init) { + FILE *fp=fopen("lex.txt","r"); + char buf[100]; int n; char *p; + if (!fp) { if (init) printf("Warning : can't open lex file\n"); sPk_table="\0"+1; return; } + __sPk_tab[0]=0; /* sPack requires sPk_table[-1] to be 0 */ + sPk_table=__sPk_tab+1; + sPk_table[0]=0; /* so that the empty string always comes last :) */ + while (!feof(fp)) { + p=sPk_table; + fgets(buf,100,fp); + n=strlen(buf); + if (buf[n-1]=='\n') n--, buf[n]=0; + while (strcmp(p,buf)>0) /* perform a decreasing insertion sort */ + while (*p++); + memmove(p+n+1,p,__sPk_end-(p+n+1)); + strcpy(p,buf); + } + if (init) + memset(sPk_usetab,128,0); + else { + p=sPk_table; n=0; + while (*p) { + if (!sPk_usetab[n]) + memmove(p,p+strlen(p)+1,__sPk_end-p), n++; + else { while (*p++); n++; } + } + } +} +#else +void read_spack_table() { + sPk_table="\0"+1; +} +#endif +int get_spack_table_size() { + char *p=sPk_table; + while (*p) + while (*p++); + return (int)(p+1-sPk_table); +} + +int hdr_read() { + char c,cont=1; +#ifdef LOGGING + FILE *logfp=fopen("pchlog.txt","w"); +#endif + var_size=0; + skipspace(); + if (strncmp(in,"#var ",4)) { + fail("'#var' expected"); + return 0; + } + in+=4; + while (cont) { + char *name,*args=NULL,*defn,*init,*block,*ptr; +#ifdef PC + int extID=-1; int oldinit=0; +#endif + char **tp,**tp0; + int A,B,C,D,n/*,*ip*/; unsigned int flags=0; + skipspace(); + if (!*in) return; + name=in; + while ((c=*in)!=' ' && c!='\n' && c!='\t' && c!='(') { + if (c=='.') *in=' '; + in++; + } + if (c=='(') { + flags|=PCHID_MACRO; + *in++=0; + args=in; + while ((c=*in)!=')') + if (c==',') *in++=0; /* terminate string */ + else if (c=='.') *in++=0, flags|=PCHID_VAMAC; /* terminate macro */ + else in++; + *in++=0; /* terminate macro */ + if ((c=*in)!=' ' && c!='\n' && c!='\t') { fail("space expected"); return 0; } + } + *in=0; defn=in; in++; + skipspace(); + if (*in=='D' && in[1]=='(') { + int depth=0; char c; + in+=2; defn=in; + while ((c=*in++)) { + if (c=='(') depth++; + else if (c==')') { if (--depth<0) break; } + } + in[-1]=0; + if (!c) in--; + if (depth>=0) { + printf("\n**************\n*** ERROR! ***\n**************\nUnmatched '('\n"); + return 0; + } + } +/* if (*in=='M' && in[1]=='(') { + int depth=0; char c; + in+=2; defn=in; + while ((c=*in++)) { + if (c=='(') depth++; + else if (c==')') { if (--depth<0) break; } + } + in[-1]=0; + is_macro=(char)0x80; + }*/ + defn=defPack(defn); + if (def_is_packed) flags|=PCHID_PACKED; +#ifdef LOGGING + fputs(defn,logfp); + fputc('\n',logfp); +#endif + skipspace(); + init=in; + if (!*in) { cont=0; goto write_it; } + while (*in && (*in!='#' || strncmp(in,"#var ",4))) in++; + while ((c=*--in)==' ' || c=='\n' || c=='\t'); // remove trailing whitespace + in++; + cont=*in; + *in=0; + if (in>8; + if (B>0) memcpy(ptr,args,B); + memcpy(ptr+=(B+1),defn,C); + memcpy(ptr+=(C+1),init,D); +#ifdef PC + *(ptr+(D+1))=extID+1; +#else + *(ptr+(D+1))=0; +#endif + tp=tab; + while (strcmp(*tp,block)<0) tp++; + if (!strcmp(*tp,block)) { + if (memcmp(*tp,block,n)) { + printf("Warning:Redeclaration of %s\n",name); + } else { + free(block-4); + continue; + } + } + var_size+=n; +#ifdef PC + memname+=A+1,memdefn+=C+1,memispk+=D+1; + meminit+=oldinit+1; +#endif + tp0=tp; +/* ip=(int *)*tp; + ((int *)block)[-2]=ip[-2]; + tp--; + do { + tp++; + ip=(int *)*tp; + ip[-2]+=n; + } while (**tp!='');*/ + memmove(tp0+1,tp0,N_MAX*sizeof(char *)+((long)tab)-((long)tp0)); + *tp0=block; + N++; + if (N>=N_MAX) { printf("Too many IDs."); return 0; } + _continue: + ; + } +#ifdef LOGGING + fclose(logfp); +#endif +#ifdef SHARED + { + FILE *fp=fopen(defname,"w"); + if (fp) { + int n=N; char **tp=tab; + while (n--) + fprintf(fp,"%s\n",*tp++); + fclose(fp); + } else { + printf("Can't open .def file"); + return 0; + } + } +#endif + return 1; +} + +int written=0,pswritten[N_MAX]={0}; +#ifdef PC +int dtot=0,dnum=0; +int dhtot=0,dhnum=0; +#endif +int do_write(int a,int b,int real,int psw +#ifdef PC + ,int depth +#endif + ) { + if (a<=b) { + int i=(a+b)/2,sz=rd((char *)((short *)tab[i]-1)); + int x=do_write(a,i-1,0,psw+sz +#ifdef PC + ,0 +#endif + ),y=do_write(i+1,b,0,x +#ifdef PC + ,0 +#endif + ); + if (real) { + char *t=tab[i]; + while (*t++); + wri((char *)((short *)t+0),x==psw+sz?0:psw+sz); + wri((char *)((short *)t+1),y==x?0:x); + addwri((char *)((short *)t+2),i-1); + fwrite(tab[i],1,sz,pch); + written+=sz; +// pswritten=written; +#ifdef PC + dtot+=depth; dnum++; + if (x==psw+sz/*) dhtot+=depth, dhnum++; + if (*/ || y==x) dhtot+=depth, dhnum++; +#endif + do_write(a,i-1,1,psw+sz +#ifdef PC + ,depth+1 +#endif + ),do_write(i+1,b,1,x +#ifdef PC + ,depth+1 +#endif + ); + return 0; + } else +/* if (((int *)tab[i])[-2]!=written) + printf("Error, written=%d and offset=%d\n",written,((int *)tab[i])[-2]);*/ + return y; + } else return psw; +} + +#ifdef PC +void _fw16(unsigned short x,FILE *fp) { + fputc((unsigned char)(x>>8),fp); + fputc((unsigned char)x,fp); +} +#define fw16(x,f) _fw16((unsigned short)(x),f) +#endif + +void pch_write() { + int n,extOff,dicOff; + int *szp=extSz,*cszp=extCumSz; void **edp=extDat; + int sPk_size=get_spack_table_size(); + fwrite("PCH\0" "\0\0",PCH_HEAD_SIZE-6,1,pch); + dicOff=PCH_HEAD_SIZE+var_size; + extOff=dicOff+sPk_size; + extOff+=(extOff&1); + fw16(extOff,pch); + fw16(dicOff,pch); + fw16(N-1,pch); + do_write(1,N-1,1,PCH_HEAD_SIZE +#ifdef PC + ,1 +#endif + ); + fwrite(sPk_table,1,sPk_size,pch); + extOff+=nExt*2; + if ((dicOff+sPk_size)&1) fputc(0,pch); + n=nExt; while (n--) fw16(extOff+(*cszp++),pch); + n=nExt; + while (n--) + fwrite(*edp++,1,*szp++,pch); +#ifndef PC + fwrite("\0HDR\0\xF8",6,1,pch); +#endif + printf("Success!\n"); +} + +char sym0[9]={0}; + +#ifdef PC +int main(int argc,char **argv) { + char *srcname,*pchname; char pchbuf[200],defbuf[200]; + int quiet=0; + int error = 0; +#ifdef SHARED + while (argc>=2 && argv[1][0]=='-') { + if (argv[1][1]=='i') { + FILE *fp=fopen(argv[1]+2,"r"); + char lbuf[200],*lptr; int l_n=0; + char *lnbuf[2000],**lnptr; + if (!fp) { + fail("Can't open .def file"); + return 254; + } + while (!feof(fp)) { + fgets(lbuf,190,fp); + lbuf[strlen(lbuf)-1]=0; // strip \n + if (!*lbuf) continue; + lptr=alloca(strlen(lbuf)+1); + strcpy(lptr,lbuf); + lnbuf[l_n++]=lptr; + } + lnbuf[l_n++]=0; + lnptr=alloca(l_n*sizeof(char*)); + memcpy(lnptr,lnbuf,l_n*sizeof(char*)); + ignored[n_ignored++]=lnptr; + fclose(fp); + argv++; argc--; + } else if (argv[1][1]=='q') { + quiet=1; + argv++; argc--; + } else break; + } +#endif + if (argc!=2 && argc!=3) { + fail("Syntax : pchmaker [-i ... -i] [-q] []\n"); + return 255; + } + srcname=argv[1]; + if (strlen(srcname)>=200-4-1) { + fail("File name is too long\n"); + return 254; + } + if (argc==2) { + char *dot_ptr = strrchr(srcname,'.'); + int dot = dot_ptr ? dot_ptr-srcname : strlen(srcname); + strcpy(pchname=pchbuf,srcname), strcpy(pchname+dot,".pch"); +#ifdef SHARED + strcpy(defname=defbuf,srcname), strcpy(defname+dot,".def"); +#endif + } else pchname=argv[2]; +#else +#include +void _main(void) { + char *srcname,pchname[30]; + int error = 0; + srcname=top_estack; + if (*srcname!=STR_TAG) { + fail("Usage: pchmaker(\"infile\")"); + return; + } + srcname--; + while (*--srcname); + srcname++; + sprintf(pchname,"zheader\\%s",srcname); +#endif + src=fopen(srcname,"r"); + pch=fopen(pchname,"wb"); + if (!src || !pch) { + fail("Couldn't open file"); + if (src) fclose(src); + return; + } +#ifndef PC + in=*(char **)src; +#else + in=malloc(100000); + in[fread(in,1,100000,src)]=0; +#endif + /*pswritten=*/written=4; + N=1; + memset(sym0,0,9); + sym0[3]=5; + tab[0]=4+sym0; + tab[1]=4+"\0\6\0\0"; + read_spack_table(1); + if (hdr_read()) { +#ifdef PC +#define clr(x) mem##x=0 + clr(name),clr(defn),clr(ispk),clr(init); + fseek(src,0,SEEK_SET); + in=malloc(100000); + in[fread(in,1,100000,src)]=0; + written=4; + N=1; + memset(sym0,0,9); + sym0[3]=5; + tab[0]=4+sym0; + tab[1]=4+"\0\6\0\0"; + read_spack_table(0); + hdr_read(); +#endif +#ifdef PC + dnum=dtot=0; + dhnum=dhtot=0; +#endif + pch_write(); +#ifdef PC + if (!quiet) { +#define disp(x) printf("Memory used by '" #x "' : %5d bytes\n", mem##x) + printf("Header contains %d identifiers\n",N-1); + printf("Average tree depth : %f\n",((float)dtot)/dnum); /* depth if ID is in PCH */ + printf("Average leaf depth : %f\n",((float)dhtot)/dhnum); /* depth if ID not found */ + printf("\n"); + disp(name),disp(defn),disp(ispk),disp(init); + printf("\nHeader has %d extension%s\n",nExt,nExt==1?"":"s"); + printf("Memory used by extensions : %5d bytes\n", extCumSz[nExt-1]+extSz[nExt-1]); + } +#endif + } else + error = 1; + fclose(pch); + fclose(src); + return error; +} diff --git a/tools/pchmaker/spack.c b/tools/pchmaker/spack.c new file mode 100644 index 0000000..60028ef --- /dev/null +++ b/tools/pchmaker/spack.c @@ -0,0 +1,223 @@ +/* + * GTools C compiler + * ================= + * source file : + * sPack header packing/unpacking + */ + +#include "define.h" + +#define SPK_START (char)0x81 +#ifdef STATIC_SPACK_TAB +#ifdef ARRAY_VER +#define C(al) al +char *sPk_tab[]={ +#else +#define C(al) al "\0" +char *sPk_table= + "\0" +#endif + C(" *)") + C("*)") + C("*,") + C("int x") + C("int y") + C("int z") + C("int a") + C("int b") + C("int c") + C("register ") + C("unsigned ") + C("signed ") + C("volatile ") + C("void _(") + C("int _(") + C("short _(") + C("BOOL _(") + C("long _(") + C(" *_(") + C("*_(") + C("const ") + C("void,(") + C("char,(") + C("int,(") + C("short,(") + C("long,(") + C("float,(") + C("void") + C("char") + C("int") + C("short") + C("long") + C("float") + C("typedef struct") + C("typedef ") +#ifdef GEN + C("FIXED ") + C("HANDLE ") + C("BGS *") + C("SCREEN *") + C("POINT *") + C("FIXED *") + C("PLANE *p") +#endif + C("Gray") + C("_RR(") + C(",15") + C(",(") + C("),") + C("({") + C("})") + C("_rom_call(") + C("_rom_call_addr(") + C("FILE*") + C("__ATTR_LIB_ASM__") + C("__ATTR_LIB_C__") + C("__ATTR_TIOS__") + C("__ATTR_") + C(" __") + C("__") + C(" *") +#ifdef ARRAY_VER + C(0) +}; +#else + C("") + - 1 +; +#endif +#else +char *sPk_table=0; +#endif +#undef C +/*#define sPk_num sizeof(sPk_tab)*/ +#ifdef PC +extern int sPk_usetab[128]; +#endif + +#ifndef isidch +#ifdef PC +static int +isidch(c) + char c; +{ + return (c>='0'&&c<='9') || (c>='A'&&c<='Z') || (c>='a'&&c<='z') + || c == '_' || c == '$'; +} +static int +isbegidch(c) + char c; +{ + return (c>='A'&&c<='Z') || (c>='a'&&c<='z') || c == '_' || c == '$'; +} +#else +#define isidch(___c) ({register short __c=(___c); \ +(__c>='0'&&__c<='9') || (__c>='A'&&__c<='Z') || (__c>='a'&&__c<='z') || __c=='_' || __c=='$';}) +#define isbegidch(___c) ({register short __c=(___c); \ +(__c>='A'&&__c<='Z') || (__c>='a'&&__c<='z') || __c=='_' || __c=='$';}) +#endif +#endif + +#ifdef PC +char sPackRet[10000]; +char sPackTemp[10000]; +#else +char sPackRet[1000]; +char sPackTemp[1000]; +#endif +int strbeg(char *S,char *s) { + char c; + while ((c=*s++)) + if (c!=*S++) + return 1; + return 0; +} +char *sPack(char *s,char *name,char *defn) { + int nl=strlen(name),dl=strlen(defn); + char *s0=s; + char c,*d=sPackTemp; + while ((c=*s)) { + if (nl && !strbeg(s,name) && (s==s0 || (!isidch(s[-1]) && !isidch(s[nl])))) + s+=nl,*d++='_'; + else if (dl && !strbeg(s,defn) && (s==s0 || (!isidch(s[-1]) && !isidch(s[nl])))) + s+=dl,*d++='_'; + else *d++=*s++; + } + *d++=0; + s=sPackTemp; d=sPackRet; +//return s; + while ((c=*s)) { +#ifdef ARRAY_VER + char pk=SPK_START; char *str,**p=sPk_tab; + while ((str=*p++)) { + if (!strbeg(s,str)) { + s+=strlen(str),*d++=pk; + goto cont; + } + pk++; + } + *d++=*s++; +#else + char pk=SPK_START; char c,*p=sPk_table; + while ((c=*p++)) { + char *S=s; + do + if (c!=*S++) goto skip; + while ((c=*p++)); +#ifdef PC + sPk_usetab[pk-SPK_START]++; +#endif + p--; while (*--p); p++; + s+=strlen(p),*d++=pk; + goto cont; + /*pk++; + continue;*/ + skip: + while (*p++); + pk++; + } + if ((char)*s<0) *d++=(char)0x80; + *d++=*s++; +#endif + cont: + (void)0; + } + *d++=0; + return sPackRet; +} +#ifdef PC +char defPackRet[10000]; +#else +char defPackRet[1000]; +#endif +#ifdef PC +#define w(p,v) (*p++=(unsigned char)((v)>>8),*p++=(unsigned char)(v)) +#else +#define w(p,_v) ({short v=_v; *p++=(unsigned char)((v)>>8); *p++=(unsigned char)(v);}) +#endif +int def_is_packed=0; +char *defPack(char *s) { + char c=0; int na=0; + def_is_packed=0; +//return s; +// if (!strncmp("_rom_call(",s,10)) c=(char)0xFF,s+=10,na=2; + if (c) { + int l=0; char *prv=s; + char *o=defPackRet; + *o++=c; + while ((c=*s++)) { + if (c=='(') l++; + else if (c==')') { if (--l<0) s[-1]=0; w(o,atoi(prv)); } + else if (c==',' && !l && !--na) { s[-1]=0; strcpy(o,sPack(s,"","")); while (*o++); } + } + return defPackRet; + } else if (strlen(s)>4) { + char *packed=sPack(s,"",""); + if (strcmp(packed,s)) { + def_is_packed=1; + strcpy(defPackRet,packed); + return defPackRet; + } + } + return s; +} diff --git a/tools/txt89t/Makefile b/tools/txt89t/Makefile new file mode 100644 index 0000000..ad19174 --- /dev/null +++ b/tools/txt89t/Makefile @@ -0,0 +1,14 @@ +include ../../common.mk +CFLAGS = $(DEFAULT_CFLAGS) + +SRC = txt89t.c bin2calc.c + +all: txt89t + +txt89t: $(SRC) + $(CC) $(CFLAGS) $(SRC) -o $@ + +include ../../platform.mk +clean: +distclean scratchclean: + $(RM) txt89t$(BIN_SUFFIX) diff --git a/tools/txt89t/bin2calc.c b/tools/txt89t/bin2calc.c new file mode 100644 index 0000000..d3b56e1 --- /dev/null +++ b/tools/txt89t/bin2calc.c @@ -0,0 +1,85 @@ +#include +#include +#include + +// This structure comes from ttools. +typedef struct { + char signature[8]; // "**TI92P*" or "**TI89**" + unsigned char fill1[2]; // 01 00 + char folder[8]; // folder name + char desc[40]; // ---- not used ---- + unsigned char fill2[6]; // 01 00 52 00 00 00 + char name[8]; // varname + unsigned char type[4]; // 0C 00 00 00 + unsigned char size[4]; // complete file size (including checksum) + unsigned char fill3[6]; // A5 5A 00 00 00 00 + unsigned char datasize[2]; // data size +} TI_FILE_HDR; + + +static void put_little_endian(unsigned char *dest, unsigned long val, int len) { + while (len--) { + *dest++ = (unsigned char)(val&0xFF); + val >>= 8; + } +} +static void put_big_endian(unsigned char *dest, unsigned long val, int len) { + dest += len; + while (len--) { + *--dest = (unsigned char)(val&0xFF); + val >>= 8; + } +} + +char *create_ti_file(int calc,int tigl_type,char *name,char *folder,char *content,unsigned long content_size,unsigned long *ti_file_size) { + TI_FILE_HDR h; + memset(&h, 0, sizeof h); + memcpy(h.signature, "********", 8); +#define sig(x) memcpy(h.signature+2,x,sizeof(x)-1) + switch (calc) { + case 0: + sig("TI89"); + break; + case 1: + sig("TI92P"); + break; + case 2: + sig("TI92P"); + break; + default: + fatal("unknown calc type"); + } +#undef sig + h.fill1[0] = 1; + strncpy(h.folder, folder?folder:"main", 8); + h.fill2[0] = 1; h.fill2[2] = 0x52; + strncpy(h.name, name, 8); + h.type[0] = tigl_type; h.type[2] = 3; + h.fill3[0] = 0xA5; h.fill3[1] = 0x5A; + { + unsigned long oncalc_size = 88+content_size+2; + put_little_endian(h.size, oncalc_size, 4); + } + put_big_endian(h.datasize, content_size, 2); + + if (content_size>=65520) + fatal("TIOS variables can't be more than 65520 bytes long."); + + { + char *ret = malloc(sizeof(h)+content_size+2); + if (!ret) + fatal("Memory"); + if (ti_file_size) + *ti_file_size = sizeof(h)+content_size+2; + memcpy(ret, &h, sizeof(h)); + memcpy(ret+sizeof(h), content, content_size); + { + unsigned int crc = h.datasize[0]+h.datasize[1]; + unsigned long n = content_size; + while (n--) + crc += 0xff & (unsigned char)*content++; + put_little_endian(ret+sizeof(h)+content_size, crc, 2); + } + return ret; + } +} diff --git a/tools/txt89t/txt89t.c b/tools/txt89t/txt89t.c new file mode 100644 index 0000000..a9b49fd --- /dev/null +++ b/tools/txt89t/txt89t.c @@ -0,0 +1,123 @@ +#include +#include +#include + +void fatal(char *s) { + fprintf(stderr,"error: %s\n"); + exit(123); +} +char *create_ti_file(int calc,int tigl_type,char *name,char *folder,char *content,unsigned long content_size,unsigned long *ti_file_size); + +char *rightest_of(char *s,char c) { + char *t=strrchr(s,c); + if (t) return t+1; + return s; +} +char *leftest_end_of(char *s,char c) { + char *t=strchr(s,c); + if (t) return t; + return s+strlen(s); +} + +int compact=0; +char getTIch(FILE *fp,int reset) { + static int need_space=1; + int c; + if (reset) { + need_space=1; + return 0; + } + if (need_space && need_space--) + return ' '; + do + c=getc(fp); + while (c=='\r'); + if (c<0) + return 0; + if (!compact && c=='\n') { + c='\r'; + need_space=1; + } + if (c=='\t') { + c=' '; + need_space=!compact; + } + return c; +} + +int main(int argc,char **argv) { + char *folder=NULL; + char **p=argv+1; + int n=argc-1; + while (n && **p=='-') { + if (!strcmp(*p,"-f")) { + folder=p[1]; + n-=2,p+=2; + continue; + } + if (!strcmp(*p,"-c") || !strcmp(*p,"--compact")) { + compact=1; + n--,p++; + continue; + } + fprintf(stderr,"unknown option\n"); + return 2; + } + if (!n) { + fprintf(stderr,"usage: txt89t [-f ] [-c|--compact] ... \n"); + return 1; + } + while (n--) { + char *filename=*p++; + char *basename=rightest_of(rightest_of(filename,'\\'),'/'); + char *rootname_end=leftest_end_of(basename,'.'); + char *rootname=malloc(rootname_end-basename+4+1); + int i; + memcpy(rootname,basename,rootname_end-basename); + rootname[rootname_end-basename]=0; + for (i=0;i