; TI-Linux v1.10 Source Code
;
; By Michael Vincent - michael@radicalsoft.org
;
; Parts of the XShell Manager are by Robin Kay - dekiii@crosswinds.net (used with permission)
;
; Please do not distribute a modified version of this source, or steal a sizeable portion of code. I worked hard on this. You may learn from it, though.
;
.nolist
#include "tse.inc"
.list
.org    usermem-3
.db     $BB,$6D
 ret
.db "TSE",1              ; Header
prgtitle:
.db " TI-Linux v1.10", 0 ; Title
.dw 100
TheBeginning:
 ld hl,Module
 rst 20h
 bcall(_chkfindsym)
 jr c,firststart
 ld a,b
 cp 0
 jr nz,firststart
 inc de
 inc de
 inc de
 inc de
 inc de
 ld a,(de)
 cp 'M'
 jr nz,firststart
 inc de
 ld a,(de)
 cp 'V'
 jr nz,firststart
 ex de,hl
 inc hl
 inc hl
 inc hl
 inc hl
 inc hl
 inc hl
 inc hl
 ld bc,768
 ld de,saferam5
 ldir	;Load module into saferam5 (APD RAM, 768 bytes)
 call saferam5	;Run the module
firststart:
 res textWrite,(iy+sGrFlags)
 set fullScrnDraw,(iy+apiFlg4)
 set 3,(iy+$24) ;enable lowercase in TI-OS
 ld a,48
 ld (cursorx),a
 ld a,40
 ld (cursory),a
 bcall(_clrLCDFull)
 bcall(_grbufclr)
 ld hl,0018h
 ld (pencol),hl
 ld hl,prgtitle+1
 bcall(_vputs)
 ld hl,0000h
 ld de,7*256+95
 bcall(_invertrect)
 ld a,20
 ld l,20
 ld ix,icon_about
 call PutSprite
 ld hl,1d0ah
 ld (pencol),hl
 ld hl,icon_about_text
 set 7,(iy+sGrFlags)
 bcall(_vputs)
 ld a,60
 ld l,20
 ld ix,icon_progs
 call PutSprite
 ld hl,1d32h
 ld (pencol),hl
 ld hl,icon_progs_text
 bcall(_vputs)
 ld a,20
 ld l,44
 ld ix,icon_options
 call PutSprite
 ld hl,350ah
 ld (pencol),hl
 ld hl,icon_options_text
 bcall(_vputs)
 ld a,60
 ld l,44
 ld ix,icon_aboutkernel
 call PutSprite
 ld hl,3538h
 ld (pencol),hl
 ld hl,icon_aboutkernel_text
 bcall(_vputs)
 call PutMouse
firstmainloop:
 res 4,(iy+9)
 ei
 halt \ halt \ halt \ halt \ halt \ halt \ halt \ halt \ halt \ halt \ halt	;Needed to slow down the cursor, direct input is that fast!
 bit 4,(iy+9)
 jr nz,skipoff
 ld a,0ffh
 out (1),a
 ld a,Group1
 out (1),a
 in a,(1)
 cp KLeft
 call z,moveleft
 cp KRight
 call z,moveright
 cp KUp
 call z,moveup
 cp KDown
 call z,movedown
 ld a,0ffh
 out (1),a
 ld a,Group7
 out (1),a
 in a,(1)
 cp k2nd
 call z,selecticon
 cp kMode
 jr nz,firstmainloop
 ld a,(contrast)
 ld (tempcontrast),a
 call FadeOut
 bcall(_clrLCDFull)
 ld a,(tempcontrast)
 ld (contrast),a
 add a,$18
 or $C0
 call lcd_busy
 out ($10),a
 res textWrite,(iy+sGrFlags)
 call _tseExitShell
skipoff:
 ld a,1
 out (3),a
 halt
 jr firstmainloop
FadeOut:
 ld a,(contrast)
fadeloop:
 ei
 halt \ halt
 dec a
 ld (contrast),a
 add a,$18
 or $C0
 call lcd_busy
 out ($10),a
 ld a,(contrast)
 cp 0
 jr nz,fadeloop
 ret
lcd_busy:
 push af
 inc hl
 dec hl
 pop af
 ret
selecticon:
 ld a,(cursorx)
 cp 24
 call z,firstcol
 ld a,(cursorx)
 cp 64
 call z,secondcol
 ret
