;//	Nifty v0.5 Code	- (c) Peter Martijn Kuipers - 2001
;//	Check the nifty.txt file for Copying/Legal information


.nolist
#define TI83P
#include "ti83p.inc"

TABSPACES .equ 0Ah
DELAYCYCLES .equ 0FFh

vwrmem        .equ 86ECh 
namespace     .equ 86EFh 
whichprog     .equ 872Fh 
numprogs      .equ 8730h 
tempvar	      .equ 8731h 
stack_Storage .equ 8733h 
pagesarray    .equ 8735h 
arrH	      .equ 87h 
arrL          .equ 35h 
maxpageH      .equ 88h 
maxpageL      .equ 35h 

progsmem      .equ 8837h 



#define kbreset() ld a, keyreset \ out (1),a
#define kbtrigger(xxxx) ld a,keyreset \ out (1),a \ ld a,xxxx \ out (1),a \ in a, (1)

keyreset          .equ 0FFh
keyGroup1         .equ 0FEh
KeyDown           .equ 254
KeyLeft           .equ 253
KeyRight          .equ 251
KeyUp             .equ 247

keyGroup2         .equ 0FDh
KeyEnter          .equ 254
KeyPlus           .equ 253
KeyMinus          .equ 251
KeyMul            .equ 247
KeyDiv            .equ 239
KeyPower          .equ 223
KeyClear          .equ 191

keyGroup3         .equ 0FBh
keyMinus2         .equ 254
key3              .equ 253
key6              .equ 251
key9              .equ 247
keyRbracket       .equ 239
keyTan            .equ 223
keyVars           .equ 191

keyGroup4         .equ 0F7h
KeyPoint          .equ 254
Key2              .equ 253
Key5              .equ 251
Key8              .equ 247
KeyLbracket       .equ 239
KeyCos            .equ 223
 
KeyPrgm           .equ 191
KeyStat           .equ 127

keyGroup5         .equ 0EFh
Key0              .equ 254
Key1              .equ 253
Key4              .equ 251
Key7              .equ 247
KeyComma          .equ 239
KeySin            .equ 223
KeyMatrx          .equ 191
KeyX              .equ 127

keyGroup6         .equ 0DFh
KeySto            .equ 253
KeyLn             .equ 251
KeyLog            .equ 247
keyX2             .equ 239
keyX-1            .equ 223
keyMath           .equ 191
keyAlpha          .equ 127
 
keyGroup7         .equ 0BFh
KeyGraph          .equ 254
KeyTrace          .equ 253
KeyZoom           .equ 251
KeyWindow         .equ 247
KeyY              .equ 239
key2nd            .equ 223

keyMode           .equ 191
keyDel            .equ 127



.list
        .org progstart-2
	.db $BB,$6D

	di			; disable interrupts
	push ix
	ld (stack_storage),sp   ; store the stack-pointer, just in case..
	bcall(_runindicoff)

    	;display a nice splash screen...

	ld hl,splashscreen	; just your average screen copy routine
	ld de,plotsscreen
	ld bc, 768
	ldir
	bcall(_grbufcpy)


        ld b,0B0h
splashloop:
        call delay
	call delay
        djnz splashloop				

start_point:
	bcall(_clrLCDFull)	; and clean it up
;	bcall(_grbufclr)


; 1st of all, let's check for any programs that comply with NIFTY standard
        ld hl, (progptr)
        ld de, 0000h
        ld c, 00h
progfindloop:
        ld a, (hl)
        and 01Fh

        cp 005h
        jp z, gotprog
        cp 006h
        jp z, gotprog
        cp 001h
        jp z, skip
        cp 00Dh
        jp z, skip

        cp 017h         ; on the TI83 Plus, groups are also stored in the vat
        jp z,skip
        cp 015h         ; AppVars, I presume
        jp z,skip

        jp let_m_choose

skip:

        dec hl  ;we don't need this stuff...
        dec hl
        dec hl

        dec hl

        dec hl
        dec hl
        ld b,(hl)
skip2:
        dec hl
        djnz skip2
        dec hl
        jp progfindloop



