; Symbolic v1.8 Source Code By Brandon Sterner ; ;March 6, 2002 ; ; I've decided to post the source code to this application which is in one of its last revisions. I've ;learned alot from this application. Unfortunately one of those things was how poorly it was planned. Its been ;under development for more than a year now. It started out based on an 83, using code from zasmload. Since then ;its been ported to the 83+ in app form, and embedded into the OS using hooks. Its time for a rewrite, a totally new CAS. ;I'd like to thank everyone who has sent be bugs to fix, tested this, and encouraged me to continue this project. ;Here is what the code looks like. I hope it will be helpful to someone. You may use portions of this code if ;your software is freeware and you give me credit in the documentation. ; If anyone experienced with some college math is interested in assisting in a joint project on a future CAS, ;please let me know. I need help understanding algorithms and notation. Of course assistance programming these ;algorithms is also welcome. ; ;Brandon Sterner ;brandon@detacheds.com ; ;fix: ; compress help text ; expr(numStr(9)) throws err:version - kevin barmish ; press + on menu items for help ; uninstaller finds illegal tokens when it shouldn't ; better square roots ; web page does not mention numStr or pretty ; sending a app after installation - paxl ; preserve asmflag1 ;v1.8 fixed: ; d("2-","X") crashes, doesn't even get to parser - el barto ; d("X3+1+)^10+","X" crashes - David Lindstrom ; menuroutine in jump table - Michael Vincent ; sin(x)+2sin( crashes - Sebastian Theiss ; wrap around was buggy - Chuck Adams ; EOL not recognized as end of quotes - calebhwrd ; if expression ended with an e, then errored ; d("[cuberoot]x","x") gives divide by 0 error - Patrick Poon ; cot(pi/2) throws error - Kevin Barmish ; split screen mode fixed - sebastian theiss ; preserve those bytes in savescreen during parse ;v1.7 fixed: ; subtraction rule got mixed up with addition - introduced in v1.6 ; simp("(a/b)^-2") returns 1/(a/b)^2 when (b/a)^2 is simpler - kevin Barmish ;v1.6 fixed: ; didn't check variable type for first arg in let() ; pretty() token added ; d(cot-1(x)) didn't return negative result - David Vorobeychik ;v1.5 fixed: ; negative exponents simplify to reciprical of base to abs of power -Kevin Barmish ; natural logs and logs had problems with decimals - Kevin Barmish ; minus sign in numStr - Kevin Barmish ; simp("a=b") didn't throw syntax error ; d(str1,"x") no longer destroys str1 - Kevin Barmish ; updated help mode ; sending BASIC programs via the link no longer causes ERR:Version - Robert Maresh ; other varaibles such as equation and strings still may not be sent ; ptempcnt was not being updated, this caused "1"+numStr(0) to return "11" - Jason Kovacs ; X^X^X is no longer assumed to be X^(X^X) but rather (X^X)^X ;v1.4 fixed: ; problems with exponents - Kevin Barmish ;v1.3 fixed: ; problems with let() - Andrey Gorlin, Patrick Poon ; optimized lots of things ; safer memory management in implicit mult routines ; period after delete all - Andrey Gorlin ; inverse trig was wrong!!! - Andrey Gorlin ; graphing sign - Andrey Gorlin ; I now made it so that it threw the errow divide by 0 ; The grapher and table editor like this much more ; uninstaller had problems with archives - Andrey Gorlin ; Graph marked dirty after symbolic is run ;v1.2 fixed: ; problems with uninstaller - Bob Wang ;v1.1 fixed: ; problem with fractions ;bugs: ;pasting is buggy in progedit GLOBALS ON include "ti83plus.inc" ;Field code = 080h: Field codes are delimiters ; of the various datums in the header file. db 080h,0Fh ;Field:Program Length where "length" = 0Fh ; and the "Fh" tells us four bytes follow db 00h,00h,00h,00h ;Length= 4 bytes in size = (0 or N/A for ; unsigned apps) For signed apps the length is ; TBD/TBA ; db 080h,012h ;Field:Program type Prgm.typeh, in 2nd byte is 12h. ; The "2" defines the number of bytes in the keyfile ; name (which are the next 2 bytes). As illustrated in ; the Demo's Keyfile example from the Developer's Guideh, ; the keyfile example was 0104; two bytes in size. db 01h,04h ;Field: App ID Field code = 080h and App ID = "21h" db 080h,021h ; "2" = 2nd data fieldh, 1 for one byte in size. ; ;ID = 1 and it's one byte in sizeh, as denoted in the ; App ID's second nibble("1").This field is typically ; incremented on shareware or authenicated apps for db 01h ; major revisionsh,i.e: 1.x to 2.0; 2.n to 3.0h, etc. ; ;Field: App Build App Build = "31h" ; the ; "3" tells us it's build data; the "1" tells us the db 080h,031h ; Build data is "1" byte in size ; ;Build = 1 (always = 1 for development); is the ; configuration control for minor revisionsh, eg: db 08h ; 1.1 to 1.2h, or X.m to X.(m+1) db 080h,048h ;Field:App Name and App Name ="48h" ; and MUST be 8 characters db "Symbolic" ; db 080h,081h ;Field: App Pages App pages code = "8" & ; the "1" infers one byte following which ; tells us the number of pages of the app. db 01h ;App Pages = 1 egh, a 1-page application ; db 080h,090h ;No default splash screen ; db 03h,026h,09h,04h,04h,06fh,01bh,80h ;Field: Date stamp- 5/12/1999 ;(No decode of the Date Stamp) ; db 02h,0dh,040h ;Dummy-encrypted TI date stamp signature ;(No decode of encrypted date stamp ; signature) ; ; ==== Below 64 bytes of data are p/o application data ===== ; db 0a1h,06bh,099h,0f6h,059h,0bch,067h db 0f5h,085h,09ch,09h,06ch,0fh,0b4h,03h,09bh,0c9h db 03h,032h,02ch,0e0h,03h,020h,0e3h,02ch,0f4h,02dh db 073h,0b4h,027h,0c4h,0a0h,072h,054h,0b9h,0eah,07ch db 03bh,0aah,016h,0f6h,077h,083h,07ah,0eeh,01ah,0d4h db 042h,04ch,06bh,08bh,013h,01fh,0bbh,093h,08bh,0fch db 019h,01ch,03ch,0ech,04dh,0e5h,075h ; db 80h,7Fh ;Field: Program Image length db 0h,0h,0h,0h ;Length=0h, N/A ; db 0h,0h,0h,0h ;Reserved / pad db 0h,0h,0h,0h ;Reserved / pad db 0h,0h,0h,0h ;Reserved / pad db 0h,0h,0h,0h ;Reserved / pad (use if you have a 4 hex character sized keyfile) mMath equ 8h ask equ 4 ;system rom calls _setKeyH equ 4F66h _setTokenH equ 4F99h _setParseH equ 5026h _excCxMain equ 4045h _IsA2ByteTok equ 42a3h _getSerial equ 807eh _JForceCmd equ 402Ah _GET_TOK_STRNG equ 4594h _CREATETEMP equ 4a4dh baseAppBrTab2 EQU 9C06h parserHookPtr equ 9bach tokenHookPtr equ 9bc8h _LoadMenuNumL equ 45e2h exitkey equ appbackupscreen tempbc equ appbackupscreen+1 timer equ appbackupscreen+3 begin: jr endofjumps ;jumptable parsejumptable: dw cscRoutine ;1 dw csciRoutine ;2 dw secRoutine ;3 dw seciRoutine ;4 dw cotRoutine ;5 dw cotiRoutine ;6 dw cschRoutine ;7 dw cschiRoutine ;8 dw sechRoutine ;9 dw sechiRoutine ;10 dw cothRoutine ;11 dw cothiRoutine ;12 dw diffRoutine ;13 dw simpRoutine ;14 dw signRoutine ;15 dw getVersion ;16 dw arclength ;17 dw letRoutine ;18 dw numcaststr ;19 dw prettyRoutine ;20 dw 0 dw customMenu dw parse endofjumps: B_CALL forcefullscreen xor a ld (exitkey),a ld (tokenHookPtr+3),a ld (rawKeyHookPtr+3),a ld (parserHookPtr+3),a ld hl,splash ld de,plotsscreen call DispRLE B_CALL grbufcpy ld hl,byTxt ld de,256*35+17 call DE_vputs ld hl,30000 ld (timer),hl authorLoop: B_CALL getcsc or a jr nz,creditsdone ld hl,(timer) dec hl ld (timer),hl ld a,l or h jr nz,authorLoop ld hl,peopleTxt ld (tempBC),hl credits: B_CALL grbufcpy ld hl,thanksTxt ld de,32*256+17 call DE_vputs ld hl,(tempBC) ld e,(hl) inc hl ld d,(hl) inc hl call DE_vputs ld (tempBC),hl ld de,endNames or a sbc hl,de jr nz,credits2 ld hl,peopleTxt ld (tempBC),hl credits2: ld hl,6000 ld (timer),hl credits3: B_CALL getcsc or a jr nz,creditsdone ld hl,(timer) dec hl ld (timer),hl ld a,h or l jr nz,credits3 jr credits creditsdone: cp skclear jp z,quitApp mainmenu: call window call vertmen sub 4 jp z,quitApp inc a jp z,instructions inc a jp z,uninstall checkInstall: ;choose install from main menu checkParser: bit 1,(iy+36h) jp z,checkKey ld a,(parserHookPtr+2) ld b,a in a,(6) cp b jp z,checkKey ld hl,parserTxt call conflict checkKey: bit 5,(iy+34h) jr z,checkToken ld a,(rawKeyHookPtr+2) ld b,a in a,(6) cp b jr z,checkToken ld hl,rawkeyTxt call conflict checkToken: bit 0,(iy+35h) jr z,install ld a,(tokenHookPtr+2) ld b,a in a,(6) cp b jr z,install ld hl,tokenTxt call conflict install: in a,(6) ld hl,keyRoutine B_CALL setKeyH in a,(6) ld hl,tokenRoutine B_CALL setTokenH in a,(6) ld hl,parseRoutine B_CALL setParseH call window ld hl,success ld de,27*256+37 call DE_vputs ld de,33*256+31 ld hl,completedTxt call DE_vputs call wait call window ld hl,warningTxt ld de,23*256+24 call DE_vputs ld de,29*256+24 call DE_vputs ld de,35*256+24 call DE_vputs ld de,41*256+24 call DE_vputs call wait invalidCalc: quitApp: ld a,(exitkey) set graphDraw,(iy+graphFlags) B_JUMP JForceCmd ;Exit the application window: ld hl,16*256+22 ld de, 22*256+74 B_CALL FillRect ld hl,23*256+22 ld de, 46*256+22 B_CALL FillRect ld hl,23*256+74 ld de, 46*256+74 B_CALL FillRect ld hl,47*256+22 ld de, 47*256+74 B_CALL FillRect ld hl,23*256+23 ld de,46*256+73 B_CALL ClearRect ld hl,sym_title ld de, 16*256+24 SET textinverse, (IY+textflags) call DE_vputs RES textInverse,(iy+textflags) ret DE_vputs: ld (pencol), de Vputs: vputs: ld a, (hl) inc hl or a ret z b_call vputmap jr nc,vputs ret myRamCode: ld b,a in a,(6) push af ld a,b out (6),a xor a ld (op1),a ld (op1+9),a ld hl,4007h ld a,(hl) ld c,00001111b and c inc a inc a ld d,0 ld e,a add hl,de ld a,(hl) and c ;00001111b inc a inc a ld e,a add hl,de ld a,(hl) and c ;00001111b add a,3 ld e,a add hl,de ld bc,8 ld de,op1+1 ldir ex de,hl ld (hl),0 pop af out (6),a ret endOfMyRamCode: conflict: push hl push bc call window pop af call getBasePage pop hl push af push hl ld bc,endOfMyRamCode-myRamCode ld hl,myRamCode ld de,ramCode ldir call ramCode B_CALL findapp jr nc,appexists pop af pop hl ret appexists: ld de,23*256+24 ld hl,op1+1 call DE_vputs ld hl,isTxt call Vputs ld de,29*256+24 ld hl,usingTxt call DE_vputs pop hl call Vputs ld hl,hookTxt ld de,35*256+24 call DE_vputs call yesNoMenu bit textinverse,(iy+textflags) jr z,checkifallappshooks call window ld hl,failedTxt ld de,30*256+26 call DE_vputs call wait ; B_JUMP JForceCmdNoChar jp quitApp checkifallappshooks: call window ld hl,allapps ld de,23*256+28 call DE_vputs push hl ld hl,op1+1 ld de,29*256+29 call DE_vputs pop hl call Vputs ld de,35*256+36 call DE_vputs call yesNoMenu pop af ld c,a bit textinverse,(iy+textflags) call z,delallapphok ret wait: B_CALL getcsc or a jr z,wait cp skclear jp z,quitApp ret vertmen: ld a,1 vertmen2: push af ld b,4 ld hl,mainTxt vertmen3: res textinverse,(iy+textflags) pop af push bc cp b jr nz,notInverse set textinverse,(iy+textflags) notInverse: ld de,17*256+33 push af ld a,b add a,a add a,b add a,a add a,d ld d,a call DE_vputs pop af pop bc push af djnz vertmen3 nokey2: B_CALL getcsc or a jr z,nokey2 cp skclear jp z,quitApp cp skdown jr z,menudown cp skup jr z,menuup cp skenter jr nz,nokey2 pop af ret menudown: pop af inc a cp 5 jr nz,vertmen2 jr vertmen menuup: pop af dec a or a jr nz,vertmen2 ld a,4 jr vertmen2 yesNoMenu: set textinverse,(iy+textflags) ynmen: ld hl,confirmMenu ld de,41*256+37 call DE_vputs ld a,(iy+textflags) xor 00001000b ld (iy+textflags),a call Vputs nokey: B_CALL getcsc or a jr z,nokey cp skenter ret z cp skclear jp z,quitApp cp skleft jr c,nokey cp skright+1 jr nc,nokey jr ynmen getBasePage: ld hl,baseAppBrTab cp 20h jr c,inchart1 sub 20h ld hl,baseAppBrTab2 inchart1: ld d,0 ld e,a add hl,de ld a,(hl) ;a now is the base page of the app ret delallapphok: ld hl,9b78h-2 ld b,23 delallapphok2: inc hl inc hl inc hl inc hl ld a,(hl) push hl call getBasePage pop hl cp c jr nz,delallapphok3 ld (hl),0ffh delallapphok3: djnz delallapphok2 ret include "symmenu.asm" include "symparse.asm" include "reciptrig.asm" include "cas.asm" include "casdiff.asm" include "caspars.asm" include "cassimp.asm" include "cassort.asm" include "caserrs.asm" include "casutil.asm" include "casdata.asm" include "syminstruc.asm" include "symunin.asm" include "symblink.asm" .end END