firstcol:
 ld a,(cursory)
 cp 24
 jp z,SysinfoIcon
 cp 48
 jp z,OptionsIcon
 ret
secondcol:
 ld a,(cursory)
 cp 24
 jp z,start
 cp 48
 jr z,AboutIcon
 ret
AboutIcon:
 bcall(_clrLCDFull)
 res textWrite,(iy+sGrFlags)
 ld hl,0000h
 ld (pencol),hl
 ld hl,prgtitle+1
 bcall(_vputs)
 ld hl,0700h
 ld (pencol),hl
 ld hl,author
 bcall(_vputs)
 ld hl,0e00h
 ld (pencol),hl
 ld hl,web
 bcall(_vputs)
 call PauseLoop
 jp firststart
PauseLoop:
 ei
 halt \ halt \ halt \ halt \ halt \ halt \ halt
 bcall(_getcsc)
 cp 0
 jr z,PauseLoop
 ret
SysinfoIcon:
 bcall(_clrlcdfull)
 res textWrite,(iy+sGrFlags)
 ld hl,0000h
 ld (pencol),hl
 ld hl,calctype
 bcall(_vputs)
 bcall(_getbasever)
 bcall(_setxxop1)
 bcall(_dispop1a)
 ld a,(pencol)
 sub 2
 ld (pencol),a
 ld a,'.'
 bcall(_vputmap)
 bcall(_getbasever)
 ld a,b
 bcall(_setxxop1)
 bcall(_dispop1a)
 ld hl,0700h
 ld (pencol),hl
 ld hl,freemem
 bcall(_vputs)
 bcall(_memchk)
 bcall(_setxxxxop2)
 bcall(_op2toop1)
 bcall(_dispop1a)
 ld hl,0e00h
 ld (pencol),hl
 ld hl,battlabel
 bcall(_vputs)
 bit 5,(iy+18h)
 jr nz, battsokare
 ld hl,battbad
 jr skipbattok
battsokare:
 ld hl,battgood
skipbattok:
 bcall(_vputs)
 call PauseLoop
 jp firststart
OptionsIcon:
 bcall(_clrLCDFull)
 bcall(_grbufclr)
 res textWrite,(iy+sGrFlags)
 ld hl,0000h
 ld (pencol),hl
 ld hl,explorertitle
 bcall(_vputs)
 ld bc,57
 ld de,95*256+57
 bcall(_darkline)
 ld bc,6
 ld de,95*256+6
 bcall(_darkline)
 ld bc,19*256+6
 ld de,19*256
 bcall(_darkline)
 ld d,38
 ld b,38
 bcall(_darkline)
 ld d,57
 ld b,57
 bcall(_darkline)
 ld d,76
 ld b,76
 bcall(_darkline)
 ld hl,58*256+3
 ld (pencol),hl
 ld hl,hide
 bcall(_vputs)
 ld a,22
 ld (pencol),a
 ld hl,prot
 bcall(_vputs)
 ld a,43
 ld (pencol),a
 ld hl,deleteme
 bcall(_vputs)
 ld a,61
 ld (pencol),a
 ld hl,flasharc
 bcall(_vputs)
 ld a,79
 ld (pencol),a
 ld hl,runbasic
 bcall(_vputs)
 bcall(_zeroop1)
 ld a,5h
 ld (op1),a
 call findnextprogram
filemanloop:
 res 4,(iy+09)
 ei
 halt
 bit 4,(iy+9)
 jr nz,PowerDown
 bcall(_getcsc)
 cp skClear
 jp z,firststart
 cp skRight
 call z,findnextprogram
 cp skLeft
 call z,findprevprogram
 cp skYEqu
 jr z,hideprogram
 cp skWindow
 call z,protectprogram
 cp skZoom
 jr z,delprogram
 cp skTrace
 call z,ArchiveUnarchive
 cp skGraph
 jr z,BasicRun
 jr filemanloop
PowerDown:
 ld a,1
 out (3),a
 halt
 jp filemanloop
BasicRun:
 bcall(_chkfindsym)
 inc de
 inc de
 ld a,(de)
 cp $3E
 jp nz,OptionsIcon
 ld a,b
 cp 0
 call nz,ArchiveUnarchive
 bcall(_runindicon)
 bit 1,(iy+8)
 push af
 set 1,(iy+8)
 AppOnErr(errorh)
 bcall(_parseinp)
 AppOffErr()
 bcall(_runindicoff)