gotprog:
        push hl

   
        dec hl		
        dec hl		
			;
        dec hl          ; all of this is to exclude Archived Programs
        dec hl		;
			;	
        dec hl		;
        ld a,(hl)	;
        cp 00h		;
        jp nz, incorrect_program;
			;
        inc hl		;
			;
        inc hl		;
        inc hl		;


        dec hl
        ld e,(hl)
        dec hl
        ld d,(hl)
        ex de,hl
        inc hl
        inc hl
        push bc
        call checkprog
        pop bc
        cp 1
        jp nz, incorrect_program ; if not a NIFTY file, loop back
        ex de,hl

        ld hl,progsmem
        push de
        ld d,00h
        ld e,c
        add hl,de
        pop de

        ld (hl), e
        inc hl
        ld (hl), d


        inc c
        inc c

        pop hl
        jp skip

incorrect_program:
        pop hl
        jp skip



let_m_choose:


        dec c
        dec c

        ld a,c
        cp -2
        jp z,no_nifty_files

        ld (numprogs),a
        ld a,00
        ld (whichprog),a


        ld hl,0013h
        ld (pencol),hl
        ld hl,text1
        bcall(_vputs)
        ld hl,060Ah
        ld (pencol),hl
        ld hl,text2
        bcall(_vputs)
        ld hl,0C05h
        ld (pencol),hl
        ld hl,text3
        bcall(_vputs)
        ld hl,120Eh
        ld (pencol),hl
	ld hl,text4
	bcall(_vputs)
	ld hl,1E00h
	ld (pencol),hl


        ld hl,(progsmem)


        call getprogname


choiceloop:
        kbtrigger(keygroup1)
        cp keyLeft
        jp z,left
        cp keyRight
        jp z,right
        kbtrigger(keyGroup2)
        cp keyEnter
        jp z, displayFile
	kbtrigger(keyGroup4)
	cp keyStat
	jp z,pchoose_help
        kbtrigger(keyGroup7)
        cp keyDel
        jp z,quit
	cp keyMode
	jp z,quit
	

        jr choiceloop

pchoose_help:
	call help

	bcall(_ClrLCDFull)

        ld hl,0013h
        ld (pencol),hl
        ld hl,text1
        bcall(_vputs)
        ld hl,060Ah
        ld (pencol),hl
        ld hl,text2
        bcall(_vputs)
        ld hl,0C05h
        ld (pencol),hl
        ld hl,text3
        bcall(_vputs)
        ld hl,120Eh
        ld (pencol),hl
	ld hl,text4
	bcall(_vputs)
	ld hl,1E00h
	ld (pencol),hl

	ld a,(whichprog)
	jp sharedpart	


right:
        ld a,(numprogs)
        ld c,a
        ld a,(whichprog)
        cp c
        jp z,choiceloop
        inc a
        inc a
        ld (whichprog),a
        jr sharedpart

left:
        ld a,(whichprog)
        cp 0
        jp z,choiceloop
        dec a
        dec a
        ld (whichprog),a

sharedpart:
        call clearline


        ld d,00h
        ld e,a
        ld hl,progsmem
        add hl,de

        ld e,(hl)
        inc hl
        ld d,(hl)

        ld h,d
        ld l,e

        call getprogname

        call delay
        jp choiceloop

no_nifty_files:
	bcall(_clrLCDFull)
	bcall(_homeup)
	ld hl,nnf_text
	bcall(_puts)

	jp realquit	

nnf_text:   ;0123456789ABCDEF	
	.db "No Nifty files  "
	.db "were found.     "
	.db "Check for Ar-   "
	.db "chived files,   "
	.db "Nifty doesn't   "
	.db "read them...    ",0        

displayFile:

	ld (pagesarray),hl
	ld ix,pagesarray
	
displayit:        
	call vwrite

displayfileloop:
	
	kbreset();
        kbtrigger(keygroup1)
        cp keyUp
        jp z,prevpage
        cp keyDown
        jp z,nextpage
        kbtrigger(keyGroup7)
        cp keyDel
        jp z,quit
	cp keyMode
	jp z,quit
	kbtrigger(keyGroup2)
	cp keyClear
	jp z,start_point
	kbtrigger(keyGroup4)
	cp keyStat
	jp z,page_help

	jr displayfileloop


page_help
	call help
	kbreset()
	jp displayit

prevpage:
	ld (tempvar),ix
	ld de,(tempvar)
	ld a,arrH		; if HH-bytes < HHBytes of start-array
	cp d			; don't goto prevpage
	jp z,prevpagecheck2
	jp p,displayfileloop	;
	jp m,gotoprevpage	; if higher, do so

prevpagecheck2:

	ld a,arrL		; if LL-bytes > LLBytes of start-array
	cp e
	jp z,displayfileloop	; and HH-bytes are HHBytes of start-array
	jp m,gotoprevpage	; goto prevpage
	jp displayfileloop	;
	

