; TxtView v1.53 by Kouri (Kouri@ucdavis.edu) ; http://kouri.cjb.net ; http://void.calc.org ; 2000.08.12 ; Ported to TI-83(+) by Sam Heald (evil_sam@hotmail.com) ; Program Information: ; TxtView allows you to view ASCII text files created by CalcText.exe on your TI-83(+). ; For information on how to use CalcText, please read CalcText.c.txt. ; Archive contents: ; TxtView.asm.txt - The file that you're reading right now! ; TxtView.83p - The program that you send to your calc to view the text files (for ION 83). ; TxtView.8xp - The program that you send to your calc to view the text files (for ION 83+). ; ASCII.82P - An example text file. ; README.82P - Another example text file. ; CalcText.c.txt - Contains information on how to use CalcText. ; CalcText.exe - Converts computer files to calculator files. ; 4x6font.inc - Default font file used by TxtView. ; DOSfont.inc - DOS font file used by TxtView. ; Usage: ; First install the appropriate shell on your calculator. ; Then send TxtView to your calc, follwed by as many text files as you want. ; Run TxtView from your shell. A list of all the valid text files on your calc will be shown. If you can't run TxtView, then ; you don't have any valid text files on your calculator. ; Controls (when selecting a file to view): ; Up - Scroll up ; Down - Scroll down ; Right - Change page (if more than 9 files on calc) ; [CLEAR] - Return to the shell ; Controls (when viewing a file): ; Arrows - Scroll ; [DEL] - PageUp ; [STAT] - PageDown ; [2nd]+[LEFT] - PageLeft ; [2nd]+[RIGHT] - PageRight ; [TRACE] - Home ; [GRAPH] - End ; [MODE] - Toggle word wrap ; [X,T,0] - Toggle font ; [Y=] - Invert the screen ; [CLEAR] - Return to the Main Menu ; Notes: ; *** DO NOT TURN OFF THE CALC WHILE IN TXTVIEW!!! IT WILL CRASH!!! *** ; Allowing the calc to auto-power-down is okay though. You can also change the contrast while in TxtView. ; If you want to make your own custom font for TxtView, look in 4x6font.inc or DOSfont.inc and follow the example. ; Credits: ; Jason Kovacs and Dan Englender, for tremendous help with the TI-83(+) version. ; Sam Heald for the initial TI-83 port. ; The CrASH team: Jeff Mears and Hideaki Omuro, for ideas and optimizations. ; Jimmy Mårdell and Florent Dhordain for SQRXZ 82, and Andreas Ess and Sam Heald for Plain Jump 82, whose programs showed me ; how to search the VAT and make cool little menus. :) ; Mark May, for major help with just about everything. ; Eric Piel, for the tab routine. ; Thomas Hruska, for helping out too. ; Joel (GuruMSD) for finding bugs. ; All of the A82 list for their various contributions. ; THANKS GUYS! ; Version History: ; 1.53- Modified ION version to use built-in ionDetect routine for more reliable program detection. ION 83: 2287 bytes. ; ION 83+: 2292 bytes. ; 1.52- Fixed APD bug in 83(+) version. 2nd+ON still crashes though. ION 83: 2321 bytes. ION 83+: 2326 bytes. ; 1.51- Ported to TI-83(+) for SOS and ION by Sam Heald. SOS: 2325 bytes. ION 83: 2322 bytes. ION 83+: 2327 bytes. ; 1.51- Fifth release. (Hopefully) fixed last of program detection bugs. Small optimizations. 2298 bytes. ; 1.5 - Fourth release. Fixed program detection routine to work better. Cleaned up source code a little too. 2300 bytes. ; 1.4 - Third release. Expanded font to 3 bytes/char (4x6 pixel) to better support ASCII extended characters. DOS font and ; font selector added. Left and right now move 8 spaces instead of 1. Tabs are now handled correctly. 2301 bytes. ; 1.3 - Second release. Font now supports 255 characters at 2 bytes/char (3x5 pixel). PageLeft and PageRight added. Screen ; invert added. Fixed coordinates used in C_CHARPUT routine. 1226 bytes. ; 1.2 - First release. Compressed font to 2 bytes/char (3x5 pixel). Word wrap added. Left, right, PageUp, and PageDown ; added. ~915 bytes. ; 1.1 - Not released. Switched to custom font (96 characters supported at 5 bytes/char (8x5 pixel)). ~1200 bytes. ; 1.0 - Not released. Used built-in menu font. Up, down, Home, and End supported. ~575 bytes. #include ion.inc #ifdef TI83P .org progstart-2 .db $BB,$6D #else .org progstart #endif xor a \ jr nc,Start Title: .db "TxtView v1.53 by Kouri",0 #define text(x,y,string) ld bc,256*x+y \ ld hl,string \ call D_ZC_STR TABSIZE = 8 CHARWIDTH = 4 CHARHEIGHT = 6 X_MAX = 96 Y_MAX = 64 NUMCOLS = X_MAX/CHARWIDTH #ifdef TI83 TEXT_MEM = statram #else TEXT_MEM = appbackupscreen #endif dataptr = pencol ; Pointer to the current string offset = TEXT_MEM ; Offset used for left and right num_files = TEXT_MEM+2 ; Number of text files on the calc top = TEXT_MEM+3 ; Pointer offset used when selecting files files = TEXT_MEM+4 ; Storage space for program addresses Start: ld hl,TEXT_MEM ; Clear the TEXT_MEM ld de,TEXT_MEM+1 ld (hl),0 #ifdef TI83 ld bc,530 #else ld bc,767 #endif ldir ld hl,(progptr) ; $FE6E ld bc,files ; bc -> area to store addresses SearchLoop: ld ix,ID ; ix -> TxtView file ID string push bc call ionDetect pop bc jr nz,Done xor a cp (hl) \ jr nz,KeepSearching inc hl ld a,l \ ld (bc),a \ inc bc ld a,h \ ld (bc),a \ inc bc ld hl,num_files inc (hl) KeepSearching: ex de,hl jr SearchLoop Done: ld a,(num_files) or a \ ret z ; No files found, return to shell SelectFileMenu: call StartGraphmemFill ld (hl),0 push hl ; Save hl -> GRAPH_MEM ldir ; Fill GRAPH_MEM with 0 text(1,1,Title) ; Display Title pop hl ld ixh,a ; Number of files in current list = 0 call Invert_NoRowCalc ; Invert part of the GRAPH_MEM ld a,(top) add a,a ld d,b ; d = 0 ld e,a ; de = 2*top ld hl,files add hl,de ; hl -> pointer to files ld c,8 ; Go to line after title DisplayFile: ld e,(hl) \ inc hl ; de -> program data ld d,(hl) \ inc hl ; Point to next address ld a,d or a \ jr z,UpdateChoice ; If d == 0, end of list reached push hl ; Save pointer ex de,hl ; hl -> program data ld b,1 ; x-coord = 1 push ix call D_ZC_STR ; Show file description pop ix pop hl ; Restore pointer inc ixh ; Increase number of files in list ld a,c \ add a,CHARHEIGHT \ ld c,a ; y-coord += CHARHEIGHT sub Y_MAX-2 \ jr nz,DisplayFile ; Continue until bottom of the screen UpdateChoice: ld ixl,a call InvertChoice Choose: bcall(_getkey) ; bc = 0 ld bc,$0000 NextPage: dec a \ jr nz,Choose2 ; cp K_RIGHT ld a,(top) add a,9 ; Add top of list with 9 ld hl,num_files cp (hl) \ jr c,ChangePage ; Check if we can go to next page xor a ; If not, start at page 0 ChangePage: ld (top),a jr SelectFileMenu Choose2: sub 2 \ jr z,ChoiceUp ; cp K_UP dec a \ jr z,ChoiceDown ; cp K_DOWN dec a \ jr z,SelectFile ; cp K_ENTER sub 4 \ ret z ; cp K_CLEAR jr Choose ChoiceUp: call InvertChoice or a \ jr nz,_ChoiceUp ; Check if at top of list ld a,ixh ; a = bottom of list + 1 _ChoiceUp: dec a jr UpdateChoice ChoiceDown: call InvertChoice inc a cp ixh \ jr nz,UpdateChoice ; Check if bottom of list passed xor a ; If so, current file is 0 jr UpdateChoice SelectFile: ld (offset),bc ; Clear offset ld d,a ; d = a = 0 ld a,(top) add a,ixl ; Add current choice add a,a ; Because addresses are 2 bytes ld e,a ld hl,files add hl,de ; hl -> pointer to current file ld e,(hl) inc hl ld d,(hl) ; de = file to open ex de,hl ; hl -> first string in file UpdateDisplay: ld (dataptr),hl ; Save the pointer _UpdateDisplay: call StartGraphmemFill FillValue: ld (hl),0 ldir ld hl,(dataptr) ld c,2 ; Cursor starts at (0,2) DisplayLoop: jr DisplayLoop+2 ; Change to 24 to enable word wrap ld de,(offset) ; 4 DoOffset: ld a,d ; 1 or e \ jr z,NoOffset ; 3 dec de ; 1 ld a,(hl) ; 1 inc hl ; 1 or a \ jr z,MakeNewLine ; 3 cp $09 \ call z,SkipTab ; 5 inc a \ jr nz,DoOffset ; 3 jr DisplayScreen ; 2 NoOffset: call D_ZC_STR ld a,(hl) inc a \ jr z,DisplayScreen ; Check for $FF (EOF) WordWrap: jr WordWrap+2 ; Change to 13 to enable word wrap ld a,b ; 1 sub X_MAX \ jr nz,MakeNewLine ; 4 NoWrap: cp (hl) ; 1 inc hl ; 1 jr nz,NoWrap ; 2 dec a ; 1 cp (hl) \ jr z,DisplayScreen ; 3 MakeNewLine: ld b,0 ; x-coord = 0 ld a,c \ add a,CHARHEIGHT \ ld c,a ; y-coord += CHARHEIGHT cp Y_MAX-2 \ jr nz,DisplayLoop ; Continue until bottom of screen DisplayScreen: call FastCopy ; Display the screen Main: bcall(_getkey) ; bc = 0 ld bc,0 ld hl,(dataptr) dec a \ jr z,Right ; cp K_RIGHT dec a \ jr z,Left ; cp K_LEFT dec a \ jp z,ScrollUp ; cp K_UP dec a \ jr z,ScrollDown ; cp K_DOWN sub 5 \ jp z,SelectFileMenu ; cp K_CLEAR dec a \ jr z,PageUp ; cp K_DEL sub 4 \ jr z,PageLeft ; cp K_BOL dec a \ jr z,PageRight ; cp K_EOL sub 34 \ jr z,PageDown ; cp K_STAT sub 19 \ jr z,End ; cp K_GRAPH dec a \ jr z,ToggleWordWrap ; cp K_MODE sub 4 \ jr z,InvertScreen ; cp K_YEDIT sub 17 \ jr z,Home ; cp K_TRACE sub 90 \ jr nz,Main ; cp K_XTO ChangeFont: ld de,(WhichFont+1) ld hl,DefaultFont bcall(_cphlde) \ jr nz,_ChangeFont ld hl,DOSfont _ChangeFont: ld (WhichFont+1),hl jr _Update PageLeft: ld de,-NUMCOLS \ jr TestNewOffset2 Left: ld de,-TABSIZE \ jr TestNewOffset2 PageRight: ld e, NUMCOLS \ jr TestNewOffset1 Right: ld e, TABSIZE TestNewOffset1: ld d,b ; d = 0 TestNewOffset2: ld hl,(offset) add hl,de ; Get new offset bit 7,h \ jr z,ChangeOffset ; If h is negative, offset = 0 ld h,b ld l,c ChangeOffset: ld (offset),hl _Update: jp _UpdateDisplay End: dec a ; a = $FF ld (offset),bc ; offset = 0 cpir ; Go to EOF dec hl ; hl -> EOF PageUp: ld b,10 ; Do 10 lines jr _ScrollUp Home: dec a ; a = $FF ld (offset),bc ; offset = 0 cpdr ; Go to BOF inc hl ; hl -> BOF ScrollDown: ld b,1 ; Do 1 line _ScrollDown: call Scroll ld a,(hl) inc a \ jr z,ScrollUp ; Check for EOF djnz _ScrollDown jr Update PageDown: ld b,10 ; Do 10 lines jr _ScrollDown InvertScreen: ld a,(FillValue+1) \ cpl \ ld (FillValue+1),a jr Update ToggleWordWrap: ld (offset),bc ; offset = 0 ld a,(DisplayLoop+1) \ xor 24 \ ld (DisplayLoop+1),a \ ld (Scroll+1),a ld a,(WordWrap+1) \ ld (ScrollUpWrap+1),a \ xor 13 \ ld (WordWrap+1),a dec hl ld a,(hl) inc hl or a \ jr z,Update ScrollUp: ld b,1 ; Do 1 line _ScrollUp: dec hl \ dec hl ; Get past previous zero ld a,(hl) inc hl \ inc hl inc a \ jr z,Update ; Check for BOF xor a push bc ld b,h ld c,l ; Save dataptr dec hl ScrollUpLoop: dec hl cp (hl) \ jr nz,ScrollUpLoop ; Get to previous zero inc hl ; Point to next byte ScrollUpWrap: jr ScrollUpNoWrap ; Change to 0 to enable word wrap _ScrollUpWrap: push hl ; 1 call Scroll ; 3 ld d,b ; 1 ld e,c ; 1 bcall(_cphlde) ; 3 pop de ; 1 jr c,_ScrollUpWrap ; 2 ex de,hl ; 1 ScrollUpNoWrap: pop bc djnz _ScrollUp Update: jp UpdateDisplay Scroll: ld de,0 ; Change to NUMCOLS to enable word wrap ScrollLoop: dec de ld a,(hl) inc hl or a \ ret z ; Go to next zero cp $09 \ call z,SkipTab ld a,d or e \ jr nz,ScrollLoop ret SkipTab: ; Courtesy of Jeff Mears :) ld a,e and 11111000b ld e,a ret InvertChoice: ld c,ixl ; c = current choice ld h,6*X_MAX/8 ld l,c bcall(_htimesl) ; hl = current choice * 72 ld de,GRAPH_MEM+(7*X_MAX/8) add hl,de ; hl -> offset in GRAPH_MEM Invert_NoRowCalc: ld b,7*X_MAX/8 ; 7 lines to invert InvertLoop: ld a,(hl) \ cpl \ ld (hl),a ; Invert the byte inc hl djnz InvertLoop ld a,c ; a = current choice FastCopy: push af push bc push de push hl push ix call ionFastCopy pop ix pop hl pop de pop bc pop af ret StartGraphmemFill: ld hl,GRAPH_MEM ld de,GRAPH_MEM+1 ld bc,X_MAX*Y_MAX/8-1 ret D_ZC_STR: ; Optimized (hacked) for TxtView xor a ld d,a ld e,(hl) ; Get char into e inc hl ; Point to next char or e \ ret z cp $09 \ jr z,Tab push bc \ push hl ; Save dataptr and coords WhichFont: ld hl,DefaultFont ; Point to custom font add hl,de ; Because each sprite is 3 bytes add hl,de add hl,de push hl \ pop ix ; ix -> sprite for char ld a,b ; Save x-coord ld b,d ; b = 0 ld h,b ; h = 0 ld l,c ; l = y add hl,hl ; hl = 2y add hl,bc ; hl = 3y add hl,hl ; hl = 6y add hl,hl ; hl = 12y ld c,a ; Restore x-coord srl c \ srl c \ srl c ; x/8 add hl,bc ; hl = 12y + x/8 ld bc,GRAPH_MEM add hl,bc ; hl = 12y + x/8 + GRAPH_MEM cpl and 00000111b ; Get the remainder of x/8 ld b,a add a,a add a,b ; Calculate number of jumps ld (C_CHARPUT_Shift+1),a ; Self-modifying code ld b,3 ; Do 3 sets of 2 lines ld de,X_MAX/8-1 ; de = offset to add to GRAPH_MEM C_CHARPUT_Loop: push bc ; Save number of loops ld b,2 ; Do 2 lines ld a,(ix) ; Get sprite data and 11110000b ; Mask out right half C_CHARPUT_Loop2: ld c,d ; c = 0 C_CHARPUT_Shift: jr C_CHARPUT_Shift rrca \ rr c rrca \ rr c rrca \ rr c rrca \ rr c rrca \ rr c rrca \ rr c rrca \ rr c xor (hl) \ ld (hl),a ; Write first byte inc hl ld a,c xor (hl) \ ld (hl),a ; Write second byte add hl,de ; Add offset ld a,(ix) ; Get sprite data add a,a \ add a,a \ add a,a \ add a,a ; Mask out left half and shift djnz C_CHARPUT_Loop2 pop bc ; Restore number of loops inc ix ; Point to next byte of sprite djnz C_CHARPUT_Loop pop hl \ pop bc ; Restore dataptr and coords ld a,b add a,CHARWIDTH ; x-coord += CHARWIDTH CheckBounds: ld b,a cp X_MAX \ jr c,D_ZC_STR ; If x-coord >= X_MAX, we're done ret Tab: ; Courtesy of Eric Piel :) ld a,b ; a = x-coord add a,TABSIZE*CHARWIDTH and 11100000b ; Round down to nearest TABSIZE*CHARWIDTH jr CheckBounds DefaultFont: #include 4x6font.inc DOSfont: #include DOSfont.inc ID: .db $FF, 0 .end