errorh:
 pop af
 jr nz,skiprestore
 res 1,(iy+8)
skiprestore:
 bcall(_runindicoff)
 jp OptionsIcon
hideprogram:
 bcall(_chkfindsym)	;looks up program in OP1 and returns pointer to symbol table entry in hl
 dec hl
 dec hl
 dec hl
 dec hl
 dec hl
 dec hl
 dec hl
 ld a,' '
 ld (hl),a
 jp OptionsIcon
delprogram:
 ld hl,57*256
 ld de,63*256+95
 bcall(_clearrect)
 ld hl,57*256
 ld (pencol),hl
 ld hl,areyousure
 bcall(_vputs)
delloop:
 ei
 halt
 bcall(_getcsc)
 cp skLog
 jr z,skipdel
 cp sk1
 jr nz,delloop
 bcall(_chkfindsym)
 bcall(_delvararc)
skipdel:
 jp OptionsIcon
protectprogram:
 bcall(_chkfindsym)
 ld a,(hl)
 cp $05
 jr nz,protectskip
 ld a,$06
 ld (hl),a
 ret
protectskip:
 ld a,$05
 ld (hl),a
 ret
ArchiveUnarchive:
 ; Borrow system stack
 ld (tempword), sp
 ld hl, (sysstack)
 ld sp, hl
 ; Do arc/unarc and handle errors
 AppOnErr(arc_err2)
 bcall(_Arc_UnArc)
 AppOffErr()
arc_err2:

 ; Restore stack
 ld hl, (tempword)
 ld sp, hl
 ret
findnextprogram:
 bcall(_findalphaup)
 ld hl,0002h
 ld (currow),hl
 ld hl,op1+1
 bcall(_puts)
 ld b,7
spaceloop:
 ld a,' '
 bcall(_putc)
 djnz spaceloop
 ret
findprevprogram:
 bcall(_findalphadn)
 ld hl,0002h
 ld (currow),hl
 ld hl,op1+1
 bcall(_puts)
 call spaceloop
 ret
moveup:
 ld a,(cursory)
 cp 0
 ret z
 call PutMouse
 ld a,(cursory)
 sub 8
 ld (cursory),a
 call PutMouse
 ret
movedown:
 ld a,(cursory)
 cp 56
 ret z
 call PutMouse
 ld a,(cursory)
 add a,8
 ld (cursory),a
 call PutMouse
 ret
moveleft:
 ld a,(cursorx)
 cp 0
 ret z
 call PutMouse
 ld a,(cursorx)
 sub 8
 ld (cursorx),a
 call PutMouse
 ret
moveright:
 ld a,(cursorx)
 cp 88
 ret z
 call PutMouse
 ld a,(cursorx)
 add a,8
 ld (cursorx),a
 call PutMouse
 ret
PutMouse:
 ld b,8
 ld ix,mouse
 ld a,(cursory)
 ld l,a
 ld a,(cursorx)
 call _tseSprite
 call _tseFastCopy
 ret
PutSprite:
 ld b,9
 call _tseSprite
 ret
mouse:
 .db %10000000
 .db %11000000
 .db %11100000
 .db %11110000
 .db %11111000
 .db %11111000
 .db %00110000
 .db %00010000
icon_about:
 .db %11111111
 .db %10000001
 .db %10011101
 .db %10000101
 .db %10011101
 .db %10000001
 .db %10010001
 .db %10000001
 .db %11111111
icon_progs:
 .db %11111111
 .db %10000001
 .db %10111101
 .db %10100101
 .db %10111101
 .db %10100001
 .db %10100001
 .db %10000001
 .db %11111111
icon_options:
 .db %01111111
 .db %01000001
 .db %01000001
 .db %01000001
 .db %01111111
 .db %01010101
 .db %01111111
 .db %01010101
 .db %01111111
icon_aboutkernel:
 .db %11111111
 .db %10000001
 .db %10111101
 .db %10100001
 .db %10011101
 .db %10100001
 .db %10011101
 .db %10000001
 .db %11111111
cursorx:
 .db 0
cursory:
 .db 0
icon_about_text:
 .db "Sys. Info.",0
icon_progs_text:
 .db "Programs",0
icon_options_text:
 .db "Explorer",0
icon_aboutkernel_text:
 .db "About",0