gotoprevpage:
	dec ix			; go back to the previous page pointer
	dec ix
	
	ld l,(ix+0)		; load it into hl
	ld h,(ix+1)

	jp displayit		; display it
	
nextpage:
		
	ld a,0 ; did we exit because the end of file is reached?
	cp b
	
	jp z,displayfileloop ; if so, don't do nextpage


	ld (tempvar),ix
	ld de,(tempvar)
	ld a,maxpageH		; if HH-bytes > HHBytes of maxpage
	cp d			; don't goto nextpage
	jp z,maxpagecheck2	; "
	jp m,displayfileloop	; "
	jp p,gotonextpage	; if lower, do so

maxpagecheck2:

	ld a,maxpageL		; if LL-bytes < LLBytes of maxpage
	cp e			;
	jp z,displayfileloop	; and HH-bytes are HHBytes of maxpage
	jp p,gotonextpage	; goto nextpage
	jp displayfileloop	;


gotonextpage:
	inc ix
	inc ix

	; save next pages address load next pages addr
	; into hl
	ld (ix+0),l
	ld (ix+1),h
	jp displayit




      
quit:
	
	bcall(_clrLCDFull)		; clear the lcd
        bcall(_homeup)			; go back up
        res textinverse,(iy+textflags)  ; unset any leftover inversities

	ld hl,quittext
	bcall(_puts)
	bcall(_grbufclr)

realquit:
	ld sp,(stack_storage)		; just for safety
	pop ix
	ei				; re-enable interrupts
        ret

quittext:   ;0123456789ABCDEF
	.db "Thanks for using"
	.db "Nifty!          ",0





checkprog:
        ld bc,0000h
cploop:
        ld a,c          ;if c is 8, all probably went well, so return 1
        cp 8
        jr z,cpRetTrue
        ld a,(hl)       ;
        push hl         ;       /   
        ld hl,progid    ;     /
        add hl,bc       ;   /
        cp (hl)         ; /
        jr nz,cpRetFalse        ;if this char was false return 0
        pop hl          ;
        inc hl
        inc c
        jp cploop

cpRetFalse:
        pop hl
        ld a,0
        ret
cpRetTrue:
        ld a,1
        ret

progid:
        .db tStop,tColon,"NIFTY",tEnter

getprogname:
        push af
getpnloop:
        ld a,(hl)
        cp 3Fh
        jr z,gotname

        push hl
        bcall(4594h)	; gettoklen equated wrongly in the origingal 
        ld hl,op3	; ti83plus.inc file
        ld b,a
        bcall(_vputsn)
        pop hl
        inc hl
        cp 0BBh
        jr z,gpnbdtwobyte
        cp 0AAh
        jr z,gpnbdtwobyte
        cp 07Eh
        jr z,gpnbdtwobyte
        sub 05Ch
        jr c,gpnbdonebyte
        cp 064h-05Ch
        jr c,gpnbdtwobyte
gpnbdonebyte:
        dec hl
gpnbdtwobyte:
        inc hl
        jp getpnloop

gotname:
        inc hl
        pop af
        ret



vwrite:
	push hl        
        bcall(_clrLCDFull)
        ld hl,0000h
        ld (PENCOL),hl
        pop hl
vwrloop:
        ld a,(hl)       ; load new token

        cp $D4          ; if we reach an End statement, return
        jp nz,continue  ; I still use the 0, in case someone forgot End
	ld b,0
        ret             ; cause 0 is found more often in mem than End
continue:
        cp 0
        jr nz,continue1 ; if 0 reached, return, else, skip next byte
	ld b,0
        ret
continue1:
	push af		; if we reached end-of-line, or something
	ld a,(PENCOL)	; like it, [ (PENCOL) > 92 ]
	cp 91		; then do a newline.
	jp m,no_eol
	dec hl		; donewline will increase hl, we don'want that
	jr donewline	; in this case.
no_eol:
	pop af

        cp tEnter
        jr nz,continue2 ; if char equ tEnter (my newline char), do newline
        push af
donewline:
        ld a,(PENROW)
        add a,06h
        ld (PENROW),a
        ld a,00h
        ld (PENCOL),a
        pop af
        inc hl
        jp vwrloop
continue2:
        cp tLBrace
        jr nz,continue3 ; if char equ "{" set inverted
        set textinverse, (iy+textflags)
        inc hl
        jp vwrloop
continue3:
        cp tRBrace
        jr nz,continue4 ; if char equ "}" reset inverted
        res textinverse, (iy+textflags)
        inc hl
        jp vwrloop
continue4:
        cp tPause
        jr nz,continue5 ; if token equ Pause, page has ended
        inc hl
        push af

pagedone:
	pop af
	ld b,1
	ret        

continue5:
        push af
        ld a,(penrow)
        cp 59		; if the screen is filled up, the page is done
        jp p, pagedone  ; using positive/negative is a great >= / < way
        pop af	



        cp tStore
        jr nz,continue6

        push af
        ld a,(pencol)
        add a,TABSPACES
        ld (pencol),a
        pop af
        inc hl
        jp vwrloop

continue6:


        push hl

        bcall(4594h);    ;GetToklen, equated wrongly in the ori ti83plus.inc
        ld hl,op3
        ld b,a
        bcall(_vputsn)
        pop hl
        ld a,(hl)

        inc hl

        cp 0BBh
        jr z,bdtwobyte
        cp 0AAh
        jr z,bdtwobyte
        cp 07Eh
        jr z,bdtwobyte
        sub 05Ch
        jr c,bdonebyte
        cp 064h-05Ch
        jr c,bdtwobyte
bdonebyte:
        dec hl
bdtwobyte:
        inc hl
        jp vwrloop
        


clearline:
        push bc
        push hl
        push af
        push de

        ld a,00
        ld (pencol),a
        ld hl, spaces
        bcall(_vputs)
        ld a,00
        ld (pencol),a

        pop de
        pop af
        pop hl
        pop bc
        ret


help:
	push hl
	push de
	push bc
	push ix
	
	ld hl, help_page
	call vwrite
help_loop:
	kbreset()
	kbtrigger(keygroup2)
	cp keyEnter
	jp nz,help_loop
	
	pop ix
	pop bc
	pop de
	pop hl
	ret
	
		


help_page:
	.db "STAT",tSpace,tColon,tspace,"DISPLAY",tSpace,"THIS",tSpace,"MESSAGE"
	.db "LEFT",tSpace,tColon,tspace,"SELECT",tSpace,"PREVIOUS",tSpace,"FILE"
	.db "RIGHT",tSpace,tColon,tspace,"SELECT",tSpace,"NEXT",tSpace,"FILE",tEnter
	.db "UP",tSpace,tColon,tspace,"GOTO",tSpace,"PREVIOUS",tSpace,"PAGE",tEnter
	.db "DOWN",tSpace,tColon,tspace,"GOTO",tSpace,"NEXT",tSpace,"PAGE",tEnter
	.db "DEL",tSpace,tColon,tspace,"QUIT",tSpace,"NIFTY",tEnter
	.db "MODE",tSpace,tColon,tspace,"QUIT",tSpace,"NIFTY",tEnter
	.db "CLEAR",tSpace,tColon,tspace,"SELECT",tSpace,"ANOTHER",tSpace,"FILE"
	.db tEnter,"PRESS",tSpace,"ENTER",tDecPt,tDecPt,tDecPt,tEnter
	.db tEnd



text1:
        .db "Choose Program:",0
text2:
	.db "--Press Stat for help--",0
text3:
        .db "Left and Right "
        .db "change files",0
text4:
        .db "Enter loads, Del quits",0

spaces:
        .db "            "
        .db "            "
        .db "            "
        .db "            "
        .db "            "
        .db "            "
        .db "            "
        .db "           ",0

delay:
        push bc
        ld b,DELAYCYCLES
delayloop:
        push hl
        push hl
        ld hl,(pencol)
        ld hl,(pencol)
        ld hl,(pencol)
        ld hl,(pencol)
        pop hl
        pop hl
        djnz delayloop

        pop bc
        ret