tempcontrast:
 .db 0
hide:
 .db "Hide",0
Prot:
 .db "Prot",0
Deleteme:
 .db "Del",0
Flasharc:
 .db "Arc",0
runbasic:
 .db "Exec",0
battlabel:
 .db "Battery Level: ",0
battgood:
 .db "Good",0
battbad:
 .db "Low",0
explorertitle:
 .db "File Manager",0
web:
 .db "www.radicalsoft.org",0
author:
 .db "By Michael Vincent",0
calctype:
 .db "TI-83 Plus v",0
areyousure:
 .db "Are you sure (Y/N)?",0
Module:
 .db 5,"ZMODULE",0
start:
 res textWrite,(iy+sGrFlags)
 ld a,(89F0h+20)
 or %00000001
 ld (sysflags+20),a
 ld a,(calcspeed)
 di
 out (4),a
 ei
 ; Initalize Index and Selected
 ld hl, 0
 ld (MenuIndex), hl

rebuildMenu:
 ; Clear screen and display title and battery info
 bcall(_clrScrnFull)  
 bcall(_grbufclr)
 bit 5,(iy+18h)
 jr nz, battsareok
 ld ix,BadBattery
 jr showsprite
battsareok:
 ld ix,GoodBattery
showsprite:
 ld b,6
 ld a,88
 ld l,58
 call _tseSprite
 call _tseFastCopy
 ld hl,3900h
 ld (pencol), hl
 ld hl,FreeMem
 bcall(_vputs)
 bcall(_memchk)
 bcall(_setxxxxop2)
 bcall(_op2toop1)
 bcall(_dispop1a)
 ld hl, 0
 ld (pencol), hl
 ld hl, MenuTitle
 bcall(_vputs)
 xor a
 ld (pencol), a
 ld a, (penrow)
 add a, 7
 ld (penrow), a
 ld bc, 0000h+(64-7)
 ld de, 5F00h+(64-7)
 ld h, 1
 bcall(_iline)
 ld c, 07h
 ld e, c
 bcall(_iline)

 ; Init Display menu
 xor a
 ld (MenuLimit), a
 ld a, (MenuIndex)
 ld b, a
loopDrawMenu:

 ; Get program title
 inc b
 push bc
 call getprog
 cp 0
 jr z, notFinished
 pop bc
 jr finished
notFinished:
 call _tseChkprog
 cp 0
 jr z, notFlash

 ; Mark if flash
Flash:
 push hl
 ld hl, arc
 bcall(_vputs)
 pop hl
notFlash:

 ; Display entry
 bcall(_vputs)
 xor a
 ld (pencol), a
 ld a, (penrow)
 add a, 6
 ld (penrow), a

 ; Increase limit
 ld hl, MenuLimit
 inc (hl)

 ; Check if menu full
 pop bc
 ld a, (hl)
 cp 8
 jr nz, loopDrawMenu
finished:

 ; Handle selected beyond end of menu
 ld a, (MenuSelect)
 ld b, a
 ld a, (MenuLimit)
 dec a
 cp b
 jr nc, skip1
 ld (MenuSelect), a
skip1:

 ; Handle empty menu
 ld a, (MenuLimit)
 cp 0
 jr nz, skip2
 ld a, (MenuIndex)
 cp 0
 jp z, _tseExitShell
 xor a
 ld (MenuIndex), a
 jp rebuildMenu
skip2:

 ; Highlight Entry
 ld a, (MenuSelect)
 call highlightMenuItem

 ; Implement delay
loopMenuKeypad:
 res onInterrupt,(iy+onflags)
 ; Poll keypad
 ei
 halt ; Save power
 bit 4,(iy+9)
 jp nz,PowerOff
 bcall(_getCSC)
 ; Handle the quit key (clear)
 cp skClear
 jp z,firststart

 ; Handle keys that refresh the display
 ld hl, rebuildMenu
 push hl
 cp skLeft
 jr z, moveLeft2
 cp skRight
 jr z, moveRight2
 cp skAlpha
 jp z, task_end
 cp sk2nd
 jp z, task_exec
 cp skEnter
 jp z, task_exec
 cp skGraphvar
 jp z, arc_unarc
 pop hl

 ; Handle keys that't don't need to refresh display
 ld hl, loopMenuKeypad
 push hl
 cp skUp
 jr z, moveUp2
 cp skDown
 jr z, moveDown2
 cp skYEqu
 jp z,maxspeed
 cp skWindow
 jp z,morespeed
 cp skZoom
 jp z,smorespeed
 cp skTrace
 jp z,normalspeed

 ; Loop back up
 ret

 ; Move Left