splashscreen:
        .db $FF,$FF,$FF,$9F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$1F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FE,$FF,$FF,$FF,$FD,$FF,$FE,$FF,$FF,$FE
        .db $FF,$EF,$FD,$FF,$FF,$E0,$3,$E0,$C,$FF,$FC,$7E
        .db $F8,$F,$F9,$F0,$1F,$80,$FF,$E,$1,$83,$F8,$7E
        .db $F0,$7,$FB,$FC,$7E,$78,$FE,$FE,$7E,$61,$F3,$FE
        .db $E7,$C7,$F3,$FC,$FC,$F9,$FD,$FE,$7D,$F8,$F7,$FE
        .db $EF,$C7,$F7,$FC,$FD,$F9,$FB,$FE,$79,$F8,$EF,$FE
        .db $CF,$C7,$F7,$F8,$F9,$F9,$FB,$FC,$FB,$FC,$EF,$FE
        .db $CF,$83,$E7,$F9,$F9,$F1,$F3,$FC,$FB,$FC,$DF,$FE
        .db $8F,$B3,$EF,$F9,$F8,$F3,$F1,$FC,$F3,$FC,$9F,$FE
        .db $C7,$B3,$EF,$F9,$F8,$F3,$F1,$FC,$F1,$FE,$3F,$FE
        .db $CF,$B3,$EF,$F1,$FF,$E0,$3B,$F9,$FB,$FE,$3F,$FE
        .db $FF,$71,$CF,$F3,$FF,$E3,$FF,$F9,$FF,$FE,$7F,$FE
        .db $FF,$79,$DF,$F3,$FF,$E7,$FF,$F9,$FF,$FE,$7F,$FE
        .db $FF,$79,$DF,$E3,$FF,$E7,$FF,$F9,$FF,$FC,$FF,$FE
        .db $FE,$F8,$DF,$E3,$FF,$E7,$FF,$F3,$FF,$FD,$FF,$FE
        .db $FE,$FC,$DF,$E7,$FF,$CF,$FF,$F3,$FF,$FD,$FF,$FE
        .db $FD,$FC,$1F,$E7,$FF,$CF,$FF,$E7,$FF,$FB,$FF,$FE
        .db $C3,$FC,$3F,$C7,$FF,$CF,$FF,$CF,$FF,$FB,$FF,$FE
        .db $87,$FE,$3F,$1,$FF,$9F,$FF,$0,$FF,$F7,$FF,$FE
        .db $FE,$3E,$3F,$FF,$FF,$BF,$FF,$FF,$FF,$F7,$1F,$FE
        .db $FD,$DF,$1F,$FF,$FF,$7F,$FF,$FF,$FF,$EE,$EF,$FE
        .db $FC,$1F,$8F,$DF,$E0,$FF,$FF,$FF,$FF,$9E,$F,$FE
        .db $FD,$5F,$C7,$9F,$E3,$FF,$FF,$FF,$F0,$3E,$AF,$FE
        .db $FC,$9F,$E0,$1F,$FF,$FF,$FF,$FF,$E0,$FE,$AF,$FE
        .db $FD,$5F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FC,$9F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FD,$5F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FC,$9F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FD,$5F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FC,$9F,$1B,$35,$B1,$11,$3C,$45,$47,$FE,$AF,$FE
        .db $FD,$5F,$75,$51,$5B,$B7,$5E,$DD,$6F,$FE,$AF,$FE
        .db $FC,$9F,$35,$35,$5B,$B3,$5E,$CE,$EF,$FE,$AF,$FE
        .db $FD,$5F,$75,$55,$1B,$B7,$5E,$DD,$6F,$FE,$AF,$FE
        .db $FE,$BF,$7B,$55,$5B,$B1,$3E,$C5,$6F,$FE,$AF,$FE
        .db $FF,$7F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FE,$BF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE,$AF,$FE
        .db $FE,$BF,$FF,$FE,$63,$66,$27,$FF,$FF,$FE,$AF,$FE
        .db $FD,$DF,$FF,$FE,$AE,$AA,$EB,$FF,$FF,$FE,$F,$FE
        .db $FD,$5F,$FF,$FE,$66,$AA,$67,$FF,$FF,$FE,$EF,$FE
        .db $FD,$5F,$FF,$FE,$AE,$2A,$EB,$FF,$FF,$FE,$EF,$FE
        .db $FD,$DF,$FF,$FE,$A2,$A6,$2B,$FF,$FF,$FF,$5F,$FE
        .db $FE,$BF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$1F,$FE
        .db $FE,$BF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$BF,$FE
        .db $FF,$7F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$BF,$FE
        .db $FF,$7F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FC,$1F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FB,$EF,$F3,$11,$13,$AD,$98,$A9,$D5,$53,$13,$3E
        .db $FA,$2F,$F5,$7B,$75,$8A,$AD,$AA,$D5,$55,$75,$7E
        .db $FA,$EC,$33,$3B,$33,$AA,$9D,$AA,$CD,$53,$33,$3E
        .db $FA,$2F,$F7,$7B,$75,$A8,$AD,$EA,$D5,$57,$75,$BE
        .db $FB,$EF,$F7,$1B,$15,$AA,$AD,$8A,$D6,$57,$15,$3E
        .db $FC,$1F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE
        .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FE





.end