moveLeft2:
 ld a, (MenuIndex)
 add a, -8
 ld (MenuIndex), a 
 ret

 ; Move Right
moveRight2:
 ld a, (MenuIndex)
 add a, 8
 ld (MenuIndex), a 
 ret

moveUp2:

 ; Check if top of list
 ld a, (MenuSelect)
 cp 0
 ret z

 ; Move Up
 call highlightMenuItem
 dec a
 ld (MenuSelect), a
 call highlightMenuItem
 ret

moveDown2:

 ; Check if bottom of list
 ld a, (MenuLimit)
 dec a
 ld c, a
 ld a, (MenuSelect)
 cp c
 ret z

 ; Move down
 call highlightMenuItem
 inc a
 ld (MenuSelect), a
 call highlightMenuItem
 ret

 ; Power Off
PowerOff:
 ld a, 1
 out (3),a
 halt ; Wait for ON interrupt
 jp loopMenuKeypad
                              
normalspeed:
	di	
	ld a,%00000110
	out (4),a
	ld (calcspeed),a
	ei
	ret	
maxspeed:
	di
	ld a,%00000000	;set speed to fastest setting
	out (4),a
	ld (calcspeed),a
	ei
	ret	
morespeed:
	di
	ld a,%00000010
	out (4),a
	ld (calcspeed),a
	ei
	ret	
smorespeed:
	di	
	ld a,%00000100
	out (4),a
	ld (calcspeed),a
	ei
	ret	
; Execute task
task_exec:
 call getsprog
 call _tseChkProg
 cp 0
 jr z,dotask
 call arc_unarc
 jp task_exec
dotask:
 call _tseStartTask
 cp 4
 jr z, ok2
 cp 0
 ret nz
ok2:
 call _tseSwitchTask
 ret

 ; End task
task_end:
 call getsprog
 call _tseChkProg
 cp 0
 ret nz
 call _tseEndTask
 ret

 ; Archive/Unarchive program
arc_unarc:
 call getsprog
 call _tseChkProg

 ; Borrow system stack
 ld (tempword), sp
 ld hl, (sysstack)
 ld sp, hl

 ; Do arc/unarc and handle errors
 AppOnErr(arc_err)
 bcall(_Arc_UnArc)
 AppOffErr()
arc_err:

 ; Restore stack
 ld hl, (tempword)
 ld sp, hl
 ret

;--Functions--

; Highlight Menu Entry
; a should contain the menu item to be selected
;
highlightMenuItem:
 push af
 ld b, a
 ld a, 7
highlightLoop:
 add a, 6
 djnz highlightLoop  
 ld h, a
 add a, 6
 ld d, a
 ld e, 5Fh
 ld l, 0
 bcall(_invertRect)
 pop af
 ret

; Get number of selected program and runs into getprog
;
getsprog:
 ld a, (MenuSelect)
 ld b, a
 ld a, (MenuIndex)
 add a, b
 ld b, a
 inc b

; Convert TSE prog number into _tseFindVar number
; 
getprog:
 ld c, 0
getprogloop:
 inc c
 ld a, c
 push bc
 call _tseFindVar
 pop bc
 ld a, 0ffh
 ret nz
 push bc
 call _tseChkProg
 pop bc
 cp 2
 jr z, okFlash
 cp 0
 jr nz, getprogloop
okFlash:
 djnz getprogloop
 xor a
 ret
GoodBattery:
 .db %00001100
 .db %00011110
 .db %00011110
 .db %00011110
 .db %00011110
 .db %00011110
BadBattery:
 .db %00001100
 .db %00011110
 .db %00010010
 .db %00010010
 .db %00010010
 .db %00011110
;--Data
arc:
.db "(A)",0
FreeMem:
	.db "Free RAM:  ",0
calcspeed:
	.db %00000110
MenuTitle:
 .db "XShell Manager v1.0",0
extdata:

MenuIndex    .equ extdata
MenuSelect   .equ MenuIndex+1
MenuLimit    .equ MenuSelect+1
tempword     .equ MenuLimit+1
.end
